aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.gitmodules2
-rw-r--r--.rspec1
-rw-r--r--.rvmrc10
-rw-r--r--Gemfile33
-rw-r--r--Gemfile.lock224
-rw-r--r--README-rails.txt188
-rw-r--r--Rakefile8
-rw-r--r--app/controllers/admin_censor_rule_controller.rb2
-rw-r--r--app/controllers/admin_controller.rb10
-rw-r--r--app/controllers/admin_general_controller.rb2
-rw-r--r--app/controllers/admin_public_body_controller.rb18
-rw-r--r--app/controllers/admin_request_controller.rb22
-rw-r--r--app/controllers/admin_track_controller.rb12
-rw-r--r--app/controllers/admin_user_controller.rb12
-rw-r--r--app/controllers/api_controller.rb13
-rw-r--r--app/controllers/application_controller.rb57
-rw-r--r--app/controllers/comment_controller.rb2
-rw-r--r--app/controllers/general_controller.rb12
-rw-r--r--app/controllers/help_controller.rb8
-rw-r--r--app/controllers/holiday_controller.rb4
-rw-r--r--app/controllers/public_body_controller.rb14
-rw-r--r--app/controllers/request_controller.rb67
-rw-r--r--app/controllers/request_game_controller.rb2
-rw-r--r--app/controllers/services_controller.rb6
-rw-r--r--app/controllers/track_controller.rb11
-rw-r--r--app/controllers/user_controller.rb28
-rw-r--r--app/helpers/application_helper.rb2
-rw-r--r--app/helpers/config_helper.rb4
-rwxr-xr-xapp/helpers/link_to_helper.rb15
-rw-r--r--app/helpers/mailer_helper.rb2
-rw-r--r--app/mailers/application_mailer.rb62
-rw-r--r--app/mailers/contact_mailer.rb45
-rw-r--r--app/mailers/outgoing_mailer.rb (renamed from app/models/outgoing_mailer.rb)32
-rw-r--r--app/mailers/request_mailer.rb (renamed from app/models/request_mailer.rb)228
-rw-r--r--app/mailers/track_mailer.rb (renamed from app/models/track_mailer.rb)26
-rw-r--r--app/mailers/user_mailer.rb44
-rw-r--r--app/models/about_me_validator.rb22
-rw-r--r--app/models/application_mailer.rb164
-rw-r--r--app/models/censor_rule.rb12
-rw-r--r--app/models/change_email_validator.rb38
-rw-r--r--app/models/comment.rb2
-rw-r--r--app/models/contact_mailer.rb56
-rw-r--r--app/models/contact_validator.rb34
-rw-r--r--app/models/foi_attachment.rb22
-rw-r--r--app/models/holiday.rb2
-rw-r--r--app/models/incoming_message.rb50
-rw-r--r--app/models/info_request.rb79
-rw-r--r--app/models/info_request_event.rb4
-rw-r--r--app/models/mail_server_log.rb12
-rw-r--r--app/models/mail_server_log_done.rb2
-rw-r--r--app/models/outgoing_message.rb23
-rw-r--r--app/models/post_redirect.rb28
-rw-r--r--app/models/profile_photo.rb39
-rw-r--r--app/models/public_body.rb65
-rw-r--r--app/models/purge_request.rb2
-rw-r--r--app/models/raw_email.rb6
-rw-r--r--app/models/track_thing.rb4
-rw-r--r--app/models/track_things_sent_email.rb2
-rw-r--r--app/models/user.rb48
-rw-r--r--app/models/user_info_request_sent_alert.rb2
-rw-r--r--app/models/user_mailer.rb48
-rw-r--r--app/views/admin_censor_rule/_form.html.erb (renamed from app/views/admin_censor_rule/_form.rhtml)0
-rw-r--r--app/views/admin_censor_rule/_show.html.erb (renamed from app/views/admin_censor_rule/_show.rhtml)0
-rw-r--r--app/views/admin_censor_rule/edit.html.erb (renamed from app/views/admin_censor_rule/edit.rhtml)4
-rw-r--r--app/views/admin_censor_rule/new.html.erb (renamed from app/views/admin_censor_rule/new.rhtml)4
-rw-r--r--app/views/admin_general/_admin_navbar.html.erb (renamed from app/views/admin_general/_admin_navbar.rhtml)0
-rw-r--r--app/views/admin_general/debug.html.erb (renamed from app/views/admin_general/debug.rhtml)7
-rw-r--r--app/views/admin_general/index.html.erb (renamed from app/views/admin_general/index.rhtml)0
-rw-r--r--app/views/admin_general/stats.html.erb (renamed from app/views/admin_general/stats.rhtml)0
-rw-r--r--app/views/admin_general/timeline.html.erb (renamed from app/views/admin_general/timeline.rhtml)0
-rw-r--r--app/views/admin_public_body/_form.html.erb (renamed from app/views/admin_public_body/_form.rhtml)5
-rw-r--r--app/views/admin_public_body/_one_list.html.erb (renamed from app/views/admin_public_body/_one_list.rhtml)2
-rw-r--r--app/views/admin_public_body/_tag_help.html.erb (renamed from app/views/admin_public_body/_tag_help.rhtml)0
-rw-r--r--app/views/admin_public_body/_tags.html.erb (renamed from app/views/admin_public_body/_tags.rhtml)0
-rw-r--r--app/views/admin_public_body/edit.html.erb (renamed from app/views/admin_public_body/edit.rhtml)2
-rw-r--r--app/views/admin_public_body/import_csv.html.erb (renamed from app/views/admin_public_body/import_csv.rhtml)2
-rw-r--r--app/views/admin_public_body/list.html.erb (renamed from app/views/admin_public_body/list.rhtml)3
-rw-r--r--app/views/admin_public_body/missing_scheme.html.erb (renamed from app/views/admin_public_body/missing_scheme.rhtml)0
-rw-r--r--app/views/admin_public_body/new.html.erb (renamed from app/views/admin_public_body/new.rhtml)2
-rw-r--r--app/views/admin_public_body/show.html.erb (renamed from app/views/admin_public_body/show.rhtml)0
-rw-r--r--app/views/admin_request/_incoming_message_actions.html.erb (renamed from app/views/admin_request/_incoming_message_actions.rhtml)4
-rw-r--r--app/views/admin_request/_some_requests.html.erb (renamed from app/views/admin_request/_some_requests.rhtml)0
-rw-r--r--app/views/admin_request/_tags.html.erb (renamed from app/views/admin_request/_tags.rhtml)0
-rw-r--r--app/views/admin_request/edit.html.erb (renamed from app/views/admin_request/edit.rhtml)4
-rw-r--r--app/views/admin_request/edit_comment.html.erb (renamed from app/views/admin_request/edit_comment.rhtml)2
-rw-r--r--app/views/admin_request/edit_outgoing.html.erb (renamed from app/views/admin_request/edit_outgoing.rhtml)4
-rw-r--r--app/views/admin_request/hidden_user_explanation.html.erb10
-rw-r--r--app/views/admin_request/hidden_user_explanation.rhtml10
-rw-r--r--app/views/admin_request/list.html.erb (renamed from app/views/admin_request/list.rhtml)2
-rw-r--r--app/views/admin_request/show.html.erb (renamed from app/views/admin_request/show.rhtml)18
-rw-r--r--app/views/admin_request/show_raw_email.html.erb (renamed from app/views/admin_request/show_raw_email.rhtml)0
-rw-r--r--app/views/admin_track/_some_tracks.html.erb (renamed from app/views/admin_track/_some_tracks.rhtml)4
-rw-r--r--app/views/admin_track/list.html.erb (renamed from app/views/admin_track/list.rhtml)2
-rw-r--r--app/views/admin_user/_form.html.erb (renamed from app/views/admin_user/_form.rhtml)0
-rw-r--r--app/views/admin_user/_user_table.html.erb (renamed from app/views/admin_user/_user_table.rhtml)0
-rw-r--r--app/views/admin_user/edit.html.erb (renamed from app/views/admin_user/edit.rhtml)2
-rw-r--r--app/views/admin_user/list.html.erb (renamed from app/views/admin_user/list.rhtml)2
-rw-r--r--app/views/admin_user/list_banned.html.erb (renamed from app/views/admin_user/list_banned.rhtml)0
-rw-r--r--app/views/admin_user/show.html.erb (renamed from app/views/admin_user/show.rhtml)6
-rw-r--r--app/views/admin_user/show_bounce_message.html.erb (renamed from app/views/admin_user/show_bounce_message.rhtml)0
-rw-r--r--app/views/comment/_comment_form.html.erb (renamed from app/views/comment/_comment_form.rhtml)2
-rw-r--r--app/views/comment/_single_comment.html.erb (renamed from app/views/comment/_single_comment.rhtml)0
-rw-r--r--app/views/comment/new.html.erb (renamed from app/views/comment/new.rhtml)0
-rw-r--r--app/views/comment/preview.html.erb (renamed from app/views/comment/preview.rhtml)2
-rw-r--r--app/views/contact_mailer/from_admin_message.text.erb (renamed from app/views/contact_mailer/from_admin_message.rhtml)0
-rw-r--r--app/views/contact_mailer/to_admin_message.text.erb (renamed from app/views/contact_mailer/to_admin_message.rhtml)0
-rw-r--r--app/views/contact_mailer/user_message.text.erb (renamed from app/views/contact_mailer/user_message.rhtml)0
-rw-r--r--app/views/general/_advanced_search_tips.html.erb (renamed from app/views/general/_advanced_search_tips.rhtml)0
-rw-r--r--app/views/general/_before_body_end.html.erb (renamed from app/views/general/_before_body_end.rhtml)0
-rw-r--r--app/views/general/_before_head_end.html.erb (renamed from app/views/general/_before_head_end.rhtml)0
-rw-r--r--app/views/general/_credits.html.erb (renamed from app/views/general/_credits.rhtml)0
-rw-r--r--app/views/general/_custom_state_descriptions.html.erb (renamed from app/views/general/_custom_state_descriptions.rhtml)0
-rw-r--r--app/views/general/_custom_state_transitions_complete.html.erb (renamed from app/views/general/_custom_state_transitions_complete.rhtml)0
-rw-r--r--app/views/general/_custom_state_transitions_pending.html.erb (renamed from app/views/general/_custom_state_transitions_pending.rhtml)0
-rw-r--r--app/views/general/_footer.html.erb (renamed from app/views/general/_footer.rhtml)2
-rw-r--r--app/views/general/_frontpage_bodies_list.html.erb (renamed from app/views/general/_frontpage_bodies_list.rhtml)0
-rw-r--r--app/views/general/_frontpage_intro_sentence.html.erb (renamed from app/views/general/_frontpage_intro_sentence.rhtml)0
-rw-r--r--app/views/general/_frontpage_new_request.html.erb (renamed from app/views/general/_frontpage_new_request.rhtml)0
-rw-r--r--app/views/general/_frontpage_requests_list.html.erb (renamed from app/views/general/_frontpage_requests_list.rhtml)0
-rw-r--r--app/views/general/_frontpage_search_box.html.erb (renamed from app/views/general/_frontpage_search_box.rhtml)0
-rw-r--r--app/views/general/_locale_switcher.html.erb (renamed from app/views/general/_locale_switcher.rhtml)0
-rw-r--r--app/views/general/_localised_datepicker.html.erb (renamed from app/views/general/_localised_datepicker.rhtml)0
-rw-r--r--app/views/general/_orglink.html.erb (renamed from app/views/general/_orglink.rhtml)0
-rw-r--r--app/views/general/_popup_banner.html.erb (renamed from app/views/general/_popup_banner.rhtml)0
-rw-r--r--app/views/general/_stylesheet_includes.html.erb (renamed from app/views/general/_stylesheet_includes.rhtml)2
-rw-r--r--app/views/general/_topnav.html.erb (renamed from app/views/general/_topnav.rhtml)0
-rw-r--r--app/views/general/blog.html.erb (renamed from app/views/general/blog.rhtml)14
-rw-r--r--app/views/general/custom_css.html.erb (renamed from app/views/general/custom_css.rhtml)0
-rw-r--r--app/views/general/exception_caught.html.erb (renamed from app/views/general/exception_caught.rhtml)2
-rw-r--r--app/views/general/frontpage.html.erb (renamed from app/views/general/frontpage.rhtml)2
-rw-r--r--app/views/general/search.html.erb (renamed from app/views/general/search.rhtml)4
-rw-r--r--app/views/help/_sidebar.html.erb (renamed from app/views/help/_sidebar.rhtml)0
-rw-r--r--app/views/help/_why_they_should_reply_by_email.html.erb (renamed from app/views/help/_why_they_should_reply_by_email.rhtml)0
-rw-r--r--app/views/help/about.html.erb (renamed from app/views/help/about.rhtml)0
-rw-r--r--app/views/help/alaveteli.html.erb (renamed from app/views/help/alaveteli.rhtml)0
-rw-r--r--app/views/help/api.html.erb (renamed from app/views/help/api.rhtml)0
-rw-r--r--app/views/help/contact.html.erb (renamed from app/views/help/contact.rhtml)4
-rw-r--r--app/views/help/credits.html.erb (renamed from app/views/help/credits.rhtml)0
-rw-r--r--app/views/help/officers.html.erb (renamed from app/views/help/officers.rhtml)0
-rw-r--r--app/views/help/privacy.html.erb (renamed from app/views/help/privacy.rhtml)0
-rw-r--r--app/views/help/requesting.html.erb (renamed from app/views/help/requesting.rhtml)0
-rw-r--r--app/views/help/unhappy.html.erb (renamed from app/views/help/unhappy.rhtml)0
-rw-r--r--app/views/holiday/due_date.html.erb (renamed from app/views/holiday/due_date.rhtml)0
-rw-r--r--app/views/layouts/admin.html.erb (renamed from app/views/layouts/admin.rhtml)0
-rw-r--r--app/views/layouts/contact_mailer.html.erb (renamed from app/views/layouts/contact_mailer.rhtml)0
-rw-r--r--app/views/layouts/default.html.erb (renamed from app/views/layouts/default.rhtml)10
-rw-r--r--app/views/layouts/no_chrome.html.erb (renamed from app/views/layouts/no_chrome.rhtml)0
-rw-r--r--app/views/layouts/outgoing_mailer.html.erb (renamed from app/views/layouts/outgoing_mailer.rhtml)0
-rw-r--r--app/views/layouts/request_mailer.html.erb (renamed from app/views/layouts/request_mailer.rhtml)0
-rw-r--r--app/views/layouts/user_mailer.html.erb (renamed from app/views/layouts/user_mailer.rhtml)0
-rw-r--r--app/views/outgoing_mailer/_followup_footer.text.erb (renamed from app/views/outgoing_mailer/_followup_footer.rhtml)0
-rw-r--r--app/views/outgoing_mailer/followup.text.erb (renamed from app/views/outgoing_mailer/followup.rhtml)0
-rw-r--r--app/views/outgoing_mailer/initial_request.text.erb (renamed from app/views/outgoing_mailer/initial_request.rhtml)0
-rw-r--r--app/views/public_body/_alphabet.html.erb (renamed from app/views/public_body/_alphabet.rhtml)2
-rw-r--r--app/views/public_body/_body_listing.html.erb (renamed from app/views/public_body/_body_listing.rhtml)0
-rw-r--r--app/views/public_body/_body_listing_single.html.erb (renamed from app/views/public_body/_body_listing_single.rhtml)0
-rw-r--r--app/views/public_body/_list_sidebar_extra.html.erb (renamed from app/views/public_body/_list_sidebar_extra.rhtml)0
-rw-r--r--app/views/public_body/_search_ahead.html.erb (renamed from app/views/public_body/_search_ahead.rhtml)2
-rw-r--r--app/views/public_body/list.html.erb (renamed from app/views/public_body/list.rhtml)2
-rw-r--r--app/views/public_body/show.html.erb (renamed from app/views/public_body/show.rhtml)0
-rw-r--r--app/views/public_body/view_email.html.erb (renamed from app/views/public_body/view_email.rhtml)0
-rw-r--r--app/views/public_body/view_email_captcha.html.erb (renamed from app/views/public_body/view_email_captcha.rhtml)2
-rw-r--r--app/views/request/_after_actions.html.erb (renamed from app/views/request/_after_actions.rhtml)0
-rw-r--r--app/views/request/_bubble.html.erb (renamed from app/views/request/_bubble.rhtml)0
-rw-r--r--app/views/request/_correspondence.html.erb (renamed from app/views/request/_correspondence.rhtml)0
-rw-r--r--app/views/request/_describe_state.html.erb (renamed from app/views/request/_describe_state.rhtml)6
-rw-r--r--app/views/request/_followup.html.erb (renamed from app/views/request/_followup.rhtml)2
-rw-r--r--app/views/request/_hidden_correspondence.html.erb (renamed from app/views/request/_hidden_correspondence.rhtml)6
-rw-r--r--app/views/request/_next_actions.html.erb (renamed from app/views/request/_next_actions.rhtml)0
-rw-r--r--app/views/request/_other_describe_state.html.erb (renamed from app/views/request/_other_describe_state.rhtml)2
-rw-r--r--app/views/request/_request_filter_form.html.erb (renamed from app/views/request/_request_filter_form.rhtml)2
-rw-r--r--app/views/request/_request_listing.html.erb (renamed from app/views/request/_request_listing.rhtml)0
-rw-r--r--app/views/request/_request_listing_short_via_event.html.erb (renamed from app/views/request/_request_listing_short_via_event.rhtml)0
-rw-r--r--app/views/request/_request_listing_single.html.erb (renamed from app/views/request/_request_listing_single.rhtml)0
-rw-r--r--app/views/request/_request_listing_via_event.html.erb (renamed from app/views/request/_request_listing_via_event.rhtml)0
-rw-r--r--app/views/request/_search_ahead.html.erb (renamed from app/views/request/_search_ahead.rhtml)0
-rw-r--r--app/views/request/_sidebar.html.erb (renamed from app/views/request/_sidebar.rhtml)19
-rw-r--r--app/views/request/_sidebar_request_listing.html.erb (renamed from app/views/request/_sidebar_request_listing.rhtml)0
-rw-r--r--app/views/request/_summary_suggestion.html.erb (renamed from app/views/request/_summary_suggestion.rhtml)0
-rw-r--r--app/views/request/_view_html_prefix.html.erb (renamed from app/views/request/_view_html_prefix.rhtml)0
-rw-r--r--app/views/request/_view_html_stylesheet.html.erb (renamed from app/views/request/_view_html_stylesheet.rhtml)0
-rw-r--r--app/views/request/_wall_listing.html.erb (renamed from app/views/request/_wall_listing.rhtml)0
-rw-r--r--app/views/request/describe_state_message.html.erb (renamed from app/views/request/describe_state_message.rhtml)2
-rw-r--r--app/views/request/details.html.erb (renamed from app/views/request/details.rhtml)0
-rw-r--r--app/views/request/followup_bad.html.erb (renamed from app/views/request/followup_bad.rhtml)0
-rw-r--r--app/views/request/followup_preview.html.erb (renamed from app/views/request/followup_preview.rhtml)4
-rw-r--r--app/views/request/hidden.html.erb (renamed from app/views/request/hidden.rhtml)2
-rw-r--r--app/views/request/list.html.erb (renamed from app/views/request/list.rhtml)0
-rw-r--r--app/views/request/new.html.erb (renamed from app/views/request/new.rhtml)4
-rw-r--r--app/views/request/new_bad_contact.html.erb (renamed from app/views/request/new_bad_contact.rhtml)0
-rw-r--r--app/views/request/new_please_describe.html.erb (renamed from app/views/request/new_please_describe.rhtml)2
-rw-r--r--app/views/request/preview.html.erb (renamed from app/views/request/preview.rhtml)8
-rw-r--r--app/views/request/select_authority.html.erb (renamed from app/views/request/select_authority.rhtml)2
-rw-r--r--app/views/request/show.html.erb (renamed from app/views/request/show.rhtml)2
-rw-r--r--app/views/request/show_response.html.erb (renamed from app/views/request/show_response.rhtml)0
-rw-r--r--app/views/request/similar.html.erb (renamed from app/views/request/similar.rhtml)0
-rw-r--r--app/views/request/simple_correspondence.html.erb (renamed from app/views/request/simple_correspondence.rhtml)2
-rw-r--r--app/views/request/upload_response.html.erb (renamed from app/views/request/upload_response.rhtml)2
-rw-r--r--app/views/request_game/play.html.erb (renamed from app/views/request_game/play.rhtml)0
-rw-r--r--app/views/request_mailer/comment_on_alert.text.erb (renamed from app/views/request_mailer/comment_on_alert.rhtml)0
-rw-r--r--app/views/request_mailer/comment_on_alert_plural.text.erb (renamed from app/views/request_mailer/comment_on_alert_plural.rhtml)0
-rw-r--r--app/views/request_mailer/external_response.rhtml1
-rw-r--r--app/views/request_mailer/external_response.text.erb1
-rw-r--r--app/views/request_mailer/fake_response.rhtml1
-rw-r--r--app/views/request_mailer/fake_response.text.erb1
-rw-r--r--app/views/request_mailer/new_response.text.erb (renamed from app/views/request_mailer/new_response.rhtml)0
-rw-r--r--app/views/request_mailer/new_response_reminder_alert.text.erb (renamed from app/views/request_mailer/new_response_reminder_alert.rhtml)0
-rw-r--r--app/views/request_mailer/not_clarified_alert.text.erb (renamed from app/views/request_mailer/not_clarified_alert.rhtml)0
-rw-r--r--app/views/request_mailer/old_unclassified_updated.text.erb (renamed from app/views/request_mailer/old_unclassified_updated.rhtml)0
-rw-r--r--app/views/request_mailer/overdue_alert.text.erb (renamed from app/views/request_mailer/overdue_alert.rhtml)0
-rw-r--r--app/views/request_mailer/requires_admin.text.erb (renamed from app/views/request_mailer/requires_admin.rhtml)0
-rw-r--r--app/views/request_mailer/stopped_responses.text.erb (renamed from app/views/request_mailer/stopped_responses.rhtml)0
-rw-r--r--app/views/request_mailer/very_overdue_alert.text.erb (renamed from app/views/request_mailer/very_overdue_alert.rhtml)0
-rw-r--r--app/views/track/_tracking_links.html.erb (renamed from app/views/track/_tracking_links.rhtml)2
-rw-r--r--app/views/track/atom_feed.atom.erb2
-rw-r--r--app/views/track_mailer/event_digest.text.erb (renamed from app/views/track_mailer/event_digest.rhtml)0
-rw-r--r--app/views/user/_change_receive_email.html.erb (renamed from app/views/user/_change_receive_email.rhtml)2
-rw-r--r--app/views/user/_show_user_info.html.erb (renamed from app/views/user/_show_user_info.rhtml)0
-rw-r--r--app/views/user/_signin.html.erb (renamed from app/views/user/_signin.rhtml)2
-rw-r--r--app/views/user/_signup.html.erb (renamed from app/views/user/_signup.rhtml)2
-rw-r--r--app/views/user/_user_listing_single.html.erb (renamed from app/views/user/_user_listing_single.rhtml)0
-rw-r--r--app/views/user/bad_token.html.erb (renamed from app/views/user/bad_token.rhtml)0
-rw-r--r--app/views/user/banned.html.erb (renamed from app/views/user/banned.rhtml)0
-rw-r--r--app/views/user/confirm.html.erb (renamed from app/views/user/confirm.rhtml)0
-rw-r--r--app/views/user/contact.html.erb (renamed from app/views/user/contact.rhtml)2
-rw-r--r--app/views/user/no_cookies.html.erb (renamed from app/views/user/no_cookies.rhtml)0
-rw-r--r--app/views/user/rate_limited.html.erb (renamed from app/views/user/rate_limited.rhtml)2
-rw-r--r--app/views/user/river.html.erb (renamed from app/views/user/river.rhtml)0
-rw-r--r--app/views/user/set_crop_profile_photo.html.erb (renamed from app/views/user/set_crop_profile_photo.rhtml)2
-rw-r--r--app/views/user/set_draft_profile_photo.html.erb (renamed from app/views/user/set_draft_profile_photo.rhtml)4
-rw-r--r--app/views/user/set_profile_about_me.html.erb (renamed from app/views/user/set_profile_about_me.rhtml)4
-rw-r--r--app/views/user/show.html.erb (renamed from app/views/user/show.rhtml)16
-rw-r--r--app/views/user/sign.html.erb (renamed from app/views/user/sign.rhtml)2
-rw-r--r--app/views/user/signchangeemail.html.erb (renamed from app/views/user/signchangeemail.rhtml)2
-rw-r--r--app/views/user/signchangeemail_confirm.html.erb (renamed from app/views/user/signchangeemail_confirm.rhtml)0
-rw-r--r--app/views/user/signchangepassword.html.erb (renamed from app/views/user/signchangepassword.rhtml)2
-rw-r--r--app/views/user/signchangepassword_confirm.html.erb (renamed from app/views/user/signchangepassword_confirm.rhtml)0
-rw-r--r--app/views/user/signchangepassword_send_confirm.html.erb (renamed from app/views/user/signchangepassword_send_confirm.rhtml)2
-rw-r--r--app/views/user/signin_successful.html.erb (renamed from app/views/user/signin_successful.rhtml)0
-rw-r--r--app/views/user/wall.html.erb (renamed from app/views/user/wall.rhtml)0
-rw-r--r--app/views/user/wrong_user.html.erb (renamed from app/views/user/wrong_user.rhtml)0
-rw-r--r--app/views/user/wrong_user_unknown_email.html.erb (renamed from app/views/user/wrong_user_unknown_email.rhtml)0
-rw-r--r--app/views/user_mailer/already_registered.text.erb (renamed from app/views/user_mailer/already_registered.rhtml)0
-rw-r--r--app/views/user_mailer/changeemail_already_used.text.erb (renamed from app/views/user_mailer/changeemail_already_used.rhtml)0
-rw-r--r--app/views/user_mailer/changeemail_confirm.text.erb (renamed from app/views/user_mailer/changeemail_confirm.rhtml)0
-rw-r--r--app/views/user_mailer/confirm_login.text.erb (renamed from app/views/user_mailer/confirm_login.rhtml)0
-rw-r--r--config.ru6
-rw-r--r--config/application.rb72
-rw-r--r--config/boot.rb136
-rw-r--r--config/crontab.ugly2
-rw-r--r--config/deploy.yml.example4
-rw-r--r--config/environment.rb157
-rw-r--r--config/environments/development.rb47
-rw-r--r--config/environments/production.rb46
-rw-r--r--config/environments/staging.rb30
-rw-r--r--config/environments/test.rb40
-rw-r--r--config/httpd.conf2
-rw-r--r--config/initializers/alaveteli.rb61
-rw-r--r--config/initializers/backtrace_silencers.rb7
-rw-r--r--config/initializers/fast_gettext.rb2
-rw-r--r--config/initializers/gettext_i18n_rails.rb3
-rw-r--r--config/initializers/inflections.rb10
-rw-r--r--config/initializers/mime_types.rb5
-rw-r--r--config/initializers/secret_token.rb7
-rw-r--r--config/initializers/session_store.rb17
-rw-r--r--config/initializers/single_quote_escape_workaround.rb31
-rw-r--r--config/initializers/strip_nil_parameters_patch.rb51
-rw-r--r--config/initializers/theme_loader.rb2
-rw-r--r--config/routes.rb472
-rw-r--r--config/test.yml2
-rw-r--r--db/development_structure.sql48
-rw-r--r--db/migrate/006_version_public_body.rb2
-rw-r--r--db/migrate/101_add_hash_to_info_request.rb4
-rw-r--r--db/seeds.rb7
-rw-r--r--doc/INSTALL.md10
-rw-r--r--doc/THEMES.md14
-rw-r--r--lib/activesupport_cache_extensions.rb2
-rw-r--r--lib/alaveteli_external_command.rb4
-rw-r--r--lib/configuration.rb14
-rw-r--r--lib/cookie_store_with_line_break_fix.rb19
-rw-r--r--lib/mail_handler/backends/mail_backend.rb8
-rw-r--r--lib/mail_handler/backends/mail_extensions.rb40
-rw-r--r--lib/mail_handler/backends/tmail_backend.rb288
-rw-r--r--lib/mail_handler/backends/tmail_extensions.rb138
-rw-r--r--lib/mail_handler/mail_handler.rb15
-rw-r--r--lib/old_rubygems_patch.rb46
-rw-r--r--lib/patches/fixtures_constraint_disabling.rb21
-rw-r--r--lib/public_body_categories.rb2
-rw-r--r--lib/rack_quote_monkeypatch.rb65
-rw-r--r--lib/sendmail_return_path.rb21
-rw-r--r--lib/tasks/.gitkeep (renamed from spec/fixtures/track_things_sent_emails.yml)0
-rw-r--r--lib/tasks/rspec.rake148
-rw-r--r--lib/tasks/themes.rake10
-rw-r--r--lib/tasks/translation.rake46
-rw-r--r--lib/timezone_fixes.rb26
-rw-r--r--lib/willpaginate_extension.rb2
-rw-r--r--public/404.html34
-rw-r--r--public/422.html26
-rw-r--r--public/500.html36
-rwxr-xr-xpublic/dispatch.cgi10
-rwxr-xr-xpublic/dispatch.fcgi24
-rwxr-xr-xpublic/dispatch.rb10
-rw-r--r--public/javascripts/controls.js148
-rw-r--r--public/javascripts/dragdrop.js340
-rw-r--r--public/javascripts/effects.js357
-rw-r--r--public/javascripts/prototype.js5198
-rw-r--r--public/javascripts/rails.js202
-rwxr-xr-xscript/about3
-rwxr-xr-xscript/alert-comment-on-request6
-rwxr-xr-xscript/alert-new-response-reminders6
-rwxr-xr-xscript/alert-not-clarified-request6
-rwxr-xr-xscript/alert-overdue-requests4
-rwxr-xr-xscript/alert-tracks7
-rwxr-xr-xscript/annotate-models2
-rwxr-xr-xscript/autospec6
-rwxr-xr-xscript/breakpointer3
-rwxr-xr-x[-rw-r--r--]script/cache-incoming-emails4
-rwxr-xr-xscript/check-recent-requests-sent7
-rwxr-xr-xscript/clear-caches5
-rwxr-xr-xscript/console3
-rwxr-xr-xscript/dbconsole3
-rwxr-xr-xscript/delete-old-things6
-rwxr-xr-xscript/destroy3
-rwxr-xr-xscript/direct-rspec8
-rwxr-xr-xscript/generate3
-rwxr-xr-xscript/handle-mail-replies.rb6
-rwxr-xr-xscript/load-mail-server-logs4
-rwxr-xr-xscript/load-sample-data26
-rwxr-xr-xscript/mailin2
-rwxr-xr-xscript/performance/benchmarker3
-rwxr-xr-xscript/performance/profiler3
-rwxr-xr-xscript/performance/request3
-rwxr-xr-xscript/plugin3
-rwxr-xr-xscript/process/inspector3
-rwxr-xr-xscript/process/reaper3
-rwxr-xr-xscript/process/spawner3
-rwxr-xr-xscript/purge-varnish4
-rwxr-xr-xscript/rails6
-rwxr-xr-xscript/rails-post-deploy2
-rwxr-xr-xscript/request-creation-graph2
-rwxr-xr-xscript/runner5
-rwxr-xr-xscript/server3
-rwxr-xr-xscript/spec10
-rwxr-xr-xscript/spec-all-pairs81
-rwxr-xr-xscript/spec_server116
-rwxr-xr-xscript/stop-new-responses-on-old-requests6
-rwxr-xr-xscript/test-run5
-rwxr-xr-xscript/user-use-graph2
-rwxr-xr-xscript/wraptest43
-rw-r--r--spec/controllers/admin_censor_rule_controller_spec.rb14
-rw-r--r--spec/controllers/admin_general_controller_spec.rb5
-rw-r--r--spec/controllers/admin_public_body_controller_spec.rb51
-rw-r--r--spec/controllers/admin_request_controller_spec.rb26
-rw-r--r--spec/controllers/admin_track_controller_spec.rb2
-rw-r--r--spec/controllers/admin_user_controller_spec.rb2
-rw-r--r--spec/controllers/api_controller_spec.rb20
-rw-r--r--spec/controllers/comment_controller_spec.rb2
-rw-r--r--spec/controllers/general_controller_spec.rb58
-rw-r--r--spec/controllers/help_controller_spec.rb2
-rw-r--r--spec/controllers/public_body_controller_spec.rb53
-rw-r--r--spec/controllers/request_controller_spec.rb256
-rw-r--r--spec/controllers/services_controller_spec.rb10
-rw-r--r--spec/controllers/track_controller_spec.rb17
-rw-r--r--spec/controllers/user_controller_spec.rb80
-rw-r--r--spec/fixtures/foi_attachments.yml1
-rw-r--r--spec/fixtures/theme_views/core/application_mailer/core_only.html.erb (renamed from spec/fixtures/theme_views/core/application_mailer/core_only.rhtml)0
-rw-r--r--spec/fixtures/theme_views/core/application_mailer/multipart_core_only.html.erb (renamed from spec/fixtures/theme_views/core/application_mailer/multipart_core_only.rhtml)0
-rw-r--r--spec/fixtures/theme_views/core/application_mailer/simple.html.erb (renamed from spec/fixtures/theme_views/core/application_mailer/simple.rhtml)0
-rw-r--r--spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.html.erb (renamed from spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.rhtml)0
-rw-r--r--spec/fixtures/theme_views/theme_one/application_mailer/simple.html.erb (renamed from spec/fixtures/theme_views/theme_one/application_mailer/simple.rhtml)0
-rw-r--r--spec/fixtures/theme_views/theme_one/application_mailer/theme_only.html.erb (renamed from spec/fixtures/theme_views/theme_one/application_mailer/theme_only.rhtml)0
-rw-r--r--spec/helpers/link_to_helper_spec.rb5
-rw-r--r--spec/integration/admin_spec.rb2
-rw-r--r--spec/integration/errors_spec.rb13
-rw-r--r--spec/integration/search_request_spec.rb6
-rw-r--r--spec/lib/mail_handler/mail_handler_spec.rb2
-rw-r--r--spec/lib/sendmail_return_path_spec.rb15
-rw-r--r--spec/lib/timezone_fixes_spec.rb5
-rw-r--r--spec/mailers/application_mailer_spec.rb (renamed from spec/models/application_mailer_spec.rb)46
-rw-r--r--spec/mailers/outgoing_mailer_spec.rb (renamed from spec/models/outgoing_mailer_spec.rb)0
-rw-r--r--spec/mailers/request_mailer_spec.rb (renamed from spec/models/request_mailer_spec.rb)28
-rw-r--r--spec/mailers/track_mailer_spec.rb (renamed from spec/models/track_mailer_spec.rb)24
-rw-r--r--spec/models/censor_rule_spec.rb22
-rw-r--r--spec/models/contact_mailer_spec.rb8
-rw-r--r--spec/models/incoming_message_spec.rb5
-rw-r--r--spec/models/info_request_event_spec.rb2
-rw-r--r--spec/models/info_request_spec.rb16
-rw-r--r--spec/models/mail_server_log_spec.rb10
-rw-r--r--spec/models/public_body_spec.rb14
-rw-r--r--spec/models/user_mailer_spec.rb8
-rw-r--r--spec/models/user_spec.rb8
-rw-r--r--spec/script/mailin_spec.rb2
-rw-r--r--spec/spec_helper.rb349
-rw-r--r--spec/support/email_helpers.rb23
-rw-r--r--spec/support/load_file_fixtures.rb14
-rw-r--r--spec/support/xapian_index.rb42
-rw-r--r--spec/views/public_body/show.html.erb_spec.rb (renamed from spec/views/public_body/show.rhtml_spec.rb)62
-rw-r--r--spec/views/request/_after_actions.html.erb_spec.rb (renamed from spec/views/request/_after_actions.rhtml_spec.rb)71
-rw-r--r--spec/views/request/_describe_state.html.erb_spec.rb (renamed from spec/views/request/_describe_state.rhtml_spec.rb)28
-rw-r--r--spec/views/request/list.html.erb_spec.rb (renamed from spec/views/request/list.rhtml_spec.rb)32
-rw-r--r--spec/views/request/show.html.erb_spec.rb (renamed from spec/views/request/show.rhtml_spec.rb)54
-rw-r--r--spec/views/request_game/play.html.erb_spec.rb (renamed from spec/views/request_game/play.rhtml_spec.rb)14
-rw-r--r--vendor/plugins/active_record_base_without_table/CHANGELOG3
-rw-r--r--vendor/plugins/active_record_base_without_table/MIT-LICENSE20
-rw-r--r--vendor/plugins/active_record_base_without_table/README29
-rw-r--r--vendor/plugins/active_record_base_without_table/Rakefile22
-rw-r--r--vendor/plugins/active_record_base_without_table/lib/active_record/base_without_table.rb26
-rw-r--r--vendor/plugins/active_record_base_without_table/test/abstract_unit.rb15
-rw-r--r--vendor/plugins/active_record_base_without_table/test/active_record_base_without_table_test.rb41
-rw-r--r--vendor/plugins/active_record_base_without_table/test/database.yml6
-rw-r--r--vendor/plugins/acts_as_versioned/CHANGELOG82
-rw-r--r--vendor/plugins/acts_as_versioned/MIT-LICENSE20
-rw-r--r--vendor/plugins/acts_as_versioned/README28
-rw-r--r--vendor/plugins/acts_as_versioned/RUNNING_UNIT_TESTS41
-rw-r--r--vendor/plugins/acts_as_versioned/Rakefile182
-rw-r--r--vendor/plugins/acts_as_versioned/init.rb1
-rw-r--r--vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb490
-rw-r--r--vendor/plugins/acts_as_versioned/test/abstract_unit.rb48
-rw-r--r--vendor/plugins/acts_as_versioned/test/database.yml18
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/authors.yml6
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/landmark.rb3
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml7
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/landmarks.yml7
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/locked_pages.yml10
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml27
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb15
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/page.rb43
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/page_versions.yml16
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/pages.yml8
-rw-r--r--vendor/plugins/acts_as_versioned/test/fixtures/widget.rb6
-rw-r--r--vendor/plugins/acts_as_versioned/test/migration_test.rb46
-rw-r--r--vendor/plugins/acts_as_versioned/test/schema.rb80
-rw-r--r--vendor/plugins/acts_as_versioned/test/versioned_test.rb352
-rw-r--r--vendor/plugins/acts_as_xapian/init.rb2
-rw-r--r--vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb20
-rw-r--r--vendor/plugins/exception_notification/README144
-rw-r--r--vendor/plugins/exception_notification/exception_notification.gemspec11
-rw-r--r--vendor/plugins/exception_notification/init.rb1
-rw-r--r--vendor/plugins/exception_notification/lib/exception_notification.rb7
-rw-r--r--vendor/plugins/exception_notification/lib/exception_notification/consider_local.rb31
-rw-r--r--vendor/plugins/exception_notification/lib/exception_notification/notifiable.rb66
-rw-r--r--vendor/plugins/exception_notification/lib/exception_notification/notifier.rb80
-rw-r--r--vendor/plugins/exception_notification/lib/exception_notification/notifier_helper.rb67
-rw-r--r--vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb62
-rw-r--r--vendor/plugins/exception_notification/test/test_helper.rb8
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml1
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml7
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml16
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml4
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml2
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml3
-rw-r--r--vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml6
-rw-r--r--vendor/plugins/globalize2/LICENSE21
-rw-r--r--vendor/plugins/globalize2/README.textile86
-rw-r--r--vendor/plugins/globalize2/Rakefile39
-rw-r--r--vendor/plugins/globalize2/VERSION1
-rw-r--r--vendor/plugins/globalize2/generators/db_backend.rb0
-rw-r--r--vendor/plugins/globalize2/generators/templates/db_backend_migration.rb25
-rw-r--r--vendor/plugins/globalize2/globalize2.gemspec81
-rw-r--r--vendor/plugins/globalize2/init.rb1
-rw-r--r--vendor/plugins/globalize2/lib/globalize.rb15
-rw-r--r--vendor/plugins/globalize2/lib/globalize/active_record.rb238
-rw-r--r--vendor/plugins/globalize2/lib/globalize/active_record/adapter.rb80
-rw-r--r--vendor/plugins/globalize2/lib/globalize/active_record/attributes.rb25
-rw-r--r--vendor/plugins/globalize2/lib/globalize/active_record/migration.rb44
-rw-r--r--vendor/plugins/globalize2/lib/i18n/missing_translations_log_handler.rb41
-rw-r--r--vendor/plugins/globalize2/lib/i18n/missing_translations_raise_handler.rb25
-rw-r--r--vendor/plugins/globalize2/test/active_record/fallbacks_test.rb102
-rw-r--r--vendor/plugins/globalize2/test/active_record/migration_test.rb118
-rw-r--r--vendor/plugins/globalize2/test/active_record/sti_translated_test.rb49
-rw-r--r--vendor/plugins/globalize2/test/active_record/translates_test.rb96
-rw-r--r--vendor/plugins/globalize2/test/active_record/translation_class_test.rb30
-rw-r--r--vendor/plugins/globalize2/test/active_record/validation_tests.rb75
-rw-r--r--vendor/plugins/globalize2/test/active_record_test.rb467
-rw-r--r--vendor/plugins/globalize2/test/all.rb2
-rw-r--r--vendor/plugins/globalize2/test/data/models.rb56
-rw-r--r--vendor/plugins/globalize2/test/data/no_globalize_schema.rb11
-rw-r--r--vendor/plugins/globalize2/test/data/schema.rb55
-rw-r--r--vendor/plugins/globalize2/test/i18n/missing_translations_test.rb36
-rw-r--r--vendor/plugins/globalize2/test/test_helper.rb76
-rw-r--r--vendor/plugins/has_tag_string/lib/has_tag_string.rb2
-rw-r--r--vendor/plugins/rails_xss/MIT-LICENSE20
-rw-r--r--vendor/plugins/rails_xss/README.markdown91
-rw-r--r--vendor/plugins/rails_xss/Rakefile23
-rw-r--r--vendor/plugins/rails_xss/init.rb9
-rw-r--r--vendor/plugins/rails_xss/lib/rails_xss.rb3
-rw-r--r--vendor/plugins/rails_xss/lib/rails_xss/action_view.rb111
-rw-r--r--vendor/plugins/rails_xss/lib/rails_xss/erubis.rb41
-rw-r--r--vendor/plugins/rails_xss/lib/rails_xss/string_ext.rb65
-rw-r--r--vendor/plugins/rails_xss/lib/tasks/rails_xss_tasks.rake4
-rw-r--r--vendor/plugins/rails_xss/test/active_record_helper_test.rb74
-rw-r--r--vendor/plugins/rails_xss/test/asset_tag_helper_test.rb49
-rw-r--r--vendor/plugins/rails_xss/test/caching_test.rb54
-rw-r--r--vendor/plugins/rails_xss/test/content_for_test.rb39
-rw-r--r--vendor/plugins/rails_xss/test/date_helper_test.rb29
-rw-r--r--vendor/plugins/rails_xss/test/deprecated_output_safety_test.rb112
-rw-r--r--vendor/plugins/rails_xss/test/erb_util_test.rb36
-rw-r--r--vendor/plugins/rails_xss/test/form_helper_test.rb1447
-rw-r--r--vendor/plugins/rails_xss/test/form_tag_helper_test.rb354
-rw-r--r--vendor/plugins/rails_xss/test/javascript_helper_test.rb10
-rw-r--r--vendor/plugins/rails_xss/test/output_escaping_test.rb19
-rw-r--r--vendor/plugins/rails_xss/test/output_safety_test.rb115
-rw-r--r--vendor/plugins/rails_xss/test/rails_xss_test.rb23
-rw-r--r--vendor/plugins/rails_xss/test/raw_output_helper_test.rb18
-rw-r--r--vendor/plugins/rails_xss/test/safe_buffer_test.rb51
-rw-r--r--vendor/plugins/rails_xss/test/tag_helper_test.rb21
-rw-r--r--vendor/plugins/rails_xss/test/test_helper.rb6
-rw-r--r--vendor/plugins/rails_xss/test/text_helper_test.rb30
-rw-r--r--vendor/plugins/rails_xss/test/url_for_test.rb39
-rw-r--r--vendor/plugins/strip_attributes/lib/strip_attributes.rb16
-rw-r--r--vendor/plugins/strip_attributes/test/strip_attributes_test.rb6
512 files changed, 6638 insertions, 13232 deletions
diff --git a/.gitignore b/.gitignore
index efba35668..e564c30b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,4 @@ bin/
config/aliases
.sass-cache
alaveteli.sublime*
+webrat.log
diff --git a/.gitmodules b/.gitmodules
index 4f9ece146..42d5db56b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,8 @@
[submodule "commonlib"]
path = commonlib
url = git://git.mysociety.org/commonlib
+# config/locales is a symbolic link to vendor/rails-locales/rails/locale
+# In Rails 3, this should be removed and the gem rails-i18n installed instead
[submodule "vendor/rails-locales"]
path = vendor/rails-locales
url = git://github.com/svenfuchs/rails-i18n.git
diff --git a/.rspec b/.rspec
new file mode 100644
index 000000000..7488cbe77
--- /dev/null
+++ b/.rspec
@@ -0,0 +1 @@
+--color --drb
diff --git a/.rvmrc b/.rvmrc
index 1f2700fc2..339f08013 100644
--- a/.rvmrc
+++ b/.rvmrc
@@ -5,10 +5,8 @@
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
# Only full ruby name is supported here, for short names use:
-# echo "rvm use 1.8.7" > .rvmrc
-environment_id="ruby-1.8.7-p370"
-
-rubygems_version="1.6.2"
+# echo "rvm use 1.9.3" > .rvmrc
+environment_id="1.9.3-p392"
# Uncomment the following lines if you want to verify rvm version per project
# rvmrc_rvm_version="1.14.10 (stable)" # 1.10.1 seams as a safe start
@@ -38,10 +36,6 @@ else
}
fi
-if [[ "$(gem --version)" != "${rubygems_version}" ]] ; then
- rvm rubygems ${rubygems_version}
-fi
-
# If you use bundler, this might be useful to you:
# if [[ -s Gemfile ]] && {
# ! builtin command -v bundle >/dev/null ||
diff --git a/Gemfile b/Gemfile
index d5fa4ed72..bf9767142 100644
--- a/Gemfile
+++ b/Gemfile
@@ -7,10 +7,7 @@ if File.exist? "/etc/debian_version" and File.open("/etc/debian_version").read.s
end
source 'https://rubygems.org'
-# A fork of rails that is kept up to date with security patches
-git "git://github.com/mysociety/rails.git", :tag => "v2.3.18.1" do
- gem 'rails'
-end
+gem 'rails', '3.1.12'
gem 'pg'
gem 'fast_gettext', '>= 0.6.0'
@@ -19,12 +16,11 @@ gem 'gettext_i18n_rails', '>= 0.7.1'
gem 'gettext', '~> 2.3.3'
gem 'json'
gem 'mahoro'
-gem 'mail', '~>2.4.4', :platforms => :ruby_19
gem 'memcache-client', :require => 'memcache'
gem 'locale', '>= 2.0.5'
gem 'net-http-local'
gem 'net-purge'
-gem 'rack', '~> 1.1.0'
+gem 'rack'
gem 'rdoc'
gem 'recaptcha', '~> 0.3.1', :require => 'recaptcha/rails'
# :require avoids "already initialized constant" warnings
@@ -33,7 +29,7 @@ gem 'routing-filter', '~> 0.2.4'
gem 'rake', '0.9.2.2'
gem 'ruby-msg', '~> 1.5.0'
gem 'vpim'
-gem 'will_paginate', '~> 2.3.11'
+gem 'will_paginate'
# when 1.2.9 is released by the maintainer, we can stop using this fork:
gem 'xapian-full-alaveteli', '~> 1.2.9.5'
gem 'xml-simple'
@@ -41,19 +37,17 @@ gem 'zip'
gem 'capistrano'
gem 'syslog_protocol'
gem 'newrelic_rpm'
-# erubis is required by rails_xss. Both erubis and rails_xss can be removed after upgrading to Rails 3.
-gem 'erubis'
-# rack-ssl won't be needed on upgrade to Rails 3.1 as something like it is baked in
-gem 'rack-ssl'
+# Use until this PR is merged: https://github.com/svenfuchs/globalize3/pull/191
+gem 'globalize3', :git => 'git://github.com/henare/globalize3.git', :branch => 'not-null-empty-attributes'
+# New gem releases aren't being done. master is newer and supports Rails > 3.0
+gem 'acts_as_versioned', :git => 'git://github.com/technoweenie/acts_as_versioned.git'
+gem 'dynamic_form'
+gem 'exception_notification'
group :test do
gem 'fakeweb'
- gem 'rspec-rails', '~> 1.3.4'
- gem 'test-unit', '~> 1.2.3', :platforms => :ruby_19
gem 'coveralls', :require => false
- # Using webrat because the preferred (capybara) doesn't work out of the box with rspec 1
- gem 'webrat', :git => 'https://github.com/brynary/webrat', :ref => 'bea5b313783eaaf17e38a05a4eaa8c45c1eedd2a'
- gem 'launchy'
+ gem 'webrat'
end
group :development do
@@ -62,8 +56,13 @@ end
group :develop do
gem 'ruby-debug', :platforms => :ruby_18
- gem 'ruby-debug19', :platforms => :ruby_19
+ gem 'debugger', :platforms => :ruby_19
gem 'bootstrap-sass'
gem 'compass'
gem 'annotate'
end
+
+group :test, :development do
+ gem 'rspec-rails'
+ gem 'spork-rails'
+end
diff --git a/Gemfile.lock b/Gemfile.lock
index 23a362d08..6c190836f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,52 +1,64 @@
GIT
- remote: git://github.com/mysociety/rails.git
- revision: c0d325a13e133b14d2faa01053226cd77c1378a7
- tag: v2.3.18.1
+ remote: git://github.com/henare/globalize3.git
+ revision: 2931f559cbed8843ab7d16278d70ce99a0239132
+ branch: not-null-empty-attributes
specs:
- actionmailer (2.3.18)
- actionpack (= 2.3.18)
- actionpack (2.3.18)
- activesupport (= 2.3.18)
- rack (~> 1.1.0)
- activerecord (2.3.18)
- activesupport (= 2.3.18)
- activeresource (2.3.18)
- activesupport (= 2.3.18)
- activesupport (2.3.18)
- rails (2.3.18)
- actionmailer (= 2.3.18)
- actionpack (= 2.3.18)
- activerecord (= 2.3.18)
- activeresource (= 2.3.18)
- activesupport (= 2.3.18)
- rake (>= 0.8.3)
+ globalize3 (0.3.0)
+ activemodel (>= 3.0.0)
+ activerecord (>= 3.0.0)
+ paper_trail (~> 2)
GIT
- remote: https://github.com/brynary/webrat
- revision: bea5b313783eaaf17e38a05a4eaa8c45c1eedd2a
- ref: bea5b313783eaaf17e38a05a4eaa8c45c1eedd2a
+ remote: git://github.com/technoweenie/acts_as_versioned.git
+ revision: 63b1fc8529d028fae632fe80ec0cb25df56cd76b
specs:
- webrat (0.7.3)
- nokogiri (>= 1.2.0)
- rack (>= 1.0)
- rack-test (>= 0.5.3)
+ acts_as_versioned (0.6.0)
+ activerecord (>= 3.0.9)
GEM
remote: https://rubygems.org/
specs:
- addressable (2.3.3)
+ actionmailer (3.1.12)
+ actionpack (= 3.1.12)
+ mail (~> 2.4.4)
+ actionpack (3.1.12)
+ activemodel (= 3.1.12)
+ activesupport (= 3.1.12)
+ builder (~> 3.0.0)
+ erubis (~> 2.7.0)
+ i18n (~> 0.6)
+ rack (~> 1.3.6)
+ rack-cache (~> 1.2)
+ rack-mount (~> 0.8.2)
+ rack-test (~> 0.6.1)
+ sprockets (~> 2.0.4)
+ activemodel (3.1.12)
+ activesupport (= 3.1.12)
+ builder (~> 3.0.0)
+ i18n (~> 0.6)
+ activerecord (3.1.12)
+ activemodel (= 3.1.12)
+ activesupport (= 3.1.12)
+ arel (~> 2.2.3)
+ tzinfo (~> 0.3.29)
+ activeresource (3.1.12)
+ activemodel (= 3.1.12)
+ activesupport (= 3.1.12)
+ activesupport (3.1.12)
+ multi_json (~> 1.0)
annotate (2.5.0)
rake
- archive-tar-minitar (0.5.2)
- bootstrap-sass (2.3.0.1)
+ arel (2.2.3)
+ bootstrap-sass (2.2.1.1)
sass (~> 3.2)
- capistrano (2.14.2)
+ builder (3.0.4)
+ capistrano (2.13.5)
highline
net-scp (>= 1.0.0)
net-sftp (>= 2.0.0)
net-ssh (>= 2.0.14)
net-ssh-gateway (>= 1.1.0)
- chunky_png (1.2.7)
+ chunky_png (1.2.6)
colorize (0.5.8)
columnize (0.3.6)
compass (0.12.2)
@@ -60,31 +72,35 @@ GEM
simplecov (>= 0.7)
thor
daemons (1.1.9)
+ debugger (1.5.0)
+ columnize (>= 0.3.1)
+ debugger-linecache (~> 1.2.0)
+ debugger-ruby_core_source (~> 1.2.0)
+ debugger-linecache (1.2.0)
+ debugger-ruby_core_source (1.2.0)
+ diff-lcs (1.1.3)
+ dynamic_form (1.1.4)
erubis (2.7.0)
- eventmachine (1.0.3)
+ eventmachine (1.0.0)
+ exception_notification (3.0.1)
+ actionmailer (>= 3.0.4)
fakeweb (1.3.0)
- fast_gettext (0.7.0)
+ fast_gettext (0.6.11)
fastercsv (1.5.5)
- fssm (0.2.10)
+ fssm (0.2.9)
gettext (2.3.7)
levenshtein
locale
- gettext_i18n_rails (0.9.2)
+ gettext_i18n_rails (0.8.0)
fast_gettext (>= 0.4.8)
- haml (4.0.0)
- tilt
+ haml (3.1.7)
highline (1.6.15)
- hoe (3.5.1)
- rake (>= 0.8, < 11.0)
+ hike (1.2.1)
i18n (0.6.4)
json (1.7.7)
- launchy (2.2.0)
- addressable (~> 2.3)
levenshtein (0.2.2)
linecache (0.46)
rbx-require-relative (> 0.0.4)
- linecache19 (0.5.12)
- ruby_core_source (>= 0.1.4)
locale (2.0.8)
mahoro (0.3)
mail (2.4.4)
@@ -103,59 +119,78 @@ GEM
thin
memcache-client (1.8.5)
mime-types (1.21)
- multi_json (1.6.1)
+ multi_json (1.7.1)
net-http-local (0.1.2)
net-purge (0.1.0)
- net-scp (1.1.0)
- net-ssh (>= 2.6.5)
- net-sftp (2.1.1)
- net-ssh (>= 2.6.5)
- net-ssh (2.6.6)
- net-ssh-gateway (1.2.0)
- net-ssh (>= 2.6.5)
- newrelic_rpm (3.5.8.72)
- nokogiri (1.5.6)
+ net-scp (1.0.4)
+ net-ssh (>= 1.99.1)
+ net-sftp (2.0.5)
+ net-ssh (>= 2.0.9)
+ net-ssh (2.6.2)
+ net-ssh-gateway (1.1.0)
+ net-ssh (>= 1.99.1)
+ newrelic_rpm (3.5.3.25)
+ nokogiri (1.5.5)
+ paper_trail (2.7.0)
+ activerecord (~> 3.0)
+ railties (~> 3.0)
pg (0.14.1)
polyglot (0.3.3)
- rack (1.1.6)
+ rack (1.3.10)
+ rack-cache (1.2)
+ rack (>= 0.4)
+ rack-mount (0.8.3)
+ rack (>= 1.0.0)
rack-ssl (1.3.3)
rack
rack-test (0.6.2)
rack (>= 1.0)
+ rails (3.1.12)
+ actionmailer (= 3.1.12)
+ actionpack (= 3.1.12)
+ activerecord (= 3.1.12)
+ activeresource (= 3.1.12)
+ activesupport (= 3.1.12)
+ bundler (~> 1.0)
+ railties (= 3.1.12)
+ railties (3.1.12)
+ actionpack (= 3.1.12)
+ activesupport (= 3.1.12)
+ rack-ssl (~> 1.3.2)
+ rake (>= 0.8.7)
+ rdoc (~> 3.4)
+ thor (~> 0.14.6)
rake (0.9.2.2)
rbx-require-relative (0.0.9)
- rdoc (4.0.0)
+ rdoc (3.12.2)
json (~> 1.4)
- recaptcha (0.3.5)
+ recaptcha (0.3.4)
rest-client (1.6.7)
mime-types (>= 1.16)
rmagick (2.13.2)
routing-filter (0.2.4)
actionpack
- rspec (1.3.2)
- rspec-rails (1.3.4)
- rack (>= 1.0.0)
- rspec (~> 1.3.1)
+ rspec-core (2.12.1)
+ rspec-expectations (2.12.0)
+ diff-lcs (~> 1.1.3)
+ rspec-mocks (2.12.0)
+ rspec-rails (2.12.0)
+ actionpack (>= 3.0)
+ activesupport (>= 3.0)
+ railties (>= 3.0)
+ rspec-core (~> 2.12.0)
+ rspec-expectations (~> 2.12.0)
+ rspec-mocks (~> 2.12.0)
ruby-debug (0.10.4)
columnize (>= 0.1)
ruby-debug-base (~> 0.10.4.0)
ruby-debug-base (0.10.4)
linecache (>= 0.3)
- ruby-debug-base19 (0.11.25)
- columnize (>= 0.3.1)
- linecache19 (>= 0.5.11)
- ruby_core_source (>= 0.1.4)
- ruby-debug19 (0.11.6)
- columnize (>= 0.3.1)
- linecache19 (>= 0.5.11)
- ruby-debug-base19 (>= 0.11.19)
ruby-msg (1.5.1)
ruby-ole (>= 1.2.8)
vpim (>= 0.360)
ruby-ole (1.2.11.6)
- ruby_core_source (0.1.5)
- archive-tar-minitar (>= 0.5.2)
- sass (3.2.7)
+ sass (3.2.3)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
@@ -166,23 +201,34 @@ GEM
skinny (0.2.3)
eventmachine (~> 1.0.0)
thin (~> 1.5.0)
- sqlite3 (1.3.7)
+ spork (1.0.0rc3)
+ spork-rails (3.2.1)
+ rails (>= 3.0.0, < 3.3.0)
+ spork (>= 1.0rc0)
+ sprockets (2.0.4)
+ hike (~> 1.2)
+ rack (~> 1.0)
+ tilt (~> 1.1, != 1.3.0)
+ sqlite3 (1.3.6)
sqlite3-ruby (1.3.3)
sqlite3 (>= 1.3.3)
syslog_protocol (0.9.2)
- test-unit (1.2.3)
- hoe (>= 1.5.1)
thin (1.5.0)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
- thor (0.17.0)
- tilt (1.3.5)
+ thor (0.14.6)
+ tilt (1.3.6)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
+ tzinfo (0.3.37)
vpim (0.695)
- will_paginate (2.3.16)
+ webrat (0.7.3)
+ nokogiri (>= 1.2.0)
+ rack (>= 1.0)
+ rack-test (>= 0.5.3)
+ will_paginate (3.0.4)
xapian-full-alaveteli (1.2.9.5)
xml-simple (1.1.2)
zip (2.0.2)
@@ -191,45 +237,45 @@ PLATFORMS
ruby
DEPENDENCIES
+ acts_as_versioned!
annotate
bootstrap-sass
capistrano
compass
coveralls
- erubis
+ debugger
+ dynamic_form
+ exception_notification
fakeweb
fast_gettext (>= 0.6.0)
fastercsv (>= 1.5.5)
gettext (~> 2.3.3)
gettext_i18n_rails (>= 0.7.1)
+ globalize3!
json
- launchy
locale (>= 2.0.5)
mahoro
- mail (~> 2.4.4)
mailcatcher
memcache-client
net-http-local
net-purge
newrelic_rpm
pg
- rack (~> 1.1.0)
- rack-ssl
- rails!
+ rack
+ rails (= 3.1.12)
rake (= 0.9.2.2)
rdoc
recaptcha (~> 0.3.1)
rmagick
routing-filter (~> 0.2.4)
- rspec-rails (~> 1.3.4)
+ rspec-rails
ruby-debug
- ruby-debug19
ruby-msg (~> 1.5.0)
+ spork-rails
syslog_protocol
- test-unit (~> 1.2.3)
vpim
- webrat!
- will_paginate (~> 2.3.11)
+ webrat
+ will_paginate
xapian-full-alaveteli (~> 1.2.9.5)
xml-simple
zip
diff --git a/README-rails.txt b/README-rails.txt
deleted file mode 100644
index 025ee5e84..000000000
--- a/README-rails.txt
+++ /dev/null
@@ -1,188 +0,0 @@
-== Welcome to Rails
-
-Rails is a web-application and persistence framework that includes everything
-needed to create database-backed web-applications according to the
-Model-View-Control pattern of separation. This pattern splits the view (also
-called the presentation) into "dumb" templates that are primarily responsible
-for inserting pre-built data in between HTML tags. The model contains the
-"smart" domain objects (such as Account, Product, Person, Post) that holds all
-the business logic and knows how to persist themselves to a database. The
-controller handles the incoming requests (such as Save New Account, Update
-Product, Show Post) by manipulating the model and directing data to the view.
-
-In Rails, the model is handled by what's called an object-relational mapping
-layer entitled Active Record. This layer allows you to present the data from
-database rows as objects and embellish these data objects with business logic
-methods. You can read more about Active Record in
-link:files/vendor/rails/activerecord/README.html.
-
-The controller and view are handled by the Action Pack, which handles both
-layers by its two parts: Action View and Action Controller. These two layers
-are bundled in a single package due to their heavy interdependence. This is
-unlike the relationship between the Active Record and Action Pack that is much
-more separate. Each of these packages can be used independently outside of
-Rails. You can read more about Action Pack in
-link:files/vendor/rails/actionpack/README.html.
-
-
-== Getting started
-
-1. At the command prompt, start a new rails application using the rails command
- and your application name. Ex: rails myapp
- (If you've downloaded rails in a complete tgz or zip, this step is already done)
-2. Change directory into myapp and start the web server: <tt>script/server</tt> (run with --help for options)
-3. Go to http://localhost:3000/ and get "Welcome aboard: You’re riding the Rails!"
-4. Follow the guidelines to start developing your application
-
-
-== Web Servers
-
-By default, Rails will try to use Mongrel and lighttpd if they are installed, otherwise
-Rails will use the WEBrick, the webserver that ships with Ruby. When you run script/server,
-Rails will check if Mongrel exists, then lighttpd and finally fall back to WEBrick. This ensures
-that you can always get up and running quickly.
-
-Mongrel is a Ruby-based webserver with a C-component (which requires compilation) that is
-suitable for development and deployment of Rails applications. If you have Ruby Gems installed,
-getting up and running with mongrel is as easy as: <tt>gem install mongrel</tt>.
-More info at: http://mongrel.rubyforge.org
-
-If Mongrel is not installed, Rails will look for lighttpd. It's considerably faster than
-Mongrel and WEBrick and also suited for production use, but requires additional
-installation and currently only works well on OS X/Unix (Windows users are encouraged
-to start with Mongrel). We recommend version 1.4.11 and higher. You can download it from
-http://www.lighttpd.net.
-
-And finally, if neither Mongrel or lighttpd are installed, Rails will use the built-in Ruby
-web server, WEBrick. WEBrick is a small Ruby web server suitable for development, but not
-for production.
-
-But of course its also possible to run Rails on any platform that supports FCGI.
-Apache, LiteSpeed, IIS are just a few. For more information on FCGI,
-please visit: http://wiki.rubyonrails.com/rails/pages/FastCGI
-
-
-== Debugging Rails
-
-Have "tail -f" commands running on the server.log and development.log. Rails will
-automatically display debugging and runtime information to these files. Debugging
-info will also be shown in the browser on requests from 127.0.0.1.
-
-
-== Breakpoints
-
-Breakpoint support is available through the script/breakpointer client. This
-means that you can break out of execution at any point in the code, investigate
-and change the model, AND then resume execution! Example:
-
- class WeblogController < ActionController::Base
- def index
- @posts = Post.find(:all)
- breakpoint "Breaking out from the list"
- end
- end
-
-So the controller will accept the action, run the first line, then present you
-with a IRB prompt in the breakpointer window. Here you can do things like:
-
-Executing breakpoint "Breaking out from the list" at .../webrick_server.rb:16 in 'breakpoint'
-
- >> @posts.inspect
- => "[#<Post:0x14a6be8 @attributes={\"title\"=>nil, \"body\"=>nil, \"id\"=>\"1\"}>,
- #<Post:0x14a6620 @attributes={\"title\"=>\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]"
- >> @posts.first.title = "hello from a breakpoint"
- => "hello from a breakpoint"
-
-...and even better is that you can examine how your runtime objects actually work:
-
- >> f = @posts.first
- => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
- >> f.
- Display all 152 possibilities? (y or n)
-
-Finally, when you're ready to resume execution, you press CTRL-D
-
-
-== Console
-
-You can interact with the domain model by starting the console through <tt>script/console</tt>.
-Here you'll have all parts of the application configured, just like it is when the
-application is running. You can inspect domain models, change values, and save to the
-database. Starting the script without arguments will launch it in the development environment.
-Passing an argument will specify a different environment, like <tt>script/console production</tt>.
-
-To reload your controllers and models after launching the console run <tt>reload!</tt>
-
-To reload your controllers and models after launching the console run <tt>reload!</tt>
-
-
-
-== Description of contents
-
-app
- Holds all the code that's specific to this particular application.
-
-app/controllers
- Holds controllers that should be named like weblogs_controller.rb for
- automated URL mapping. All controllers should descend from ApplicationController
- which itself descends from ActionController::Base.
-
-app/models
- Holds models that should be named like post.rb.
- Most models will descend from ActiveRecord::Base.
-
-app/views
- Holds the template files for the view that should be named like
- weblogs/index.rhtml for the WeblogsController#index action. All views use eRuby
- syntax.
-
-app/views/layouts
- Holds the template files for layouts to be used with views. This models the common
- header/footer method of wrapping views. In your views, define a layout using the
- <tt>layout :default</tt> and create a file named default.rhtml. Inside default.rhtml,
- call <% yield %> to render the view using this layout.
-
-app/helpers
- Holds view helpers that should be named like weblogs_helper.rb. These are generated
- for you automatically when using script/generate for controllers. Helpers can be used to
- wrap functionality for your views into methods.
-
-config
- Configuration files for the Rails environment, the routing map, the database, and other dependencies.
-
-components
- Self-contained mini-applications that can bundle together controllers, models, and views.
-
-db
- Contains the database schema in schema.rb. db/migrate contains all
- the sequence of Migrations for your schema.
-
-doc
- This directory is where your application documentation will be stored when generated
- using <tt>rake doc:app</tt>
-
-lib
- Application specific libraries. Basically, any kind of custom code that doesn't
- belong under controllers, models, or helpers. This directory is in the load path.
-
-public
- The directory available for the web server. Contains subdirectories for images, stylesheets,
- and javascripts. Also contains the dispatchers and the default HTML files. This should be
- set as the DOCUMENT_ROOT of your web server.
-
-script
- Helper scripts for automation and generation.
-
-spec
- Unit and functional specifications along with fixtures, using rspec. We use
- this instead of test.
-
-test
- DEPRECATED for this project, see 'spec' instead. Unit and functional tests
- along with fixtures. When using the script/generate scripts, template test
- files will be generated for you and placed in this directory.
-
-vendor
- External libraries that the application depends on. Also includes the plugins subdirectory.
- This directory is in the load path.
-
diff --git a/Rakefile b/Rakefile
index eb9ec718b..6e86b06f6 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,11 +1,7 @@
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
-require(File.join(File.dirname(__FILE__), 'config', 'boot'))
-
+require File.expand_path('../config/application', __FILE__)
require 'rake'
-require 'rake/testtask'
-require 'rdoc/task'
-
-require 'tasks/rails'
+Alaveteli::Application.load_tasks
diff --git a/app/controllers/admin_censor_rule_controller.rb b/app/controllers/admin_censor_rule_controller.rb
index d3e9e47d2..6f79b5ba1 100644
--- a/app/controllers/admin_censor_rule_controller.rb
+++ b/app/controllers/admin_censor_rule_controller.rb
@@ -2,7 +2,7 @@
# For modifying requests.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class AdminCensorRuleController < AdminController
def new
diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb
index e90f03187..0bccd3358 100644
--- a/app/controllers/admin_controller.rb
+++ b/app/controllers/admin_controller.rb
@@ -2,7 +2,7 @@
# All admin controllers are dervied from this.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'fileutils'
@@ -51,7 +51,7 @@ class AdminController < ApplicationController
# For administration interface, return display name of authenticated user
def admin_current_user
- if Configuration::skip_admin_auth
+ if AlaveteliConfiguration::skip_admin_auth
admin_http_auth_user
else
session[:admin_name]
@@ -74,12 +74,12 @@ class AdminController < ApplicationController
end
def authenticate
- if Configuration::skip_admin_auth
+ if AlaveteliConfiguration::skip_admin_auth
session[:using_admin] = 1
return
else
if session[:using_admin].nil? || session[:admin_name].nil?
- if params[:emergency].nil? || Configuration::disable_emergency_user
+ if params[:emergency].nil? || AlaveteliConfiguration::disable_emergency_user
if authenticated?(
:web => _("To log into the administrative interface"),
:email => _("Then you can log into the administrative interface"),
@@ -97,7 +97,7 @@ class AdminController < ApplicationController
end
else
authenticate_or_request_with_http_basic do |user_name, password|
- if user_name == Configuration::admin_username && password == Configuration::admin_password
+ if user_name == AlaveteliConfiguration::admin_username && password == AlaveteliConfiguration::admin_password
session[:using_admin] = 1
session[:admin_name] = user_name
else
diff --git a/app/controllers/admin_general_controller.rb b/app/controllers/admin_general_controller.rb
index 800678787..b64fcac3e 100644
--- a/app/controllers/admin_general_controller.rb
+++ b/app/controllers/admin_general_controller.rb
@@ -2,7 +2,7 @@
# Controller for main admin pages.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class AdminGeneralController < AdminController
skip_before_filter :authenticate, :only => :admin_js
diff --git a/app/controllers/admin_public_body_controller.rb b/app/controllers/admin_public_body_controller.rb
index bb5e98852..52b56eda2 100644
--- a/app/controllers/admin_public_body_controller.rb
+++ b/app/controllers/admin_public_body_controller.rb
@@ -2,7 +2,7 @@
# Controller for editing public bodies from the admin interface.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require "public_body_categories"
@@ -14,7 +14,7 @@ class AdminPublicBodyController < AdminController
def _lookup_query_internal
@locale = self.locale_from_params()
- PublicBody.with_locale(@locale) do
+ I18n.with_locale(@locale) do
@query = params[:query]
if @query == ""
@query = nil
@@ -23,12 +23,10 @@ class AdminPublicBodyController < AdminController
if @page == ""
@page = nil
end
- @public_bodies = PublicBody.paginate :order => "public_body_translations.name", :page => @page, :per_page => 100,
- :conditions => @query.nil? ? "public_body_translations.locale = '#{@locale}'" :
+ @public_bodies = PublicBody.joins(:translations).where(@query.nil? ? "public_body_translations.locale = '#{@locale}'" :
["(lower(public_body_translations.name) like lower('%'||?||'%') or
lower(public_body_translations.short_name) like lower('%'||?||'%') or
- lower(public_body_translations.request_email) like lower('%'||?||'%' )) AND (public_body_translations.locale = '#{@locale}')", @query, @query, @query],
- :joins => :translations
+ lower(public_body_translations.request_email) like lower('%'||?||'%' )) AND (public_body_translations.locale = '#{@locale}')", @query, @query, @query]).paginate :order => "public_body_translations.name", :page => @page, :per_page => 100
end
@public_bodies_by_tag = PublicBody.find_by_tag(@query)
end
@@ -75,7 +73,7 @@ class AdminPublicBodyController < AdminController
def show
@locale = self.locale_from_params()
- PublicBody.with_locale(@locale) do
+ I18n.with_locale(@locale) do
@public_body = PublicBody.find(params[:id])
render
end
@@ -87,7 +85,7 @@ class AdminPublicBodyController < AdminController
end
def create
- PublicBody.with_locale(I18n.default_locale) do
+ I18n.with_locale(I18n.default_locale) do
params[:public_body][:last_edit_editor] = admin_current_user()
@public_body = PublicBody.new(params[:public_body])
if @public_body.save
@@ -106,7 +104,7 @@ class AdminPublicBodyController < AdminController
end
def update
- PublicBody.with_locale(I18n.default_locale) do
+ I18n.with_locale(I18n.default_locale) do
params[:public_body][:last_edit_editor] = admin_current_user()
@public_body = PublicBody.find(params[:id])
if @public_body.update_attributes(params[:public_body])
@@ -120,7 +118,7 @@ class AdminPublicBodyController < AdminController
def destroy
@locale = self.locale_from_params()
- PublicBody.with_locale(@locale) do
+ I18n.with_locale(@locale) do
public_body = PublicBody.find(params[:id])
if public_body.info_requests.size > 0
diff --git a/app/controllers/admin_request_controller.rb b/app/controllers/admin_request_controller.rb
index 53055ae32..66989ea93 100644
--- a/app/controllers/admin_request_controller.rb
+++ b/app/controllers/admin_request_controller.rb
@@ -2,7 +2,7 @@
# Controller for viewing FOI requests from the admin interface.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'ostruct'
@@ -14,10 +14,14 @@ class AdminRequestController < AdminController
def list
@query = params[:query]
- @info_requests = InfoRequest.paginate :order => "created_at desc",
+ if @query
+ info_requests = InfoRequest.where(["lower(title) like lower('%'||?||'%')", @query])
+ else
+ info_requests = InfoRequest
+ end
+ @info_requests = info_requests.paginate :order => "created_at desc",
:page => params[:page],
- :per_page => 100,
- :conditions => @query.nil? ? nil : ["lower(title) like lower('%'||?||'%')", @query]
+ :per_page => 100
end
def show
@@ -25,11 +29,11 @@ class AdminRequestController < AdminController
# XXX is this *really* the only way to render a template to a
# variable, rather than to the response?
vars = OpenStruct.new(:name_to => @info_request.user_name,
- :name_from => Configuration::contact_name,
+ :name_from => AlaveteliConfiguration::contact_name,
:info_request => @info_request, :reason => params[:reason],
- :info_request_url => 'http://' + Configuration::domain + request_path(@info_request),
+ :info_request_url => 'http://' + AlaveteliConfiguration::domain + request_url(@info_request),
:site_name => site_name)
- template = File.read(File.join(File.dirname(__FILE__), "..", "views", "admin_request", "hidden_user_explanation.rhtml"))
+ template = File.read(File.join(File.dirname(__FILE__), "..", "views", "admin_request", "hidden_user_explanation.html.erb"))
@request_hidden_user_explanation = ERB.new(template).result(vars.instance_eval { binding })
end
@@ -361,11 +365,11 @@ class AdminRequestController < AdminController
info_request.save!
if ! info_request.is_external?
- ContactMailer.deliver_from_admin_message(
+ ContactMailer.from_admin_message(
info_request.user,
subject,
params[:explanation].strip.html_safe
- )
+ ).deliver
flash[:notice] = _("Your message to {{recipient_user_name}} has been sent",:recipient_user_name=>CGI.escapeHTML(info_request.user.name))
else
flash[:notice] = _("This external request has been hidden")
diff --git a/app/controllers/admin_track_controller.rb b/app/controllers/admin_track_controller.rb
index 525c96782..085c9c6cc 100644
--- a/app/controllers/admin_track_controller.rb
+++ b/app/controllers/admin_track_controller.rb
@@ -2,14 +2,18 @@
# Show email alerts / RSS feeds from admin interface.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class AdminTrackController < AdminController
def list
@query = params[:query]
- @admin_tracks = TrackThing.paginate :order => "created_at desc", :page => params[:page], :per_page => 100,
- :conditions => @query.nil? ? nil : ["lower(track_query) like lower('%'||?||'%')", @query ]
- @popular = ActiveRecord::Base.connection.select_all("select count(*) as count, title, info_request_id from track_things join info_requests on info_request_id = info_requests.id where info_request_id is not null group by info_request_id, title order by count desc limit 10;")
+ if @query
+ track_things = TrackThing.where(["lower(track_query) like lower('%'||?||'%')", @query])
+ else
+ track_things = TrackThing
+ end
+ @admin_tracks = track_things.paginate :order => "created_at desc", :page => params[:page], :per_page => 100
+ @popular = ActiveRecord::Base.connection.select_all("select count(*) as count, title, info_request_id from track_things join info_requests on info_request_id = info_requests.id where info_request_id is not null group by info_request_id, title order by count desc limit 10;")
end
private
diff --git a/app/controllers/admin_user_controller.rb b/app/controllers/admin_user_controller.rb
index feffa208e..929b93e0e 100644
--- a/app/controllers/admin_user_controller.rb
+++ b/app/controllers/admin_user_controller.rb
@@ -2,7 +2,7 @@
# Controller for viewing user accounts from the admin interface.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class AdminUserController < AdminController
def index
@@ -12,9 +12,13 @@ class AdminUserController < AdminController
def list
@query = params[:query]
- @admin_users = User.paginate :order => "name", :page => params[:page], :per_page => 100,
- :conditions => @query.nil? ? nil : ["lower(name) like lower('%'||?||'%') or
- lower(email) like lower('%'||?||'%')", @query, @query]
+ if @query
+ users = User.where(["lower(name) like lower('%'||?||'%') or
+ lower(email) like lower('%'||?||'%')", @query, @query])
+ else
+ users = User
+ end
+ @admin_users = users.paginate :order => "name", :page => params[:page], :per_page => 100
end
def list_banned
diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb
index 5d8ceb888..49b226e4b 100644
--- a/app/controllers/api_controller.rb
+++ b/app/controllers/api_controller.rb
@@ -83,7 +83,7 @@ class ApiController < ApplicationController
direction = json["direction"]
body = json["body"]
- sent_at_str = json["sent_at"]
+ sent_at = json["sent_at"]
errors = []
@@ -107,12 +107,6 @@ class ApiController < ApplicationController
errors << "The 'body' is empty"
end
- begin
- sent_at = Time.iso8601(sent_at_str)
- rescue ArgumentError
- errors << "Failed to parse 'sent_at' field as ISO8601 time: #{sent_at_str}"
- end
-
if direction == "request" && !attachments.nil?
errors << "You cannot attach files to messages in the 'request' direction"
end
@@ -155,7 +149,8 @@ class ApiController < ApplicationController
)
end
- mail = RequestMailer.create_external_response(request, body, sent_at, attachment_hashes)
+ mail = RequestMailer.external_response(request, body, sent_at, attachment_hashes)
+
request.receive(mail, mail.encoded, true)
end
render :json => {
@@ -248,6 +243,6 @@ class ApiController < ApplicationController
private
def make_url(*args)
- "http://" + Configuration::domain + "/" + args.join("/")
+ "http://" + AlaveteliConfiguration::domain + "/" + args.join("/")
end
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index f3deeb64a..029b536ec 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -5,7 +5,7 @@
# will be available for all controllers.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'open-uri'
@@ -16,9 +16,6 @@ class ApplicationController < ActionController::Base
layout "default"
include FastGettext::Translation # make functions like _, n_, N_ etc available)
- # Send notification email on exceptions
- include ExceptionNotification::Notifiable
-
# Note: a filter stops the chain if it redirects or renders something
before_filter :authentication_check
before_filter :set_gettext_locale
@@ -27,9 +24,6 @@ class ApplicationController < ActionController::Base
before_filter :set_vary_header
before_filter :set_popup_banner
- # scrub sensitive parameters from the logs
- filter_parameter_logging :password
-
def set_vary_header
response.headers['Vary'] = 'Cookie'
end
@@ -54,12 +48,12 @@ class ApplicationController < ActionController::Base
end
def set_gettext_locale
- if Configuration::include_default_locale_in_urls == false
+ if AlaveteliConfiguration::include_default_locale_in_urls == false
params_locale = params[:locale] ? params[:locale] : I18n.default_locale
else
params_locale = params[:locale]
end
- if Configuration::use_default_browser_language
+ if AlaveteliConfiguration::use_default_browser_language
requested_locale = params_locale || session[:locale] || cookies[:locale] || request.env['HTTP_ACCEPT_LANGUAGE'] || I18n.default_locale
else
requested_locale = params_locale || session[:locale] || cookies[:locale] || I18n.default_locale
@@ -74,9 +68,6 @@ class ApplicationController < ActionController::Base
end
end
- # scrub sensitive parameters from the logs
- filter_parameter_logging :password
-
helper_method :locale_from_params
# Help work out which request causes RAM spike.
@@ -92,7 +83,7 @@ class ApplicationController < ActionController::Base
# egrep "CONSUME MEMORY: [0-9]{7} KB" production.log
around_filter :record_memory
def record_memory
- record_memory = Configuration::debug_record_memory
+ record_memory = AlaveteliConfiguration::debug_record_memory
if record_memory
logger.info "Processing request for #{request.url} with Rails process #{Process.pid}"
File.read("/proc/#{Process.pid}/status").match(/VmRSS:\s+(\d+)/)
@@ -151,22 +142,23 @@ class ApplicationController < ActionController::Base
@exception_backtrace = exception.backtrace.join("\n")
@exception_class = exception.class.to_s
@exception_message = exception.message
- render :template => "general/exception_caught.rhtml", :status => @status
+ render :template => "general/exception_caught", :status => @status
end
- # For development sites.
- alias original_rescue_action_locally rescue_action_locally
- def rescue_action_locally(exception)
- # Make sure expiry time for session is set (before_filters are
- # otherwise missed by this override)
- session_remember_me
+ # FIXME: This was disabled during the Rails 3 upgrade as this is now handled by Rack
+ # # For development sites.
+ # alias original_rescue_action_locally rescue_action_locally
+ # def rescue_action_locally(exception)
+ # # Make sure expiry time for session is set (before_filters are
+ # # otherwise missed by this override)
+ # session_remember_me
- # Make sure the locale is set correctly too
- set_gettext_locale
+ # # Make sure the locale is set correctly too
+ # set_gettext_locale
- # Display default, detailed error for developers
- original_rescue_action_locally(exception)
- end
+ # # Display default, detailed error for developers
+ # original_rescue_action_locally(exception)
+ # end
def local_request?
false
@@ -175,6 +167,7 @@ class ApplicationController < ActionController::Base
# Called from test code, is a mimic of UserController.confirm, for use in following email
# links when in controller tests (though we also have full integration tests that
# can work over multiple controllers)
+ # TODO: Move this to the tests. It shouldn't be here
def test_code_redirect_by_email_token(token, controller_example_group)
post_redirect = PostRedirect.find_by_email_token(token)
if post_redirect.nil?
@@ -182,7 +175,7 @@ class ApplicationController < ActionController::Base
end
session[:user_id] = post_redirect.user.id
session[:user_circumstance] = post_redirect.circumstance
- params = controller_example_group.params_from(:get, post_redirect.local_part_uri)
+ params = Rails.application.routes.recognize_path(post_redirect.local_part_uri)
params.merge(post_redirect.post_params)
controller_example_group.get params[:action], params
end
@@ -258,7 +251,7 @@ class ApplicationController < ActionController::Base
# Check the user is logged in
def authenticated?(reason_params)
unless session[:user_id]
- post_redirect = PostRedirect.new(:uri => request.request_uri, :post_params => params,
+ post_redirect = PostRedirect.new(:uri => request.fullpath, :post_params => params,
:reason_params => reason_params)
post_redirect.save!
# 'modal' controls whether the sign-in form will be displayed in the typical full-blown
@@ -346,10 +339,10 @@ class ApplicationController < ActionController::Base
#
def check_read_only
- if !Configuration::read_only.empty?
+ if !AlaveteliConfiguration::read_only.empty?
flash[:notice] = _("<p>{{site_name}} is currently in maintenance. You can only view existing requests. You cannot make new ones, add followups or annotations, or otherwise change the database.</p> <p>{{read_only}}</p>",
:site_name => site_name,
- :read_only => Configuration::read_only)
+ :read_only => AlaveteliConfiguration::read_only)
redirect_to frontpage_url
end
@@ -552,10 +545,10 @@ class ApplicationController < ActionController::Base
def country_from_ip
country = ""
- if !Configuration::gaze_url.empty?
- country = quietly_try_to_open("#{Configuration::gaze_url}/gaze-rest?f=get_country_from_ip;ip=#{request.remote_ip}")
+ if !AlaveteliConfiguration::gaze_url.empty?
+ country = quietly_try_to_open("#{AlaveteliConfiguration::gaze_url}/gaze-rest?f=get_country_from_ip;ip=#{request.remote_ip}")
end
- country = Configuration::iso_country_code if country.empty?
+ country = AlaveteliConfiguration::iso_country_code if country.empty?
return country
end
diff --git a/app/controllers/comment_controller.rb b/app/controllers/comment_controller.rb
index ed249d6cc..d4b17e9d2 100644
--- a/app/controllers/comment_controller.rb
+++ b/app/controllers/comment_controller.rb
@@ -2,7 +2,7 @@
# Show annotations upon a request or other object.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class CommentController < ApplicationController
before_filter :check_read_only, :only => [ :new ]
diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb
index f6a46458e..075d35ba0 100644
--- a/app/controllers/general_controller.rb
+++ b/app/controllers/general_controller.rb
@@ -3,7 +3,7 @@
# particular model.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
begin
require 'xmlsimple'
@@ -21,11 +21,11 @@ class GeneralController < ApplicationController
medium_cache
# get some example searches and public bodies to display
# either from config, or based on a (slow!) query if not set
- body_short_names = Configuration::frontpage_publicbody_examples.split(/\s*;\s*/).map{|s| "'%s'" % s.gsub(/'/, "''") }.join(", ")
+ body_short_names = AlaveteliConfiguration::frontpage_publicbody_examples.split(/\s*;\s*/).map{|s| "'%s'" % s.gsub(/'/, "''") }.join(", ")
@locale = self.locale_from_params()
locale_condition = 'public_body_translations.locale = ?'
conditions = [locale_condition, @locale]
- PublicBody.with_locale(@locale) do
+ I18n.with_locale(@locale) do
if body_short_names.empty?
# This is too slow
@popular_bodies = PublicBody.visible.find(:all,
@@ -71,7 +71,7 @@ class GeneralController < ApplicationController
def blog
medium_cache
@feed_autodetect = []
- @feed_url = Configuration::blog_feed
+ @feed_url = AlaveteliConfiguration::blog_feed
separator = @feed_url.include?('?') ? '&' : '?'
@feed_url = "#{@feed_url}#{separator}lang=#{self.locale_from_params()}"
@blog_items = []
@@ -84,7 +84,7 @@ class GeneralController < ApplicationController
@feed_autodetect = [{:url => @feed_url, :title => "#{site_name} blog"}]
end
end
- @twitter_user = Configuration::twitter_username
+ @twitter_user = AlaveteliConfiguration::twitter_username
end
# Just does a redirect from ?query= search to /query
@@ -109,7 +109,7 @@ class GeneralController < ApplicationController
def search
# XXX Why is this so complicated with arrays and stuff? Look at the route
# in config/routes.rb for comments.
- combined = params[:combined]
+ combined = params[:combined].split("/")
@sortby = nil
@bodies = @requests = @users = true
if combined.size > 0 && (['advanced'].include?(combined[-1]))
diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb
index 573abac63..9959df6d8 100644
--- a/app/controllers/help_controller.rb
+++ b/app/controllers/help_controller.rb
@@ -2,7 +2,7 @@
# Show information about one particular request.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class HelpController < ApplicationController
@@ -18,7 +18,7 @@ class HelpController < ApplicationController
end
def contact
- @contact_email = Configuration::contact_email
+ @contact_email = AlaveteliConfiguration::contact_email
# if they clicked remove for link to request/body, remove it
if params[:remove]
@@ -49,14 +49,14 @@ class HelpController < ApplicationController
end
@contact = ContactValidator.new(params[:contact])
if @contact.valid? && !params[:remove]
- ContactMailer.deliver_to_admin_message(
+ ContactMailer.to_admin_message(
params[:contact][:name],
params[:contact][:email],
params[:contact][:subject],
params[:contact][:message],
@user,
@last_request, @last_body
- )
+ ).deliver
flash[:notice] = _("Your message has been sent. Thank you for getting in touch! We'll get back to you soon.")
redirect_to frontpage_url
return
diff --git a/app/controllers/holiday_controller.rb b/app/controllers/holiday_controller.rb
index 3101c07e3..efc20701d 100644
--- a/app/controllers/holiday_controller.rb
+++ b/app/controllers/holiday_controller.rb
@@ -2,7 +2,7 @@
# Calculate dates
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class HolidayController < ApplicationController
@@ -12,7 +12,7 @@ class HolidayController < ApplicationController
def due_date
if params[:holiday]
@request_date = Date.strptime(params[:holiday]) or raise "Invalid date"
- @due_date = Holiday.due_date_from(@request_date, Configuration::reply_late_after_days, Configuration::working_or_calendar_days)
+ @due_date = Holiday.due_date_from(@request_date, AlaveteliConfiguration::reply_late_after_days, AlaveteliConfiguration::working_or_calendar_days)
@skipped = Holiday.all(
:conditions => [ 'day >= ? AND day <= ?',
@request_date.strftime("%F"), @due_date.strftime("%F")
diff --git a/app/controllers/public_body_controller.rb b/app/controllers/public_body_controller.rb
index aa6980b69..74ea043bb 100644
--- a/app/controllers/public_body_controller.rb
+++ b/app/controllers/public_body_controller.rb
@@ -3,7 +3,7 @@
# Show information about a public body.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'fastercsv'
@@ -16,7 +16,7 @@ class PublicBodyController < ApplicationController
return
end
@locale = self.locale_from_params()
- PublicBody.with_locale(@locale) do
+ I18n.with_locale(@locale) do
@public_body = PublicBody.find_by_url_name_with_historic(params[:url_name])
raise ActiveRecord::RecordNotFound.new("None found") if @public_body.nil?
if @public_body.url_name.nil?
@@ -69,7 +69,7 @@ class PublicBodyController < ApplicationController
@public_body = PublicBody.find_by_url_name_with_historic(params[:url_name])
raise ActiveRecord::RecordNotFound.new("None found") if @public_body.nil?
- PublicBody.with_locale(self.locale_from_params()) do
+ I18n.with_locale(self.locale_from_params()) do
if params[:submitted_view_email]
if verify_recaptcha
flash.discard(:error)
@@ -127,11 +127,9 @@ class PublicBodyController < ApplicationController
@description = _("in the category ‘{{category_name}}’", :category_name=>category_name)
end
end
- PublicBody.with_locale(@locale) do
- @public_bodies = PublicBody.paginate(
- :order => "public_body_translations.name", :page => params[:page], :per_page => 100,
- :conditions => conditions,
- :joins => :translations
+ I18n.with_locale(@locale) do
+ @public_bodies = PublicBody.where(conditions).joins(:translations).order("public_body_translations.name").paginate(
+ :page => params[:page], :per_page => 100
)
render :template => "public_body/list"
end
diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb
index ec5c9d055..ea84d3b10 100644
--- a/app/controllers/request_controller.rb
+++ b/app/controllers/request_controller.rb
@@ -2,7 +2,7 @@
# Show information about one particular request.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'alaveteli_file_types'
require 'zip/zip'
@@ -17,7 +17,7 @@ class RequestController < ApplicationController
@@custom_states_loaded = false
begin
- if ENV["RAILS_ENV"] != "test"
+ if !Rails.env.test?
require 'customstates'
include RequestControllerCustomStates
@@custom_states_loaded = true
@@ -28,7 +28,7 @@ class RequestController < ApplicationController
def select_authority
# Check whether we force the user to sign in right at the start, or we allow her
# to start filling the request anonymously
- if Configuration::force_registration_on_new_request && !authenticated?(
+ if AlaveteliConfiguration::force_registration_on_new_request && !authenticated?(
:web => _("To send your FOI request"),
:email => _("Then you'll be allowed to send FOI requests."),
:email_subject => _("Confirm your email address")
@@ -44,7 +44,7 @@ class RequestController < ApplicationController
end
def show
- if !Configuration::varnish_host.blank?
+ if !AlaveteliConfiguration::varnish_host.blank?
# If varnish is set up to accept PURGEs, then cache for a
# long time
long_cache
@@ -52,7 +52,7 @@ class RequestController < ApplicationController
medium_cache
end
@locale = self.locale_from_params()
- PublicBody.with_locale(@locale) do
+ I18n.with_locale(@locale) do
# Look up by old style numeric identifiers
if params[:url_title].match(/^[0-9]+$/)
@@ -242,16 +242,19 @@ class RequestController < ApplicationController
# Read parameters in - first the public body (by URL name or id)
if params[:url_name]
if params[:url_name].match(/^[0-9]+$/)
- params[:info_request][:public_body_id] = params[:url_name]
+ params[:info_request][:public_body] = PublicBody.find(params[:url_name])
else
public_body = PublicBody.find_by_url_name_with_historic(params[:url_name])
raise ActiveRecord::RecordNotFound.new("None found") if public_body.nil? # XXX proper 404
- params[:info_request][:public_body_id] = public_body.id
+ params[:info_request][:public_body] = public_body
end
elsif params[:public_body_id]
- params[:info_request][:public_body_id] = params[:public_body_id]
+ params[:info_request][:public_body] = PublicBody.find(params[:public_body_id])
+ # Explicitly load the association as this isn't done automatically in newer Rails versions
+ elsif params[:info_request][:public_body_id]
+ params[:info_request][:public_body] = PublicBody.find(params[:info_request][:public_body_id])
end
- if !params[:info_request][:public_body_id]
+ if !params[:info_request][:public_body]
# compulsory to have a body by here, or go to front page which is start of process
redirect_to frontpage_url
return
@@ -344,7 +347,7 @@ class RequestController < ApplicationController
end
if !authenticated?(
- :web => _("To send your FOI request"),
+ :web => _("To send your FOI request").to_str,
:email => _("Then your FOI request to {{public_body_name}} will be sent.",:public_body_name=>@info_request.public_body.name),
:email_subject => _("Confirm your FOI request to ") + @info_request.public_body.name
)
@@ -368,8 +371,8 @@ class RequestController < ApplicationController
replied by then.</p>
<p>If you write about this request (for example in a forum or a blog) please link to this page, and add an
annotation below telling people about your writing.</p>",:law_used_full=>@info_request.law_used_full,
- :late_number_of_days => Configuration::reply_late_after_days)
- redirect_to show_new_request_url(:url_title => @info_request.url_title)
+ :late_number_of_days => AlaveteliConfiguration::reply_late_after_days)
+ redirect_to show_new_request_path(:url_title => @info_request.url_title)
end
# Submitted to the describing state of messages form
@@ -434,6 +437,7 @@ class RequestController < ApplicationController
return
end
+ calculated_status = info_request.calculate_status
# Display advice for requester on what to do next, as appropriate
flash[:notice] = case info_request.calculate_status
when 'waiting_response'
@@ -442,7 +446,7 @@ class RequestController < ApplicationController
when 'waiting_response_overdue'
_("<p>Thank you! Hope you don't have to wait much longer.</p> <p>By law, you should have got a response promptly, and normally before the end of <strong>{{date_response_required_by}}</strong>.</p>",:date_response_required_by=>simple_date(info_request.date_response_required_by))
when 'waiting_response_very_overdue'
- _("<p>Thank you! Your request is long overdue, by more than {{very_late_number_of_days}} working days. Most requests should be answered within {{late_number_of_days}} working days. You might like to complain about this, see below.</p>", :very_late_number_of_days => Configuration::reply_very_late_after_days, :late_number_of_days => Configuration::reply_late_after_days)
+ _("<p>Thank you! Your request is long overdue, by more than {{very_late_number_of_days}} working days. Most requests should be answered within {{late_number_of_days}} working days. You might like to complain about this, see below.</p>", :very_late_number_of_days => AlaveteliConfiguration::reply_very_late_after_days, :late_number_of_days => AlaveteliConfiguration::reply_late_after_days)
when 'not_held'
_("<p>Thank you! Here are some ideas on what to do next:</p>
<ul>
@@ -468,7 +472,7 @@ class RequestController < ApplicationController
when 'gone_postal'
nil
when 'internal_review'
- _("<p>Thank you! Hopefully your wait isn't too long.</p><p>You should get a response within {{late_number_of_days}} days, or be told if it will take longer (<a href=\"{{review_url}}\">details</a>).</p>",:late_number_of_days => Configuration.reply_late_after_days, :review_url => unhappy_url(info_request) + "#internal_review")
+ _("<p>Thank you! Hopefully your wait isn't too long.</p><p>You should get a response within {{late_number_of_days}} days, or be told if it will take longer (<a href=\"{{review_url}}\">details</a>).</p>",:late_number_of_days => AlaveteliConfiguration.reply_late_after_days, :review_url => unhappy_url(info_request) + "#internal_review")
when 'error_message', 'requires_admin'
_("Thank you! We'll look into what happened and try and fix it up.")
when 'user_withdrawn'
@@ -560,10 +564,7 @@ class RequestController < ApplicationController
end
- params_outgoing_message = params[:outgoing_message]
- if params_outgoing_message.nil?
- params_outgoing_message = {}
- end
+ params_outgoing_message = params[:outgoing_message] ? params[:outgoing_message].clone : {}
params_outgoing_message.merge!({
:status => 'ready',
:message_type => 'followup',
@@ -708,10 +709,13 @@ class RequestController < ApplicationController
key_path = foi_fragment_cache_path(key)
if foi_fragment_cache_exists?(key_path)
logger.info("Reading cache for #{key_path}")
- raise PermissionDenied.new("Directory listing not allowed") if File.directory?(key_path)
- cached = foi_fragment_cache_read(key_path)
- response.content_type = AlaveteliFileTypes.filename_to_mimetype(params[:file_name].join("/")) || 'application/octet-stream'
- render_for_text(cached)
+
+ if File.directory?(key_path)
+ render :text => "Directory listing not allowed", :status => 403
+ else
+ render :text => foi_fragment_cache_read(key_path),
+ :content_type => (AlaveteliFileTypes.filename_to_mimetype(params[:file_name]) || 'application/octet-stream')
+ end
return
end
@@ -738,7 +742,7 @@ class RequestController < ApplicationController
@incoming_message.binary_mask_stuff!(@attachment.body, @attachment.content_type)
# we don't use @attachment.content_type here, as we want same mime type when cached in cache_attachments above
- response.content_type = AlaveteliFileTypes.filename_to_mimetype(params[:file_name].join("/")) || 'application/octet-stream'
+ response.content_type = AlaveteliFileTypes.filename_to_mimetype(params[:file_name]) || 'application/octet-stream'
render :text => @attachment.body
end
@@ -788,7 +792,7 @@ class RequestController < ApplicationController
raise ActiveRecord::RecordNotFound.new(message)
end
@part_number = params[:part].to_i
- @filename = params[:file_name].join("/")
+ @filename = params[:file_name]
if html_conversion
@original_filename = @filename.gsub(/\.html$/, "")
else
@@ -811,7 +815,7 @@ class RequestController < ApplicationController
# FOI officers can upload a response
def upload_response
@locale = self.locale_from_params()
- PublicBody.with_locale(@locale) do
+ I18n.with_locale(@locale) do
@info_request = InfoRequest.find_by_url_title!(params[:url_title])
@reason_params = {
@@ -849,7 +853,8 @@ class RequestController < ApplicationController
return
end
- mail = RequestMailer.create_fake_response(@info_request, @user, body, file_name, file_content)
+ mail = RequestMailer.fake_response(@info_request, @user, body, file_name, file_content)
+
@info_request.receive(mail, mail.encoded, true)
flash[:notice] = _("Thank you for responding to this FOI request! Your response has been published below, and a link to your response has been emailed to ") + CGI.escapeHTML(@info_request.user.name) + "."
redirect_to request_url(@info_request)
@@ -863,12 +868,12 @@ class RequestController < ApplicationController
# by making the last work a wildcard, which is quite the same
query = params[:q]
@xapian_requests = perform_search_typeahead(query, InfoRequestEvent)
- render :partial => "request/search_ahead.rhtml"
+ render :partial => "request/search_ahead"
end
def download_entire_request
@locale = self.locale_from_params()
- PublicBody.with_locale(@locale) do
+ I18n.with_locale(@locale) do
@info_request = InfoRequest.find_by_url_title!(params[:url_title])
# Test for whole request being hidden or requester-only
if !@info_request.all_can_view?
@@ -891,10 +896,10 @@ class RequestController < ApplicationController
if !File.exists?(file_path)
FileUtils.mkdir_p(File.dirname(file_path))
Zip::ZipFile.open(file_path, Zip::ZipFile::CREATE) { |zipfile|
- convert_command = Configuration::html_to_pdf_command
+ convert_command = AlaveteliConfiguration::html_to_pdf_command
done = false
if !convert_command.blank? && File.exists?(convert_command)
- url = "http://#{Configuration::domain}#{request_path(@info_request)}?print_stylesheet=1"
+ url = "http://#{AlaveteliConfiguration::domain}#{request_path(@info_request)}?print_stylesheet=1"
tempfile = Tempfile.new('foihtml2pdf')
output = AlaveteliExternalCommand.run(convert_command, url, tempfile.path)
if !output.nil?
@@ -911,7 +916,7 @@ class RequestController < ApplicationController
end
if !done
@info_request_events = @info_request.info_request_events
- template = File.read(File.join(File.dirname(__FILE__), "..", "views", "request", "simple_correspondence.rhtml"))
+ template = File.read(File.join(File.dirname(__FILE__), "..", "views", "request", "simple_correspondence.html.erb"))
output = ERB.new(template).result(binding)
zipfile.get_output_stream("correspondence.txt") { |f|
f.puts(output)
diff --git a/app/controllers/request_game_controller.rb b/app/controllers/request_game_controller.rb
index 4b6f02970..6eac399ac 100644
--- a/app/controllers/request_game_controller.rb
+++ b/app/controllers/request_game_controller.rb
@@ -2,7 +2,7 @@
# The 'categorise old requests' game
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class RequestGameController < ApplicationController
diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb
index e75dac903..11ed4ac8f 100644
--- a/app/controllers/services_controller.rb
+++ b/app/controllers/services_controller.rb
@@ -6,7 +6,7 @@ class ServicesController < ApplicationController
def other_country_message
text = ""
- iso_country_code = Configuration::iso_country_code.downcase
+ iso_country_code = AlaveteliConfiguration::iso_country_code.downcase
if country_from_ip.downcase != iso_country_code
found_country = WorldFOIWebsites.by_code(country_from_ip)
@@ -36,9 +36,9 @@ class ServicesController < ApplicationController
:content_type => "text/plain",
:layout => false,
:locals => {:name_to => info_request.user_name,
- :name_from => Configuration::contact_name,
+ :name_from => AlaveteliConfiguration::contact_name,
:info_request => info_request, :reason => params[:reason],
- :info_request_url => 'http://' + Configuration::domain + request_path(info_request),
+ :info_request_url => 'http://' + AlaveteliConfiguration::domain + request_path(info_request),
:site_name => site_name}
end
diff --git a/app/controllers/track_controller.rb b/app/controllers/track_controller.rb
index 15da7f327..9076148c4 100644
--- a/app/controllers/track_controller.rb
+++ b/app/controllers/track_controller.rb
@@ -3,7 +3,7 @@
# social bookmarking.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class TrackController < ApplicationController
@@ -80,10 +80,7 @@ class TrackController < ApplicationController
# Track a search term
def track_search_query
- # XXX should be better thing in rails routes than having to do this
- # join just to get / and . to work in a query.
- query_array = params[:query_array]
- @query = query_array.join("/")
+ @query = params[:query_array]
# XXX more hackery to make alternate formats still work with query_array
if /^(.*)\.json$/.match(@query)
@@ -157,10 +154,10 @@ class TrackController < ApplicationController
def atom_feed_internal
@xapian_object = perform_search([InfoRequestEvent], @track_thing.track_query, @track_thing.params[:feed_sortby], nil, 25, 1)
respond_to do |format|
- format.atom { render :template => 'track/atom_feed', :content_type => "application/atom+xml" }
format.json { render :json => @xapian_object.results.map { |r| r[:model].json_for_api(true,
- lambda { |t| @template.highlight_and_excerpt(t, @xapian_object.words_to_highlight, 150) }
+ lambda { |t| view_context.highlight_and_excerpt(t, @xapian_object.words_to_highlight, 150) }
) } }
+ format.any { render :template => 'track/atom_feed.atom', :layout => false, :content_type => :atom }
end
end
diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb
index fc8b6e014..dca3cda17 100644
--- a/app/controllers/user_controller.rb
+++ b/app/controllers/user_controller.rb
@@ -2,7 +2,7 @@
# Show information about a user.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'set'
@@ -136,7 +136,7 @@ class UserController < ApplicationController
# Login form
def signin
work_out_post_redirect
- @request_from_foreign_country = country_from_ip != Configuration::iso_country_code
+ @request_from_foreign_country = country_from_ip != AlaveteliConfiguration::iso_country_code
# make sure we have cookies
if session.instance_variable_get(:@dbman)
if not session.instance_variable_get(:@dbman).instance_variable_get(:@original)
@@ -190,7 +190,7 @@ class UserController < ApplicationController
# Create new account form
def signup
work_out_post_redirect
- @request_from_foreign_country = country_from_ip != Configuration::iso_country_code
+ @request_from_foreign_country = country_from_ip != AlaveteliConfiguration::iso_country_code
# Make the user and try to save it
@user_signup = User.new(params[:user_signup])
error = false
@@ -222,7 +222,7 @@ class UserController < ApplicationController
post_redirect = PostRedirect.find_by_email_token(params[:email_token])
if post_redirect.nil?
- render :template => 'user/bad_token.rhtml'
+ render :template => 'user/bad_token'
return
end
@@ -288,7 +288,7 @@ class UserController < ApplicationController
post_redirect.user = user_signchangepassword
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
- UserMailer.deliver_confirm_login(user_signchangepassword, post_redirect.reason_params, url)
+ UserMailer.confirm_login(user_signchangepassword, post_redirect.reason_params, url).deliver
else
# User not found, but still show confirm page to not leak fact user exists
end
@@ -352,7 +352,7 @@ class UserController < ApplicationController
# if new email already in use, send email there saying what happened
user_alreadyexists = User.find_user_by_email(@signchangeemail.new_email)
if user_alreadyexists
- UserMailer.deliver_changeemail_already_used(@user.email, @signchangeemail.new_email)
+ UserMailer.changeemail_already_used(@user.email, @signchangeemail.new_email).deliver
# it is important this screen looks the same as the one below, so
# you can't change to someone's email in order to tell if they are
# registered with that email on the site
@@ -373,7 +373,7 @@ class UserController < ApplicationController
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
- UserMailer.deliver_changeemail_confirm(@user, @signchangeemail.new_email, url)
+ UserMailer.changeemail_confirm(@user, @signchangeemail.new_email, url).deliver
# it is important this screen looks the same as the one above, so
# you can't change to someone's email in order to tell if they are
# registered with that email on the site
@@ -419,13 +419,13 @@ class UserController < ApplicationController
params[:contact][:email] = @user.email
@contact = ContactValidator.new(params[:contact])
if @contact.valid?
- ContactMailer.deliver_user_message(
+ ContactMailer.user_message(
@user,
@recipient_user,
user_url(@user),
params[:contact][:subject],
params[:contact][:message]
- )
+ ).deliver
flash[:notice] = _("Your message to {{recipient_user_name}} has been sent!",:recipient_user_name=>CGI.escapeHTML(@recipient_user.name))
redirect_to user_url(@recipient_user)
return
@@ -465,7 +465,7 @@ class UserController < ApplicationController
@draft_profile_photo = ProfilePhoto.new(:data => file_content, :draft => true)
if !@draft_profile_photo.valid?
# error page (uses @profile_photo's error fields in view to show errors)
- render :template => 'user/set_draft_profile_photo.rhtml'
+ render :template => 'user/set_draft_profile_photo'
return
end
@draft_profile_photo.save
@@ -480,7 +480,7 @@ class UserController < ApplicationController
return
end
- render :template => 'user/set_crop_profile_photo.rhtml'
+ render :template => 'user/set_crop_profile_photo'
return
elsif !params[:submitted_crop_profile_photo].nil?
# crop the draft photo according to jquery parameters and set it as the users photo
@@ -499,7 +499,7 @@ class UserController < ApplicationController
redirect_to set_profile_about_me_url()
end
else
- render :template => 'user/set_draft_profile_photo.rhtml'
+ render :template => 'user/set_draft_profile_photo'
end
end
@@ -631,7 +631,7 @@ class UserController < ApplicationController
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
- UserMailer.deliver_confirm_login(user, post_redirect.reason_params, url)
+ UserMailer.confirm_login(user, post_redirect.reason_params, url).deliver
render :action => 'confirm'
end
@@ -642,7 +642,7 @@ class UserController < ApplicationController
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
- UserMailer.deliver_already_registered(user, post_redirect.reason_params, url)
+ UserMailer.already_registered(user, post_redirect.reason_params, url).deliver
render :action => 'confirm' # must be same as for send_confirmation_mail above to avoid leak of presence of email in db
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 42f9d30f1..e3b1e57ac 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -3,7 +3,7 @@
# in the application.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'languages'
diff --git a/app/helpers/config_helper.rb b/app/helpers/config_helper.rb
index 73e12172f..026600ff1 100644
--- a/app/helpers/config_helper.rb
+++ b/app/helpers/config_helper.rb
@@ -1,5 +1,5 @@
module ConfigHelper
def site_name
- Configuration::site_name
+ AlaveteliConfiguration::site_name
end
-end \ No newline at end of file
+end
diff --git a/app/helpers/link_to_helper.rb b/app/helpers/link_to_helper.rb
index 3f59c55ca..238a36ce4 100755
--- a/app/helpers/link_to_helper.rb
+++ b/app/helpers/link_to_helper.rb
@@ -3,7 +3,7 @@
# -
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
module LinkToHelper
@@ -218,6 +218,9 @@ module LinkToHelper
return url
end
+ def search_link(query, variety_postfix = nil, sort_postfix = nil, advanced = nil)
+ link_to h(query), search_url(query)
+ end
def search_path(query, options = {})
search_url(query, options.merge(:only_path => true))
@@ -238,7 +241,7 @@ module LinkToHelper
# TODO: Remove in next release
def main_url(relative_path, append = nil)
warn "[DEPRECATION] main_url is deprecated. Please remove it from your theme."
- url_prefix = "http://" + Configuration::domain
+ url_prefix = "http://" + AlaveteliConfiguration::domain
url = url_prefix + relative_path
if !append.nil?
begin
@@ -282,5 +285,13 @@ module LinkToHelper
def year_from_date(date)
return date.strftime("%Y").strip
end
+
+ #I18n locale switcher
+
+ def locale_switcher(locale, params)
+ params['locale'] = locale
+ return url_for(params)
+ end
+
end
diff --git a/app/helpers/mailer_helper.rb b/app/helpers/mailer_helper.rb
index be2ce47aa..3d4bbac71 100644
--- a/app/helpers/mailer_helper.rb
+++ b/app/helpers/mailer_helper.rb
@@ -1,5 +1,5 @@
module MailerHelper
def contact_from_name_and_email
- "#{Configuration::contact_name} <#{Configuration::contact_email}>"
+ "#{AlaveteliConfiguration::contact_name} <#{AlaveteliConfiguration::contact_email}>"
end
end
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
new file mode 100644
index 000000000..a5f27c068
--- /dev/null
+++ b/app/mailers/application_mailer.rb
@@ -0,0 +1,62 @@
+# models/application_mailer.rb:
+# Shared code between different mailers.
+#
+# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
+
+require 'action_mailer/version'
+class ApplicationMailer < ActionMailer::Base
+ # Include all the functions views get, as emails call similar things.
+ helper :application
+ include MailerHelper
+
+ # This really should be the default - otherwise you lose any information
+ # about the errors, and have to do error checking on return codes.
+ self.raise_delivery_errors = true
+
+ def blackhole_email
+ AlaveteliConfiguration::blackhole_prefix+"@"+AlaveteliConfiguration::incoming_email_domain
+ end
+
+ # URL generating functions are needed by all controllers (for redirects),
+ # views (for links) and mailers (for use in emails), so include them into
+ # all of all.
+ include LinkToHelper
+
+ # Site-wide access to configuration settings
+ include ConfigHelper
+
+ # For each multipart template (e.g. "the_template_file.text.html.erb") available,
+ # add the one from the view path with the highest priority as a part to the mail
+ def render_multipart_templates
+ added_content_types = {}
+ self.view_paths.each do |view_path|
+ Dir.glob("#{view_path}/#{mailer_name}/#{@template}.*").each do |path|
+ template = view_path["#{mailer_name}/#{File.basename(path)}"]
+
+ # Skip unless template has a multipart format
+ next unless template && template.multipart?
+ next if added_content_types[template.content_type] == true
+ @parts << Part.new(
+ :content_type => template.content_type,
+ :disposition => "inline",
+ :charset => charset,
+ :body => render_message(template, @body)
+ )
+ added_content_types[template.content_type] = true
+ end
+ end
+ end
+
+ # Look for the current template in each element of view_paths in order,
+ # return the first
+ def find_template
+ self.view_paths.each do |view_path|
+ if template = view_path["#{mailer_name}/#{@template}"]
+ return template
+ end
+ end
+ return nil
+ end
+end
+
diff --git a/app/mailers/contact_mailer.rb b/app/mailers/contact_mailer.rb
new file mode 100644
index 000000000..4dc49bf8b
--- /dev/null
+++ b/app/mailers/contact_mailer.rb
@@ -0,0 +1,45 @@
+# models/contact_mailer.rb:
+# Sends contact form mails.
+#
+# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
+
+class ContactMailer < ApplicationMailer
+ # Send message to administrator
+ def to_admin_message(name, email, subject, message, logged_in_user, last_request, last_body)
+ @message, @logged_in_user, @last_request, @last_body = message, logged_in_user, last_request, last_body
+
+ mail(:from => "#{name} <#{email}>",
+ :to => contact_from_name_and_email,
+ :subject => subject)
+ end
+
+ # We always set Reply-To when we set Return-Path to be different from From,
+ # since some email clients seem to erroneously use the envelope from when
+ # they shouldn't, and this might help. (Have had mysterious cases of a
+ # reply coming in duplicate from a public body to both From and envelope
+ # from)
+
+ # Send message to another user
+ def user_message(from_user, recipient_user, from_user_url, subject, message)
+ @message, @from_user, @recipient_user, @from_user_url = message, from_user, recipient_user, from_user_url
+
+ # Do not set envelope from address to the from_user, so they can't get
+ # someone's email addresses from transitory bounce messages.
+ headers('Return-Path' => blackhole_email, 'Reply-To' => from_user.name_and_email)
+
+ mail(:from => from_user.name_and_email,
+ :to => recipient_user.name_and_email,
+ :subject => subject)
+ end
+
+ # Send message to a user from the administrator
+ def from_admin_message(recipient_user, subject, message)
+ @message, @from_user, @recipient_user = message, contact_from_name_and_email, recipient_user
+
+ mail(:from => contact_from_name_and_email,
+ :to => recipient_user.name_and_email,
+ :bcc => AlaveteliConfiguration::contact_email,
+ :subject => subject)
+ end
+end
diff --git a/app/models/outgoing_mailer.rb b/app/mailers/outgoing_mailer.rb
index 503166b8a..083c05a7c 100644
--- a/app/models/outgoing_mailer.rb
+++ b/app/mailers/outgoing_mailer.rb
@@ -2,7 +2,7 @@
# Emails which go to public bodies on behalf of users.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
# Note: The layout for this wraps messages by lines rather than (blank line
# separated) paragraphs, as is the convention for all the other mailers. This
@@ -13,31 +13,29 @@
# throughout the application.
class OutgoingMailer < ApplicationMailer
-
# Email to public body requesting info
def initial_request(info_request, outgoing_message)
+ @info_request, @outgoing_message, @contact_email = info_request, outgoing_message, AlaveteliConfiguration::contact_email
@wrap_lines_as_paragraphs = true
- @from = info_request.incoming_name_and_email
- @recipients = info_request.recipient_name_and_email
- @subject = info_request.email_subject_request
- @headers["message-id"] = OutgoingMailer.id_for_message(outgoing_message)
- @body = {:info_request => info_request, :outgoing_message => outgoing_message,
- :contact_email => Configuration::contact_email }
+ headers["message-id"] = OutgoingMailer.id_for_message(outgoing_message)
+
+ mail(:from => info_request.incoming_name_and_email,
+ :to => info_request.recipient_name_and_email,
+ :subject => info_request.email_subject_request)
end
# Later message to public body regarding existing request
def followup(info_request, outgoing_message, incoming_message_followup)
+ @info_request, @outgoing_message, @incoming_message_followup, @contact_email = info_request, outgoing_message, incoming_message_followup, AlaveteliConfiguration::contact_email
@wrap_lines_as_paragraphs = true
- @from = info_request.incoming_name_and_email
- @recipients = OutgoingMailer.name_and_email_for_followup(info_request, incoming_message_followup)
- @subject = OutgoingMailer.subject_for_followup(info_request, outgoing_message)
- @headers["message-id"] = OutgoingMailer.id_for_message(outgoing_message)
- @body = {:info_request => info_request, :outgoing_message => outgoing_message,
- :incoming_message_followup => incoming_message_followup,
- :contact_email => Configuration::contact_email }
+ headers["message-id"] = OutgoingMailer.id_for_message(outgoing_message)
+
+ mail(:from => info_request.incoming_name_and_email,
+ :to => OutgoingMailer.name_and_email_for_followup(info_request, incoming_message_followup),
+ :subject => OutgoingMailer.subject_for_followup(info_request, outgoing_message))
end
- # XXX the condition checking valid_to_reply_to? also appears in views/request/_followup.rhtml,
+ # XXX the condition checking valid_to_reply_to? also appears in views/request/_followup.html.erb,
# it shouldn't really, should call something here.
# XXX also OutgoingMessage.get_salutation
# XXX these look like they should be members of IncomingMessage, but logically they
@@ -90,7 +88,7 @@ class OutgoingMailer < ApplicationMailer
message_id = "ogm-" + outgoing_message.id.to_s
t = Time.now
message_id += "+" + '%08x%05x-%04x' % [t.to_i, t.tv_usec, rand(0xffff)]
- message_id += "@" + Configuration::incoming_email_domain
+ message_id += "@" + AlaveteliConfiguration::incoming_email_domain
return "<" + message_id + ">"
end
diff --git a/app/models/request_mailer.rb b/app/mailers/request_mailer.rb
index 955f73ef4..3eb89c660 100644
--- a/app/models/request_mailer.rb
+++ b/app/mailers/request_mailer.rb
@@ -2,89 +2,89 @@
# Alerts relating to requests.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'alaveteli_file_types'
-if Rails.env == 'test' && RUBY_VERSION.to_f >= 1.9
- # Avoid spec/script/mailin_spec.rb running script/runner as a test suite
- # http://stackoverflow.com/questions/1899009/why-are-tests-running-in-production-mode-and-causing-my-script-runners-to-fail
- Test::Unit.run = true
-end
-class RequestMailer < ApplicationMailer
-
+class RequestMailer < ApplicationMailer
# Used when an FOI officer uploads a response from their web browser - this is
# the "fake" email used to store in the same format in the database as if they
# had emailed it.
- def fake_response(info_request, from_user, body, attachment_name, attachment_content)
- @from = from_user.name_and_email
- @recipients = info_request.incoming_name_and_email
- @body = {
- :body => body
- }
+ def fake_response(info_request, from_user, message_body, attachment_name, attachment_content)
+ @message_body = message_body
+
if !attachment_name.nil? && !attachment_content.nil?
content_type = AlaveteliFileTypes.filename_to_mimetype(attachment_name) || 'application/octet-stream'
- attachment :content_type => content_type,
- :body => attachment_content,
- :filename => attachment_name
+ attachments[attachment_name] = {:content => attachment_content,
+ :content_type => content_type}
end
+
+ mail(:from => from_user.name_and_email,
+ :to => info_request.incoming_name_and_email)
end
# Used when a response is uploaded using the API
- def external_response(info_request, body, sent_at, attachments)
- @from = blackhole_email
- @recipients = info_request.incoming_name_and_email
- @body = { :body => body }
-
- # ActionMailer only works properly when the time is in the local timezone:
- # see https://rails.lighthouseapp.com/projects/8994/tickets/3113-actionmailer-only-works-correctly-with-sent_on-times-that-are-in-the-local-time-zone
- @sent_on = sent_at.dup.localtime
+ def external_response(info_request, message_body, sent_at, attachment_hashes)
+ @message_body = message_body
- attachments.each do |attachment_hash|
- attachment attachment_hash
+ attachment_hashes.each do |attachment_hash|
+ attachments[attachment_hash[:filename]] = {:content => attachment_hash[:body],
+ :content_type => attachment_hash[:content_type]}
end
+
+ mail(:from => blackhole_email,
+ :to => info_request.incoming_name_and_email,
+ :date => sent_at)
end
# Incoming message arrived for a request, but new responses have been stopped.
def stopped_responses(info_request, email, raw_email_data)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # we don't care about bounces, likely from spammers
- 'Auto-Submitted' => 'auto-replied' # http://tools.ietf.org/html/rfc3834
- @recipients = email.from_addrs[0].to_s
- @subject = _("Your response to an FOI request was not delivered")
- attachment :content_type => 'message/rfc822', :body => raw_email_data,
- :filename => "original.eml", :transfer_encoding => '7bit', :content_disposition => 'inline'
- @body = {
- :info_request => info_request,
- :contact_email => Configuration::contact_email
- }
+ headers('Return-Path' => blackhole_email, # we don't care about bounces, likely from spammers
+ 'Auto-Submitted' => 'auto-replied') # http://tools.ietf.org/html/rfc3834
+
+ attachments.inline["original.eml"] = raw_email_data
+
+ @info_request = info_request
+ @contact_email = AlaveteliConfiguration::contact_email
+
+ mail(:to => email.from_addrs[0].to_s,
+ :from => contact_from_name_and_email,
+ :reply_to => contact_from_name_and_email,
+ :subject => _("Your response to an FOI request was not delivered"))
end
# An FOI response is outside the scope of the system, and needs admin attention
def requires_admin(info_request, set_by = nil, message = "")
user = set_by || info_request.user
- @from = user.name_and_email
- @recipients = contact_from_name_and_email
- @subject = _("FOI response requires admin ({{reason}}) - {{title}}", :reason => info_request.described_state, :title => info_request.title)
- url = request_url(info_request)
- admin_url = admin_request_show_url(info_request)
- @body = {:reported_by => user, :message => message, :info_request => info_request, :url => url, :admin_url => admin_url }
+ @reported_by = user
+ @url = request_url(info_request)
+ @admin_url = admin_request_show_url(info_request)
+ @info_request = info_request
+ @message = message
+
+ mail(:from => user.name_and_email,
+ :to => contact_from_name_and_email,
+ :subject => _("FOI response requires admin ({{reason}}) - {{title}}", :reason => info_request.described_state, :title => info_request.title))
end
# Tell the requester that a new response has arrived
def new_response(info_request, incoming_message)
# Don't use login link here, just send actual URL. This is
# because people tend to forward these emails amongst themselves.
- url = incoming_message_url(incoming_message)
+ @url = incoming_message_url(incoming_message)
+ @incoming_message, @info_request = incoming_message, info_request
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ headers('Return-Path' => blackhole_email,
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = (_("New response to your FOI request - ") + info_request.title).html_safe
- @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => _("New response to your FOI request - ") + info_request.title,
+ :charset => "UTF-8",
+ # not much we can do if the user's email is broken
+ :reply_to => contact_from_name_and_email)
end
# Tell the requester that the public body is late in replying
@@ -92,18 +92,21 @@ class RequestMailer < ApplicationMailer
respond_url = respond_to_last_url(info_request) + "#followup"
post_redirect = PostRedirect.new(
- :uri => respond_url,
+ :uri => respond_to_last_url(info_request) + "#followup",
:user_id => user.id)
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ @url = confirm_url(:email_token => post_redirect.email_token)
+ @info_request = info_request
+
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = user.name_and_email
- @subject = (_("Delayed response to your FOI request - ") + info_request.title).html_safe
- @body = { :info_request => info_request, :url => url }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => user.name_and_email,
+ :subject => (_("Delayed response to your FOI request - ") + info_request.title).html_safe)
end
# Tell the requester that the public body is very late in replying
@@ -111,18 +114,19 @@ class RequestMailer < ApplicationMailer
respond_url = respond_to_last_url(info_request) + "#followup"
post_redirect = PostRedirect.new(
- :uri => respond_url,
+ :uri => respond_to_last_url(info_request) + "#followup",
:user_id => user.id)
post_redirect.save!
- url = confirm_url(:email_token => post_redirect.email_token)
+ @url = confirm_url(:email_token => post_redirect.email_token)
+ @info_request = info_request
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = user.name_and_email
- @subject = (_("You're long overdue a response to your FOI request - ") + info_request.title).html_safe
- @body = { :info_request => info_request, :url => url }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => user.name_and_email,
+ :subject => (_("You're long overdue a response to your FOI request - ") + info_request.title).html_safe)
end
# Tell the requester that they need to say if the new response
@@ -134,27 +138,31 @@ class RequestMailer < ApplicationMailer
:uri => request_url(info_request) + "#describe_state_form_1",
:user_id => info_request.user.id)
post_redirect.save!
- url = confirm_url(:email_token => post_redirect.email_token)
+ @url = confirm_url(:email_token => post_redirect.email_token)
+ @incoming_message = incoming_message
+ @info_request = info_request
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = _("Was the response you got to your FOI request any good?")
- @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => _("Was the response you got to your FOI request any good?"))
end
# Tell the requester that someone updated their old unclassified request
def old_unclassified_updated(info_request)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ @url = request_url(info_request)
+ @info_request = info_request
+
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = _("Someone has updated the status of your request")
- url = request_url(info_request)
- @body = {:info_request => info_request, :url => url}
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => _("Someone has updated the status of your request"))
end
# Tell the requester that they need to clarify their request
@@ -166,35 +174,43 @@ class RequestMailer < ApplicationMailer
:uri => respond_url,
:user_id => info_request.user.id)
post_redirect.save!
- url = confirm_url(:email_token => post_redirect.email_token)
+ @url = confirm_url(:email_token => post_redirect.email_token)
+ @incoming_message = incoming_message
+ @info_request = info_request
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = (_("Clarify your FOI request - ") + info_request.title).html_safe
- @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => _("Clarify your FOI request - ") + info_request.title)
end
# Tell requester that somebody add an annotation to their request
def comment_on_alert(info_request, comment)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ @comment, @info_request = comment, info_request
+ @url = comment_url(comment)
+
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = (_("Somebody added a note to your FOI request - ") + info_request.title).html_safe
- @body = { :comment => comment, :info_request => info_request, :url => comment_url(comment) }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => (_("Somebody added a note to your FOI request - ") + info_request.title).html_safe)
end
def comment_on_alert_plural(info_request, count, earliest_unalerted_comment)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
+ @count, @info_request = count, info_request
+ @url = comment_url(earliest_unalerted_comment)
+
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email, # not much we can do if the user's email is broken
'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'X-Auto-Response-Suppress' => 'OOF'
- @recipients = info_request.user.name_and_email
- @subject = (_("Some notes have been added to your FOI request - ") + info_request.title).html_safe
- @body = { :count => count, :info_request => info_request, :url => comment_url(earliest_unalerted_comment) }
+ 'X-Auto-Response-Suppress' => 'OOF')
+
+ mail(:from => contact_from_name_and_email,
+ :to => info_request.user.name_and_email,
+ :subject => (_("Some notes have been added to your FOI request - ") + info_request.title).html_safe)
end
# Class function, called by script/mailin with all incoming responses.
@@ -307,9 +323,9 @@ class RequestMailer < ApplicationMailer
# (otherwise they are banned, and there is no point sending it)
if info_request.user.can_make_followup?
if calculated_status == 'waiting_response_overdue'
- RequestMailer.deliver_overdue_alert(info_request, info_request.user)
+ RequestMailer.overdue_alert(info_request, info_request.user).deliver
elsif calculated_status == 'waiting_response_very_overdue'
- RequestMailer.deliver_very_overdue_alert(info_request, info_request.user)
+ RequestMailer.very_overdue_alert(info_request, info_request.user).deliver
else
raise "unknown request status"
end
@@ -323,7 +339,7 @@ class RequestMailer < ApplicationMailer
# Send email alerts for new responses which haven't been classified. By default,
# it goes out 3 days after last update of event, then after 10, then after 24.
def self.alert_new_response_reminders
- Configuration::new_response_reminder_after_days.each_with_index do |days, i|
+ AlaveteliConfiguration::new_response_reminder_after_days.each_with_index do |days, i|
self.alert_new_response_reminders_internal(days, "new_response_reminder_#{i+1}")
end
end
@@ -348,7 +364,7 @@ class RequestMailer < ApplicationMailer
store_sent.alert_type = type_code
store_sent.info_request_event_id = alert_event_id
# XXX uses same template for reminder 1 and reminder 2 right now.
- RequestMailer.deliver_new_response_reminder_alert(info_request, last_response_message)
+ RequestMailer.new_response_reminder_alert(info_request, last_response_message).deliver
store_sent.save!
end
end
@@ -376,7 +392,7 @@ class RequestMailer < ApplicationMailer
# Only send the alert if the user can act on it by making a followup
# (otherwise they are banned, and there is no point sending it)
if info_request.user.can_make_followup?
- RequestMailer.deliver_not_clarified_alert(info_request, last_response_message)
+ RequestMailer.not_clarified_alert(info_request, last_response_message).deliver
end
store_sent.save!
end
@@ -440,9 +456,9 @@ class RequestMailer < ApplicationMailer
store_sent.alert_type = 'comment_1'
store_sent.info_request_event_id = last_comment_event.id
if count > 1
- RequestMailer.deliver_comment_on_alert_plural(info_request, count, earliest_unalerted_comment_event.comment)
+ RequestMailer.comment_on_alert_plural(info_request, count, earliest_unalerted_comment_event.comment).deliver
elsif count == 1
- RequestMailer.deliver_comment_on_alert(info_request, last_comment_event.comment)
+ RequestMailer.comment_on_alert(info_request, last_comment_event.comment).deliver
else
raise "internal error"
end
diff --git a/app/models/track_mailer.rb b/app/mailers/track_mailer.rb
index 51440e4d7..391143214 100644
--- a/app/models/track_mailer.rb
+++ b/app/mailers/track_mailer.rb
@@ -2,30 +2,31 @@
# Emails which go to users who are tracking things.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class TrackMailer < ApplicationMailer
def event_digest(user, email_about_things)
+ @user, @email_about_things = user, email_about_things
+
post_redirect = PostRedirect.new(
:uri => user_url(user) + "#email_subscriptions",
:user_id => user.id)
post_redirect.save!
- unsubscribe_url = confirm_url(:email_token => post_redirect.email_token)
+ @unsubscribe_url = confirm_url(:email_token => post_redirect.email_token)
- @from = contact_from_name_and_email
- headers 'Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
- 'Precedence' => 'bulk' # http://www.vbulletin.com/forum/project.php?issueid=27687 (Exchange hack)
+ headers('Auto-Submitted' => 'auto-generated', # http://tools.ietf.org/html/rfc3834
+ 'Precedence' => 'bulk')# http://www.vbulletin.com/forum/project.php?issueid=27687 (Exchange hack)
# 'Return-Path' => blackhole_email, 'Reply-To' => @from # we don't care about bounces for tracks
# (We let it return bounces for now, so we can manually kill the tracks that bounce so Yahoo
# etc. don't decide we are spammers.)
- @recipients = user.name_and_email
- @subject = _("Your {{site_name}} email alert", :site_name => site_name)
- @body = { :user => user, :email_about_things => email_about_things, :unsubscribe_url => unsubscribe_url }
+ mail(:from => contact_from_name_and_email,
+ :to => user.name_and_email,
+ :subject => _("Your {{site_name}} email alert", :site_name => site_name))
end
def contact_from_name_and_email
- "#{Configuration::track_sender_name} <#{Configuration::track_sender_email}>"
+ "#{AlaveteliConfiguration::track_sender_name} <#{AlaveteliConfiguration::track_sender_email}>"
end
# Send email alerts for tracked things. Never more than one email
@@ -91,10 +92,9 @@ class TrackMailer < ApplicationMailer
if email_about_things.size > 0
# Send the email
- previous_locale = I18n.locale
- I18n.locale = user.get_locale
- TrackMailer.deliver_event_digest(user, email_about_things)
- I18n.locale = previous_locale
+ I18n.with_locale(user.get_locale) do
+ TrackMailer.event_digest(user, email_about_things).deliver
+ end
end
# Record that we've now sent those alerts to that user
diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb
new file mode 100644
index 000000000..a351147f9
--- /dev/null
+++ b/app/mailers/user_mailer.rb
@@ -0,0 +1,44 @@
+# models/user_mailer.rb:
+# Emails relating to user accounts. e.g. Confirming a new account
+#
+# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
+
+class UserMailer < ApplicationMailer
+ def confirm_login(user, reasons, url)
+ @reasons, @name, @url = reasons, user.name, url
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email) # we don't care about bounces when people are fiddling with their account
+
+ mail(:from => contact_from_name_and_email,
+ :to => user.name_and_email,
+ :subject => reasons[:email_subject])
+ end
+
+ def already_registered(user, reasons, url)
+ @reasons, @name, @url = reasons, user.name, url
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email) # we don't care about bounces when people are fiddling with their account
+
+ mail(:from => contact_from_name_and_email,
+ :to => user.name_and_email,
+ :subject => reasons[:email_subject])
+ end
+
+ def changeemail_confirm(user, new_email, url)
+ @name, @url, @old_email, @new_email = user.name, url, user.email, new_email
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email) # we don't care about bounces when people are fiddling with their account
+
+ mail(:from => contact_from_name_and_email,
+ :to => new_email,
+ :subject => _("Confirm your new email address on {{site_name}}", :site_name => site_name))
+ end
+
+ def changeemail_already_used(old_email, new_email)
+ @old_email, @new_email = old_email, new_email
+ headers('Return-Path' => blackhole_email, 'Reply-To' => contact_from_name_and_email) # we don't care about bounces when people are fiddling with their account
+
+ mail(:from => contact_from_name_and_email,
+ :to => new_email,
+ :subject => _("Unable to change email address on {{site_name}}", :site_name=>site_name))
+ end
+end
+
diff --git a/app/models/about_me_validator.rb b/app/models/about_me_validator.rb
index 8ee505ac8..7df70fb61 100644
--- a/app/models/about_me_validator.rb
+++ b/app/models/about_me_validator.rb
@@ -1,25 +1,23 @@
-# == Schema Information
-# Schema version: 114
-#
-# Table name: about_me_validators
-#
-# about_me :text default("I..."), not null
-#
-
# models/about_me_validator.rb:
# Validates editing about me text on user profile pages.
#
# Copyright (c) 2010 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
-class AboutMeValidator < ActiveRecord::BaseWithoutTable
- strip_attributes!
+class AboutMeValidator
+ include ActiveModel::Validations
- column :about_me, :text, "I...", false
+ attr_accessor :about_me
# TODO: Switch to built in validations
validate :length_of_about_me
+ def initialize(attributes = {})
+ attributes.each do |name, value|
+ send("#{name}=", value)
+ end
+ end
+
private
def length_of_about_me
diff --git a/app/models/application_mailer.rb b/app/models/application_mailer.rb
deleted file mode 100644
index 1a97a4bf9..000000000
--- a/app/models/application_mailer.rb
+++ /dev/null
@@ -1,164 +0,0 @@
-# models/application_mailer.rb:
-# Shared code between different mailers.
-#
-# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-require 'action_mailer/version'
-class ApplicationMailer < ActionMailer::Base
- # Include all the functions views get, as emails call similar things.
- helper :application
- include MailerHelper
-
- # This really should be the default - otherwise you lose any information
- # about the errors, and have to do error checking on return codes.
- self.raise_delivery_errors = true
-
- def blackhole_email
- Configuration::blackhole_prefix+"@"+Configuration::incoming_email_domain
- end
-
- # URL generating functions are needed by all controllers (for redirects),
- # views (for links) and mailers (for use in emails), so include them into
- # all of all.
- include LinkToHelper
-
- # Site-wide access to configuration settings
- include ConfigHelper
-
- # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
- # will be initialized according to the named method. If not, the mailer will
- # remain uninitialized (useful when you only need to invoke the "receive"
- # method, for instance).
- def initialize(method_name=nil, *parameters) #:nodoc:
- create!(method_name, *parameters) if method_name
- end
-
- # For each multipart template (e.g. "the_template_file.text.html.erb") available,
- # add the one from the view path with the highest priority as a part to the mail
- def render_multipart_templates
- added_content_types = {}
- self.view_paths.each do |view_path|
- Dir.glob("#{view_path}/#{mailer_name}/#{@template}.*").each do |path|
- template = view_path["#{mailer_name}/#{File.basename(path)}"]
-
- # Skip unless template has a multipart format
- next unless template && template.multipart?
- next if added_content_types[template.content_type] == true
- @parts << Part.new(
- :content_type => template.content_type,
- :disposition => "inline",
- :charset => charset,
- :body => render_message(template, @body)
- )
- added_content_types[template.content_type] = true
- end
- end
- end
-
- # Look for the current template in each element of view_paths in order,
- # return the first
- def find_template
- self.view_paths.each do |view_path|
- if template = view_path["#{mailer_name}/#{@template}"]
- return template
- end
- end
- return nil
- end
-
- if ActionMailer::VERSION::MAJOR == 2
-
- # This method is a customised version of ActionMailer::Base.create!
- # modified to allow templates to be selected correctly for multipart
- # mails when themes have added to the view_paths. The problem from our
- # point of view with ActionMailer::Base is that it sets template_root to
- # the first element of the view_paths array and then uses only that (directly
- # and via template_path, which is created from it) in the create! method when
- # looking for templates. Our modified version looks for templates in the view_paths
- # in order.
-
- # It also has a line converting the mail subject to a string. This is because we
- # use translated strings in the subject lines, sometimes in conjunction with
- # user input, like request titles. The _() function used for translation
- # returns an instance of SafeBuffer, which doesn't handle gsub calls in the block form
- # with $ variables - https://github.com/rails/rails/issues/1555.
- # Unfortunately ActionMailer uses that form in quoted_printable(), which will be
- # called if any part of the subject requires quoting. So we convert the subject
- # back to a string via to_str() before passing in to create_mail. There is a test
- # for this in spec/models/request_mailer_spec.rb
-
- # Changed lines marked with ***
-
- # Initialize the mailer via the given +method_name+. The body will be
- # rendered and a new TMail::Mail object created.
- def create!(method_name, *parameters) #:nodoc:
- initialize_defaults(method_name)
- __send__(method_name, *parameters)
-
- # If an explicit, textual body has not been set, we check assumptions.
- unless String === @body
- # First, we look to see if there are any likely templates that match,
- # which include the content-type in their file name (i.e.,
- # "the_template_file.text.html.erb", etc.). Only do this if parts
- # have not already been specified manually.
- if @parts.empty?
- # *** render_multipart_templates replaces the following code
- # Dir.glob("#{template_path}/#{@template}.*").each do |path|
- # template = template_root["#{mailer_name}/#{File.basename(path)}"]
- #
- # # Skip unless template has a multipart format
- # next unless template && template.multipart?
- #
- # @parts << Part.new(
- # :content_type => template.content_type,
- # :disposition => "inline",
- # :charset => charset,
- # :body => render_message(template, @body)
- # )
- # end
- render_multipart_templates
-
- unless @parts.empty?
- @content_type = "multipart/alternative" if @content_type !~ /^multipart/
- @parts = sort_parts(@parts, @implicit_parts_order)
- end
- end
-
- # Then, if there were such templates, we check to see if we ought to
- # also render a "normal" template (without the content type). If a
- # normal template exists (or if there were no implicit parts) we render
- # it.
- template_exists = @parts.empty?
-
- # *** find_template replaces template_root call
- # template_exists ||= template_root["#{mailer_name}/#{@template}"]
- template_exists ||= find_template
-
- @body = render_message(@template, @body) if template_exists
-
- # Finally, if there are other message parts and a textual body exists,
- # we shift it onto the front of the parts and set the body to nil (so
- # that create_mail doesn't try to render it in addition to the parts).
- if !@parts.empty? && String === @body
- @parts.unshift ActionMailer::Part.new(:charset => charset, :body => @body)
- @body = nil
- end
- end
-
- # If this is a multipart e-mail add the mime_version if it is not
- # already set.
- @mime_version ||= "1.0" if !@parts.empty?
-
- # *** Convert into a string
- @subject = @subject.to_str if @subject
-
- # build the mail object itself
- @mail = create_mail
- end
- else
- raise "ApplicationMailer.create! is obsolete - find another way to ensure that themes can override mail templates for multipart mails"
- end
-
-end
-
diff --git a/app/models/censor_rule.rb b/app/models/censor_rule.rb
index f40ab6fbb..f0d06e088 100644
--- a/app/models/censor_rule.rb
+++ b/app/models/censor_rule.rb
@@ -20,7 +20,7 @@
# Stores alterations to remove specific data from requests.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class CensorRule < ActiveRecord::Base
belongs_to :info_request
@@ -33,13 +33,15 @@ class CensorRule < ActiveRecord::Base
validate :require_valid_regexp, :if => proc{ |rule| rule.regexp? == true }
validates_presence_of :text
- named_scope :global, {:conditions => {:info_request_id => nil,
- :user_id => nil,
- :public_body_id => nil}}
+ scope :global, {:conditions => {:info_request_id => nil,
+ :user_id => nil,
+ :public_body_id => nil}}
def require_user_request_or_public_body
if self.info_request.nil? && self.user.nil? && self.public_body.nil?
- errors.add("Censor must apply to an info request a user or a body; ")
+ [:info_request, :user, :public_body].each do |a|
+ errors.add(a, "Rule must apply to an info request, a user or a body")
+ end
end
end
diff --git a/app/models/change_email_validator.rb b/app/models/change_email_validator.rb
index 2ddebb177..5cc13d4c2 100644
--- a/app/models/change_email_validator.rb
+++ b/app/models/change_email_validator.rb
@@ -1,36 +1,27 @@
-# == Schema Information
-# Schema version: 114
-#
-# Table name: change_email_validators
-#
-# old_email :string
-# new_email :string
-# password :string
-# user_circumstance :string
-#
-
# models/changeemail_validator.rb:
# Validates email change form submissions.
#
# Copyright (c) 2010 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-class ChangeEmailValidator < ActiveRecord::BaseWithoutTable
- strip_attributes!
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
- column :old_email, :string
- column :new_email, :string
- column :password, :string
- column :user_circumstance, :string
+class ChangeEmailValidator
+ include ActiveModel::Validations
- attr_accessor :logged_in_user
+ attr_accessor :old_email, :new_email, :password, :user_circumstance, :logged_in_user
validates_presence_of :old_email, :message => N_("Please enter your old email address")
validates_presence_of :new_email, :message => N_("Please enter your new email address")
validates_presence_of :password, :message => N_("Please enter your password"), :unless => :changing_email
validate :password_and_format_of_email
- def changing_email()
+ def initialize(attributes = {})
+ attributes.each do |name, value|
+ send("#{name}=", value)
+ end
+ end
+
+
+ def changing_email
self.user_circumstance == 'change_email'
end
@@ -41,11 +32,11 @@ class ChangeEmailValidator < ActiveRecord::BaseWithoutTable
errors.add(:old_email, _("Old email doesn't look like a valid address"))
end
- if !errors[:old_email]
+ if errors[:old_email].blank?
if self.old_email.downcase != self.logged_in_user.email.downcase
errors.add(:old_email, _("Old email address isn't the same as the address of the account you are logged in with"))
elsif (!self.changing_email) && (!self.logged_in_user.has_this_password?(self.password))
- if !errors[:password]
+ if errors[:password].blank?
errors.add(:password, _("Password is not correct"))
end
end
@@ -55,5 +46,4 @@ class ChangeEmailValidator < ActiveRecord::BaseWithoutTable
errors.add(:new_email, _("New email doesn't look like a valid address"))
end
end
-
end
diff --git a/app/models/comment.rb b/app/models/comment.rb
index 70f3ba00d..9527030a9 100644
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -18,7 +18,7 @@
# A comment by a user upon something.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class Comment < ActiveRecord::Base
strip_attributes!
diff --git a/app/models/contact_mailer.rb b/app/models/contact_mailer.rb
deleted file mode 100644
index abde64928..000000000
--- a/app/models/contact_mailer.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# models/contact_mailer.rb:
-# Sends contact form mails.
-#
-# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-class ContactMailer < ApplicationMailer
-
- # Send message to administrator
- def to_admin_message(name, email, subject, message, logged_in_user, last_request, last_body)
- @from = name + " <" + email + ">"
- @recipients = contact_from_name_and_email
- @subject = subject
- @body = { :message => message,
- :logged_in_user => logged_in_user ,
- :last_request => last_request,
- :last_body => last_body
- }
- end
-
- # We always set Reply-To when we set Return-Path to be different from From,
- # since some email clients seem to erroneously use the envelope from when
- # they shouldn't, and this might help. (Have had mysterious cases of a
- # reply coming in duplicate from a public body to both From and envelope
- # from)
-
- # Send message to another user
- def user_message(from_user, recipient_user, from_user_url, subject, message)
- @from = from_user.name_and_email
- # Do not set envelope from address to the from_user, so they can't get
- # someone's email addresses from transitory bounce messages.
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from
- @recipients = recipient_user.name_and_email
- @subject = subject
- @body = {
- :message => message,
- :from_user => from_user,
- :recipient_user => recipient_user,
- :from_user_url => from_user_url
- }
- end
-
- # Send message to a user from the administrator
- def from_admin_message(recipient_user, subject, message)
- @from = contact_from_name_and_email
- @recipients = recipient_user.name_and_email
- @subject = subject
- @body = {
- :message => message,
- :from_user => @from,
- :recipient_user => recipient_user,
- }
- bcc Configuration::contact_email
- end
-
-end
diff --git a/app/models/contact_validator.rb b/app/models/contact_validator.rb
index d277161f9..65e539669 100644
--- a/app/models/contact_validator.rb
+++ b/app/models/contact_validator.rb
@@ -1,35 +1,29 @@
-# == Schema Information
-# Schema version: 114
-#
-# Table name: contact_validators
-#
-# name :string
-# email :string
-# subject :text
-# message :text
-#
-
# models/contact_validator.rb:
# Validates contact form submissions.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
-class ContactValidator < ActiveRecord::BaseWithoutTable
- strip_attributes!
+class ContactValidator
+ include ActiveModel::Validations
- column :name, :string
- column :email, :string
- column :subject, :text
- column :message, :text
+ attr_accessor :name, :email, :subject, :message
validates_presence_of :name, :message => N_("Please enter your name")
validates_presence_of :email, :message => N_("Please enter your email address")
validates_presence_of :subject, :message => N_("Please enter a subject")
validates_presence_of :message, :message => N_("Please enter the message you want to send")
+ validate :email_format
- def validate
- errors.add(:email, _("Email doesn't look like a valid address")) unless MySociety::Validate.is_valid_email(self.email)
+ def initialize(attributes = {})
+ attributes.each do |name, value|
+ send("#{name}=", value)
+ end
end
+ private
+
+ def email_format
+ errors.add(:email, _("Email doesn't look like a valid address")) unless MySociety::Validate.is_valid_email(self.email)
+ end
end
diff --git a/app/models/foi_attachment.rb b/app/models/foi_attachment.rb
index bba0b6a8d..fcde379e0 100644
--- a/app/models/foi_attachment.rb
+++ b/app/models/foi_attachment.rb
@@ -20,7 +20,7 @@
# An attachment to an email (IncomingMessage)
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
# This is the type which is used to send data about attachments to the view
require 'digest'
@@ -38,11 +38,7 @@ class FoiAttachment < ActiveRecord::Base
BODY_MAX_DELAY = 5
def directory
- rails_env = Rails.env
- if rails_env.nil? || rails_env.empty?
- raise "$RAILS_ENV is not set"
- end
- base_dir = File.expand_path(File.join(File.dirname(__FILE__), "../../cache", "attachments_#{rails_env}"))
+ base_dir = File.expand_path(File.join(File.dirname(__FILE__), "../../cache", "attachments_#{Rails.env}"))
return File.join(base_dir, self.hexdigest[0..2])
end
@@ -67,22 +63,9 @@ class FoiAttachment < ActiveRecord::Base
file.write d
}
update_display_size!
- encode_cached_body!
@cached_body = d
end
- # If the original mail part had a charset, it's some kind of string, so assume that
- # it should be handled as a string in the stated charset, not a bytearray, and then
- # convert it our default encoding. For ruby 1.8 this is a noop.
- def encode_cached_body!
- if RUBY_VERSION.to_f >= 1.9
- if charset
- @cached_body.force_encoding(charset)
- @cached_body = @cached_body.encode(Encoding.default_internal, charset)
- end
- end
- end
-
def body
if @cached_body.nil?
tries = 0
@@ -103,7 +86,6 @@ class FoiAttachment < ActiveRecord::Base
self.incoming_message.parse_raw_email!(force)
retry
end
- encode_cached_body!
end
return @cached_body
end
diff --git a/app/models/holiday.rb b/app/models/holiday.rb
index 13258396a..98f73e963 100644
--- a/app/models/holiday.rb
+++ b/app/models/holiday.rb
@@ -19,7 +19,7 @@
# -- Freedom of Information Act 2000 section 10
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class Holiday < ActiveRecord::Base
diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb
index 5c845ead3..c914edb7e 100644
--- a/app/models/incoming_message.rb
+++ b/app/models/incoming_message.rb
@@ -25,7 +25,7 @@
# response from the public body.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
# TODO
# Move some of the (e.g. quoting) functions here into rblib, as they feel
@@ -37,7 +37,7 @@ require 'rexml/document'
require 'zip/zip'
require 'mapi/msg'
require 'mapi/convert'
-
+require 'iconv' unless RUBY_VERSION >= '1.9'
class IncomingMessage < ActiveRecord::Base
belongs_to :info_request
@@ -193,7 +193,7 @@ class IncomingMessage < ActiveRecord::Base
text.gsub!(self.info_request.public_body.request_email, _("[{{public_body}} request email]", :public_body => self.info_request.public_body.short_or_long_name))
end
text.gsub!(self.info_request.incoming_email, _('[FOI #{{request}} email]', :request => self.info_request.id.to_s) )
- text.gsub!(Configuration::contact_email, _("[{{site_name}} contact email]", :site_name => Configuration::site_name) )
+ text.gsub!(AlaveteliConfiguration::contact_email, _("[{{site_name}} contact email]", :site_name => AlaveteliConfiguration::site_name) )
end
# Replaces all email addresses in (possibly binary data) with equal length alternative ones.
@@ -219,7 +219,7 @@ class IncomingMessage < ActiveRecord::Base
if censored_uncompressed_text != uncompressed_text
# then use the altered file (recompressed)
recompressed_text = nil
- if Configuration::use_ghostscript_compression == true
+ if AlaveteliConfiguration::use_ghostscript_compression == true
command = ["gs", "-sDEVICE=pdfwrite", "-dCompatibilityLevel=1.4", "-dPDFSETTINGS=/screen", "-dNOPAUSE", "-dQUIET", "-dBATCH", "-sOutputFile=-", "-"]
else
command = ["pdftk", "-", "output", "-", "compress"]
@@ -258,11 +258,21 @@ class IncomingMessage < ActiveRecord::Base
# equivalents to the UCS-2
ascii_chars = text.gsub(/\0/, "")
emails = ascii_chars.scan(MySociety::Validate.email_find_regexp)
+
# Convert back to UCS-2, making a mask at the same time
- emails.map! {|email| [
- Iconv.conv('ucs-2le', 'ascii', email[0]),
- Iconv.conv('ucs-2le', 'ascii', email[0].gsub(/[^@.]/, 'x'))
- ] }
+ if RUBY_VERSION >= '1.9'
+ emails.map! do |email|
+ # We want the ASCII representation of UCS-2
+ [email[0].encode('UTF-16LE').force_encoding('US-ASCII'),
+ email[0].gsub(/[^@.]/, 'x').encode('UTF-16LE').force_encoding('US-ASCII')]
+ end
+ else
+ emails.map! {|email| [
+ Iconv.conv('ucs-2le', 'ascii', email[0]),
+ Iconv.conv('ucs-2le', 'ascii', email[0].gsub(/[^@.]/, 'x'))
+ ] }
+ end
+
# Now search and replace the UCS-2 email with the UCS-2 mask
for email, mask in emails
text.gsub!(email, mask)
@@ -316,7 +326,7 @@ class IncomingMessage < ActiveRecord::Base
text.gsub!(/(Mobile|Mob)([\s\/]*(Fax|Tel))*\s*:?[\s\d]*\d/, "[mobile number]")
# Remove WhatDoTheyKnow signup links
- text.gsub!(/http:\/\/#{Configuration::domain}\/c\/[^\s]+/, "[WDTK login link]")
+ text.gsub!(/http:\/\/#{AlaveteliConfiguration::domain}\/c\/[^\s]+/, "[WDTK login link]")
# Remove things from censor rules
self.info_request.apply_censor_rules_to_text!(text)
@@ -534,7 +544,7 @@ class IncomingMessage < ActiveRecord::Base
source_charset = 'utf-8' if source_charset.nil?
text = Iconv.conv('utf-8//IGNORE', source_charset, text) +
_("\n\n[ {{site_name}} note: The above text was badly encoded, and has had strange characters removed. ]",
- :site_name => Configuration::site_name)
+ :site_name => AlaveteliConfiguration::site_name)
rescue Iconv::InvalidEncoding, Iconv::IllegalSequence, Iconv::InvalidCharacter
if source_charset != "utf-8"
source_charset = "utf-8"
@@ -605,7 +615,7 @@ class IncomingMessage < ActiveRecord::Base
content_type = 'application/octet-stream'
end
hexdigest = Digest::MD5.hexdigest(content)
- attachment = self.foi_attachments.find_or_create_by_hexdigest(:hexdigest => hexdigest)
+ attachment = self.foi_attachments.find_or_create_by_hexdigest(hexdigest)
attachment.update_attributes(:filename => filename,
:content_type => content_type,
:body => content,
@@ -632,14 +642,14 @@ class IncomingMessage < ActiveRecord::Base
attachment_attributes = MailHandler.get_attachment_attributes(self.mail(force))
attachments = []
attachment_attributes.each do |attrs|
- attachment = self.foi_attachments.find_or_create_by_hexdigest(:hexdigest => attrs[:hexdigest])
- body = attrs.delete(:body)
+ attachment = self.foi_attachments.find_or_create_by_hexdigest(attrs[:hexdigest])
attachment.update_attributes(attrs)
- # Set the body separately as its handling can depend on the value of charset
- attachment.body = body
attachment.save!
attachments << attachment.id
end
+ # Reload to refresh newly created foi_attachments
+ self.reload
+
main_part = get_main_body_text_part
# we don't use get_main_body_text_internal, as we want to avoid charset
# conversions, since /usr/bin/uudecode needs to deal with those.
@@ -748,9 +758,15 @@ class IncomingMessage < ActiveRecord::Base
attachment.body,
attachment.charset)
end
+
# Remove any bad characters
- text = Iconv.conv('utf-8//IGNORE', 'utf-8', text)
- return text
+ if RUBY_VERSION >= '1.9'
+ text.encode("utf-8", :invalid => :replace,
+ :undef => :replace,
+ :replace => "")
+ else
+ Iconv.conv('utf-8//IGNORE', 'utf-8', text)
+ end
end
diff --git a/app/models/info_request.rb b/app/models/info_request.rb
index 237364f56..156399b99 100644
--- a/app/models/info_request.rb
+++ b/app/models/info_request.rb
@@ -26,8 +26,7 @@
require 'digest/sha1'
class InfoRequest < ActiveRecord::Base
- include ActionView::Helpers::UrlHelper
- include ActionController::UrlWriter
+ include Rails.application.routes.url_helpers
strip_attributes!
@@ -51,7 +50,7 @@ class InfoRequest < ActiveRecord::Base
has_tag_string
- named_scope :visible, :conditions => {:prominence => "normal"}
+ scope :visible, :conditions => {:prominence => "normal"}
# user described state (also update in info_request_event, admin_request/edit.rhtml)
validate :must_be_valid_state
@@ -81,6 +80,11 @@ class InfoRequest < ActiveRecord::Base
'blackhole' # just dump them
]
+ # only check on create, so existing models with mixed case are allowed
+ validate :title_formatting, :on => :create
+
+ after_initialize :set_defaults
+
def self.enumerate_states
states = [
'waiting_response',
@@ -148,7 +152,7 @@ class InfoRequest < ActiveRecord::Base
@@custom_states_loaded = false
begin
- if ENV["RAILS_ENV"] != "test"
+ if !Rails.env.test?
require 'customstates'
include InfoRequestCustomStates
@@custom_states_loaded = true
@@ -456,7 +460,7 @@ public
if !allow
if self.handle_rejected_responses == 'bounce'
- RequestMailer.deliver_stopped_responses(self, email, raw_email_data) if !is_external?
+ RequestMailer.stopped_responses(self, email, raw_email_data).deliver if !is_external?
elsif self.handle_rejected_responses == 'holding_pen'
InfoRequest.holding_pen_request.receive(email, raw_email_data, false, reason)
elsif self.handle_rejected_responses == 'blackhole'
@@ -484,13 +488,13 @@ public
self.awaiting_description = true
params = { :incoming_message_id => incoming_message.id }
if !rejected_reason.empty?
- params[:rejected_reason] = rejected_reason
+ params[:rejected_reason] = rejected_reason.to_str
end
self.log_event("response", params)
self.save!
end
self.info_request_events.each { |event| event.xapian_mark_needs_index } # for the "waiting_classification" index
- RequestMailer.deliver_new_response(self, incoming_message) if !is_external?
+ RequestMailer.new_response(self, incoming_message).deliver if !is_external?
end
@@ -543,6 +547,10 @@ public
# states which require administrator action (hence email administrators
# when they are entered, and offer state change dialog to them)
+ def InfoRequest.requires_admin_states
+ return ['requires_admin', 'error_message', 'attention_requested']
+ end
+
def requires_admin?
['requires_admin', 'error_message', 'attention_requested'].include?(described_state)
end
@@ -564,7 +572,7 @@ public
if self.requires_admin?
# Check there is someone to send the message "from"
if !set_by.nil? || !self.user.nil?
- RequestMailer.deliver_requires_admin(self, set_by, message)
+ RequestMailer.requires_admin(self, set_by, message).deliver
end
end
@@ -579,7 +587,7 @@ public
RequestClassification.create!(:user_id => set_by.id,
:info_request_event_id => event.id)
- RequestMailer.deliver_old_unclassified_updated(self) if !is_external?
+ RequestMailer.old_unclassified_updated(self).deliver if !is_external?
end
end
@@ -694,7 +702,7 @@ public
# last_event_forming_initial_request. There may be more obscure
# things, e.g. fees, not properly covered.
def date_response_required_by
- Holiday.due_date_from(self.date_initial_request_last_sent_at, Configuration::reply_late_after_days, Configuration::working_or_calendar_days)
+ Holiday.due_date_from(self.date_initial_request_last_sent_at, AlaveteliConfiguration::reply_late_after_days, AlaveteliConfiguration::working_or_calendar_days)
end
# This is a long stop - even with UK public interest test extensions, 40
# days is a very long time.
@@ -702,10 +710,10 @@ public
last_sent = last_event_forming_initial_request
if self.public_body.is_school?
# schools have 60 working days maximum (even over a long holiday)
- Holiday.due_date_from(self.date_initial_request_last_sent_at, Configuration::special_reply_very_late_after_days, Configuration::working_or_calendar_days)
+ Holiday.due_date_from(self.date_initial_request_last_sent_at, AlaveteliConfiguration::special_reply_very_late_after_days, AlaveteliConfiguration::working_or_calendar_days)
else
# public interest test ICO guidance gives 40 working maximum
- Holiday.due_date_from(self.date_initial_request_last_sent_at, Configuration::reply_very_late_after_days, Configuration::working_or_calendar_days)
+ Holiday.due_date_from(self.date_initial_request_last_sent_at, AlaveteliConfiguration::reply_very_late_after_days, AlaveteliConfiguration::working_or_calendar_days)
end
end
@@ -791,6 +799,16 @@ public
end
end
+ # Returns last event
+ def get_last_event
+ events = self.info_request_events
+ if events.size == 0
+ return nil
+ else
+ return events[-1]
+ end
+ end
+
# Get previous email sent to
def get_previous_email_sent_to(info_request_event)
last_email = nil
@@ -867,10 +885,10 @@ public
end
def InfoRequest.magic_email_for_id(prefix_part, id)
- magic_email = Configuration::incoming_email_prefix
+ magic_email = AlaveteliConfiguration::incoming_email_prefix
magic_email += prefix_part + id.to_s
magic_email += "-" + InfoRequest.hash_from_id(id)
- magic_email += "@" + Configuration::incoming_email_domain
+ magic_email += "@" + AlaveteliConfiguration::incoming_email_domain
return magic_email
end
@@ -881,7 +899,7 @@ public
end
def InfoRequest.hash_from_id(id)
- return Digest::SHA1.hexdigest(id.to_s + Configuration::incoming_email_secret)[0,8]
+ return Digest::SHA1.hexdigest(id.to_s + AlaveteliConfiguration::incoming_email_secret)[0,8]
end
# Called by find_by_incoming_email - and used to be called by separate
@@ -1104,7 +1122,7 @@ public
before_save :purge_in_cache
def purge_in_cache
- if !Configuration::varnish_host.blank? && !self.id.nil?
+ if !AlaveteliConfiguration::varnish_host.blank? && !self.id.nil?
# we only do this for existing info_requests (new ones have a nil id)
path = url_for(:controller => 'request', :action => 'show', :url_title => self.url_title, :only_path => true, :locale => :none)
req = PurgeRequest.find_by_url(path)
@@ -1122,5 +1140,34 @@ public
yield(column.human_name, self.send(column.name), column.type.to_s, column.name)
end
end
+
+ private
+
+ def set_defaults
+ begin
+ if self.described_state.nil?
+ self.described_state = 'waiting_response'
+ end
+ rescue ActiveModel::MissingAttributeError
+ # this should only happen on Model.exists?() call. It can be safely ignored.
+ # See http://www.tatvartha.com/2011/03/activerecordmissingattributeerror-missing-attribute-a-bug-or-a-features/
+ end
+ # FOI or EIR?
+ if !self.public_body.nil? && self.public_body.eir_only?
+ self.law_used = 'eir'
+ end
+ end
+
+ def title_formatting
+ if !self.title.nil? && !MySociety::Validate.uses_mixed_capitals(self.title, 10)
+ errors.add(:title, _('Please write the summary using a mixture of capital and lower case letters. This makes it easier for others to read.'))
+ end
+ if !self.title.nil? && title.size > 200
+ errors.add(:title, _('Please keep the summary short, like in the subject of an email. You can use a phrase, rather than a full sentence.'))
+ end
+ if !self.title.nil? && self.title =~ /^(FOI|Freedom of Information)\s*requests?$/i
+ errors.add(:title, _('Please describe more what the request is about in the subject. There is no need to say it is an FOI request, we add that on anyway.'))
+ end
+ end
end
diff --git a/app/models/info_request_event.rb b/app/models/info_request_event.rb
index 871b81b1f..469aabc4a 100644
--- a/app/models/info_request_event.rb
+++ b/app/models/info_request_event.rb
@@ -20,7 +20,7 @@
# models/info_request_event.rb:
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class InfoRequestEvent < ActiveRecord::Base
belongs_to :info_request
@@ -405,7 +405,7 @@ class InfoRequestEvent < ActiveRecord::Base
:comment_id => self.comment_id,
# XXX would be nice to add links here, but alas the
- # code to make them is in views only. See views/request/details.rhtml
+ # code to make them is in views only. See views/request/details.html.erb
# perhaps can call with @template somehow
}
diff --git a/app/models/mail_server_log.rb b/app/models/mail_server_log.rb
index 755584b90..7f61377ce 100644
--- a/app/models/mail_server_log.rb
+++ b/app/models/mail_server_log.rb
@@ -15,9 +15,7 @@
# We load log file lines for requests in here, for display in the admin interface.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-#
-# $Id: exim_log.rb,v 1.14 2009-09-17 21:10:05 francis Exp $
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class MailServerLog < ActiveRecord::Base
belongs_to :info_request
@@ -53,7 +51,7 @@ class MailServerLog < ActiveRecord::Base
done.save!
f = is_gz ? Zlib::GzipReader.open(file_name) : File.open(file_name, 'r')
- case(Configuration::mta_log_type.to_sym)
+ case(AlaveteliConfiguration::mta_log_type.to_sym)
when :exim
load_exim_log_data(f, done)
when :postfix
@@ -123,13 +121,13 @@ class MailServerLog < ActiveRecord::Base
# We also check the email prefix so that we could, for instance, separately handle a staging and production
# instance running on the same server with different email prefixes.
def MailServerLog.email_addresses_on_line(line)
- prefix = Regexp::quote(Configuration::incoming_email_prefix)
- domain = Regexp::quote(Configuration::incoming_email_domain)
+ prefix = Regexp::quote(AlaveteliConfiguration::incoming_email_prefix)
+ domain = Regexp::quote(AlaveteliConfiguration::incoming_email_domain)
line.scan(/#{prefix}request-[^\s]+@#{domain}/).sort.uniq
end
def MailServerLog.request_sent?(ir)
- case(Configuration::mta_log_type.to_sym)
+ case(AlaveteliConfiguration::mta_log_type.to_sym)
when :exim
request_exim_sent?(ir)
when :postfix
diff --git a/app/models/mail_server_log_done.rb b/app/models/mail_server_log_done.rb
index 3fb20f0b3..0e7e9eec3 100644
--- a/app/models/mail_server_log_done.rb
+++ b/app/models/mail_server_log_done.rb
@@ -13,7 +13,7 @@
# Stores that a particular mail server log file has been loaded in, see mail_server_log.rb
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class MailServerLogDone < ActiveRecord::Base
has_many :mail_server_logs
diff --git a/app/models/outgoing_message.rb b/app/models/outgoing_message.rb
index c75894e6a..11711090e 100644
--- a/app/models/outgoing_message.rb
+++ b/app/models/outgoing_message.rb
@@ -20,7 +20,7 @@
# else. e.g. An initial request for information, or a complaint.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class OutgoingMessage < ActiveRecord::Base
strip_attributes!
@@ -51,6 +51,8 @@ class OutgoingMessage < ActiveRecord::Base
end
end
+ after_initialize :set_default_letter
+
# How the default letter starts and ends
def get_salutation
ret = ""
@@ -86,7 +88,7 @@ class OutgoingMessage < ActiveRecord::Base
"'" + self.info_request.title + "'." +
"\n\n\n\n [ " + self.get_internal_review_insert_here_note + " ] \n\n\n\n" +
"A full history of my FOI request and all correspondence is available on the Internet at this address:\n" +
- "http://" + Configuration::domain + "/request/" + self.info_request.url_title
+ "http://" + AlaveteliConfiguration::domain + "/request/" + self.info_request.url_title
else
""
end
@@ -130,13 +132,6 @@ class OutgoingMessage < ActiveRecord::Base
MySociety::Validate.contains_postcode?(self.body)
end
- # Set default letter
- def after_initialize
- if self.body.nil?
- self.body = get_default_message
- end
- end
-
# Deliver outgoing message
# Note: You can test this from script/console with, say:
# InfoRequest.find(1).outgoing_messages[0].send_message
@@ -147,7 +142,7 @@ class OutgoingMessage < ActiveRecord::Base
self.status = 'sent'
self.save!
- mail_message = OutgoingMailer.deliver_initial_request(self.info_request, self)
+ mail_message = OutgoingMailer.initial_request(self.info_request, self).deliver
self.info_request.log_event(log_event_type, {
:email => mail_message.to_addrs.join(", "),
:outgoing_message_id => self.id,
@@ -159,7 +154,7 @@ class OutgoingMessage < ActiveRecord::Base
self.status = 'sent'
self.save!
- mail_message = OutgoingMailer.deliver_followup(self.info_request, self, self.incoming_message_followup)
+ mail_message = OutgoingMailer.followup(self.info_request, self, self.incoming_message_followup).deliver
self.info_request.log_event('followup_' + log_event_type, {
:email => mail_message.to_addrs.join(", "),
:outgoing_message_id => self.id,
@@ -253,6 +248,12 @@ class OutgoingMessage < ActiveRecord::Base
private
+ def set_default_letter
+ if self.body.nil?
+ self.body = get_default_message
+ end
+ end
+
def format_of_body
if self.body.empty? || self.body =~ /\A#{get_salutation}\s+#{get_signoff}/ || self.body =~ /#{get_internal_review_insert_here_note}/
if self.message_type == 'followup'
diff --git a/app/models/post_redirect.rb b/app/models/post_redirect.rb
index 31f08c21a..409069cb6 100644
--- a/app/models/post_redirect.rb
+++ b/app/models/post_redirect.rb
@@ -24,7 +24,7 @@
# fakes the redirect to include POST parameters in request later.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'openssl' # for random bytes function
@@ -32,6 +32,8 @@ class PostRedirect < ActiveRecord::Base
# Optional, does a login confirm before redirect for use in email links.
belongs_to :user
+ after_initialize :generate_token
+
# We store YAML version of POST parameters in the database
def post_params=(params)
self.post_params_yaml = params.to_yaml
@@ -62,18 +64,6 @@ class PostRedirect < ActiveRecord::Base
MySociety::Util.generate_token
end
- # Make the token
- def after_initialize
- # The token is used to return you to what you are doing after the login form.
- if not self.token
- self.token = PostRedirect.generate_random_token
- end
- # There is a separate token to use in the URL if we send a confirmation email.
- if not self.email_token
- self.email_token = PostRedirect.generate_random_token
- end
- end
-
# Used by (rspec) test code only
def self.get_last_post_redirect
# XXX yeuch - no other easy way of getting the token so we can check
@@ -89,6 +79,18 @@ class PostRedirect < ActiveRecord::Base
PostRedirect.delete_all "updated_at < (now() - interval '2 months')"
end
+ private
+
+ def generate_token
+ # The token is used to return you to what you are doing after the login form.
+ if not self.token
+ self.token = PostRedirect.generate_random_token
+ end
+ # There is a separate token to use in the URL if we send a confirmation email.
+ if not self.email_token
+ self.email_token = PostRedirect.generate_random_token
+ end
+ end
end
diff --git a/app/models/profile_photo.rb b/app/models/profile_photo.rb
index 73d7ca12b..8a6fe1636 100644
--- a/app/models/profile_photo.rb
+++ b/app/models/profile_photo.rb
@@ -13,7 +13,7 @@
# Image of user that goes on their profile.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class ProfilePhoto < ActiveRecord::Base
WIDTH = 96
@@ -29,25 +29,9 @@ class ProfilePhoto < ActiveRecord::Base
attr_accessor :x, :y, :w, :h
- # convert binary data blob into ImageMagick image when assigned
attr_accessor :image
- def after_initialize
- if data.nil?
- self.image = nil
- return
- end
-
- image_list = Magick::ImageList.new
- begin
- image_list.from_blob(data)
- rescue Magick::ImageMagickError
- self.image = nil
- return
- end
- self.image = image_list[0] # XXX perhaps take largest image or somesuch if there were multiple in the file?
- self.convert_image
- end
+ after_initialize :convert_data_to_image
# make image valid format and size
def convert_image
@@ -112,6 +96,25 @@ class ProfilePhoto < ActiveRecord::Base
raise "Internal error, real pictures must have a user"
end
end
+
+ # Convert binary data blob into ImageMagick image when assigned
+ def convert_data_to_image
+ if data.nil?
+ self.image = nil
+ return
+ end
+
+ image_list = Magick::ImageList.new
+ begin
+ image_list.from_blob(data)
+ rescue Magick::ImageMagickError
+ self.image = nil
+ return
+ end
+
+ self.image = image_list[0] # XXX perhaps take largest image or somesuch if there were multiple in the file?
+ self.convert_image
+ end
end
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index 168b9f4c7..a76aeb189 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -45,7 +45,7 @@ class PublicBody < ActiveRecord::Base
before_save :set_api_key, :set_default_publication_scheme
# Every public body except for the internal admin one is visible
- named_scope :visible, lambda {
+ scope :visible, lambda {
{
:conditions => "public_bodies.id <> #{PublicBody.internal_admin_body.id}"
}
@@ -54,7 +54,7 @@ class PublicBody < ActiveRecord::Base
translates :name, :short_name, :request_email, :url_name, :notes, :first_letter, :publication_scheme
# Convenience methods for creating/editing translations via forms
- def translation(locale)
+ def find_translation_by_locale(locale)
self.translations.find_by_locale(locale)
end
@@ -79,7 +79,7 @@ class PublicBody < ActiveRecord::Base
if translation_attrs.respond_to? :each_value # Hash => updating
translation_attrs.each_value do |attrs|
next if skip?(attrs)
- t = translation(attrs[:locale]) || PublicBody::Translation.new
+ t = translation_for(attrs[:locale]) || PublicBody::Translation.new
t.attributes = attrs
calculate_cached_fields(t)
t.save!
@@ -106,28 +106,25 @@ class PublicBody < ActiveRecord::Base
# like find_by_url_name but also search historic url_name if none found
def self.find_by_url_name_with_historic(name)
- locale = self.locale || I18n.locale
- PublicBody.with_locale(locale) do
- found = PublicBody.find(:all,
- :conditions => ["public_body_translations.url_name=?", name],
- :joins => :translations,
- :readonly => false)
- # If many bodies are found (usually because the url_name is the same across
- # locales) return any of them
- return found.first if found.size >= 1
-
- # If none found, then search the history of short names
- old = PublicBody::Version.find_all_by_url_name(name)
- # Find unique public bodies in it
- old = old.map { |x| x.public_body_id }
- old = old.uniq
- # Maybe return the first one, so we show something relevant,
- # rather than throwing an error?
- raise "Two bodies with the same historical URL name: #{name}" if old.size > 1
- return unless old.size == 1
- # does acts_as_versioned provide a method that returns the current version?
- return PublicBody.find(old.first)
- end
+ found = PublicBody.find(:all,
+ :conditions => ["public_body_translations.url_name=?", name],
+ :joins => :translations,
+ :readonly => false)
+ # If many bodies are found (usually because the url_name is the same across
+ # locales) return any of them
+ return found.first if found.size >= 1
+
+ # If none found, then search the history of short names
+ old = PublicBody::Version.find_all_by_url_name(name)
+ # Find unique public bodies in it
+ old = old.map { |x| x.public_body_id }
+ old = old.uniq
+ # Maybe return the first one, so we show something relevant,
+ # rather than throwing an error?
+ raise "Two bodies with the same historical URL name: #{name}" if old.size > 1
+ return unless old.size == 1
+ # does acts_as_versioned provide a method that returns the current version?
+ return PublicBody.find(old.first)
end
# Set the first letter, which is used for faster queries
@@ -243,13 +240,13 @@ class PublicBody < ActiveRecord::Base
# When name or short name is changed, also change the url name
def short_name=(short_name)
- globalize.write(self.class.locale || I18n.locale, :short_name, short_name)
+ globalize.write(I18n.locale, :short_name, short_name)
self[:short_name] = short_name
self.update_url_name
end
def name=(name)
- globalize.write(self.class.locale || I18n.locale, :name, name)
+ globalize.write(I18n.locale, :name, name)
self[:name] = name
self.update_url_name
end
@@ -329,13 +326,13 @@ class PublicBody < ActiveRecord::Base
# The "internal admin" is a special body for internal use.
def PublicBody.internal_admin_body
- PublicBody.with_locale(I18n.default_locale) do
+ I18n.with_locale(I18n.default_locale) do
pb = PublicBody.find_by_url_name("internal_admin_authority")
if pb.nil?
pb = PublicBody.new(
:name => 'Internal admin authority',
:short_name => "",
- :request_email => Configuration::contact_email,
+ :request_email => AlaveteliConfiguration::contact_email,
:home_page => "",
:notes => "",
:publication_scheme => "",
@@ -367,7 +364,7 @@ class PublicBody < ActiveRecord::Base
# of updating them
bodies_by_name = {}
set_of_existing = Set.new()
- PublicBody.with_locale(I18n.default_locale) do
+ I18n.with_locale(I18n.default_locale) do
bodies = (tag.nil? || tag.empty?) ? PublicBody.find(:all) : PublicBody.find_by_tag(tag)
for existing_body in bodies
# Hide InternalAdminBody from import notes
@@ -410,7 +407,7 @@ class PublicBody < ActiveRecord::Base
if public_body = bodies_by_name[name] # Existing public body
available_locales.each do |locale|
- PublicBody.with_locale(locale) do
+ I18n.with_locale(locale) do
changed = ActiveSupport::OrderedHash.new
field_list.each do |field_name|
localized_field_name = (locale.to_s == I18n.default_locale.to_s) ? field_name : "#{field_name}.#{locale}"
@@ -445,7 +442,7 @@ class PublicBody < ActiveRecord::Base
else # New public body
public_body = PublicBody.new(:name=>"", :short_name=>"", :request_email=>"")
available_locales.each do |locale|
- PublicBody.with_locale(locale) do
+ I18n.with_locale(locale) do
changed = ActiveSupport::OrderedHash.new
field_list.each do |field_name|
localized_field_name = (locale.to_s == I18n.default_locale.to_s) ? field_name : "#{field_name}.#{locale}"
@@ -551,7 +548,7 @@ class PublicBody < ActiveRecord::Base
# Returns nil if configuration variable not set
def override_request_email
- e = Configuration::override_all_public_body_request_emails
+ e = AlaveteliConfiguration::override_all_public_body_request_emails
e if e != ""
end
@@ -635,6 +632,8 @@ class PublicBody < ActiveRecord::Base
end
end
+ private
+
def request_email_if_requestable
# Request_email can be blank, meaning we don't have details
if self.is_requestable?
diff --git a/app/models/purge_request.rb b/app/models/purge_request.rb
index 48a16f9e6..e48f3cc6f 100644
--- a/app/models/purge_request.rb
+++ b/app/models/purge_request.rb
@@ -14,7 +14,7 @@
# A queue of URLs to purge
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
#
class PurgeRequest < ActiveRecord::Base
diff --git a/app/models/raw_email.rb b/app/models/raw_email.rb
index de7978b82..6bf01bc74 100644
--- a/app/models/raw_email.rb
+++ b/app/models/raw_email.rb
@@ -10,7 +10,7 @@
# The fat part of models/incoming_message.rb
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class RawEmail < ActiveRecord::Base
# deliberately don't strip_attributes, so keeps raw email properly
@@ -23,10 +23,10 @@ class RawEmail < ActiveRecord::Base
raise "Failed to find the id number of the associated request: has it been saved?"
end
- if ENV["RAILS_ENV"] == "test"
+ if Rails.env.test?
return File.join(Rails.root, 'files/raw_email_test')
else
- return File.join(Configuration::raw_emails_location,
+ return File.join(AlaveteliConfiguration::raw_emails_location,
request_id[0..2], request_id)
end
end
diff --git a/app/models/track_thing.rb b/app/models/track_thing.rb
index a0c74bdb6..66b8a5c47 100644
--- a/app/models/track_thing.rb
+++ b/app/models/track_thing.rb
@@ -19,7 +19,7 @@
# When somebody is getting alerts for something.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'set'
@@ -260,7 +260,7 @@ class TrackThing < ActiveRecord::Base
:title_in_email => self.public_body.law_only_short + " requests to '" + self.public_body.name + "'",
:title_in_rss => self.public_body.law_only_short + " requests to '" + self.public_body.name + "'",
# Authentication
- :web => _("To follow requests made using {{site_name}} to the public authority '{{public_body_name}}'", :site_name=>Configuration::site_name, :public_body_name=>CGI.escapeHTML(self.public_body.name)),
+ :web => _("To follow requests made using {{site_name}} to the public authority '{{public_body_name}}'", :site_name=>AlaveteliConfiguration::site_name, :public_body_name=>CGI.escapeHTML(self.public_body.name)),
:email => _("Then you will be notified whenever someone requests something or gets a response from '{{public_body_name}}'.", :public_body_name=>CGI.escapeHTML(self.public_body.name)),
:email_subject => _("Confirm you want to follow requests to '{{public_body_name}}'", :public_body_name=>self.public_body.name),
# RSS sorting
diff --git a/app/models/track_things_sent_email.rb b/app/models/track_things_sent_email.rb
index a0a4c0f0c..a9ea2520e 100644
--- a/app/models/track_things_sent_email.rb
+++ b/app/models/track_things_sent_email.rb
@@ -16,7 +16,7 @@
# Record that alert has arrived.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class TrackThingsSentEmail < ActiveRecord::Base
belongs_to :info_request_event
diff --git a/app/models/user.rb b/app/models/user.rb
index e6c666e47..63dd5b1dd 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -58,6 +58,9 @@ class User < ActiveRecord::Base
],
:terms => [ [ :variety, 'V', "variety" ] ],
:if => :indexed_by_search?
+
+ after_initialize :set_defaults
+
def created_at_numeric
# format it here as no datetime support in Xapian's value ranges
return self.created_at.strftime("%Y%m%d%H%M%S")
@@ -67,17 +70,6 @@ class User < ActiveRecord::Base
"user"
end
- def after_initialize
- if self.admin_level.nil?
- self.admin_level = 'none'
- end
- if self.new_record?
- # make alert emails go out at a random time for each new user, so
- # overall they are spread out throughout the day.
- self.last_daily_track_email = User.random_time_in_last_day
- end
- end
-
# requested_by: and commented_by: search queries also need updating after save
after_update :reindex_referencing_models
def reindex_referencing_models
@@ -98,12 +90,7 @@ class User < ActiveRecord::Base
end
def get_locale
- if !self.locale.nil?
- locale = self.locale
- else
- locale = I18n.locale
- end
- return locale.to_s
+ (self.locale || I18n.locale).to_s
end
def visible_comments
@@ -141,14 +128,14 @@ class User < ActiveRecord::Base
if user
# There is user with email, check password
if !user.has_this_password?(params[:password])
- user.errors.add_to_base(auth_fail_message)
+ user.errors.add(:base, auth_fail_message)
end
else
# No user of same email, make one (that we don't save in the database)
# for the forms code to use.
user = User.new(params)
# deliberately same message as above so as not to leak whether registered
- user.errors.add_to_base(auth_fail_message)
+ user.errors.add(:base, auth_fail_message)
end
user
end
@@ -201,12 +188,12 @@ class User < ActiveRecord::Base
# The "internal admin" is a special user for internal use.
def User.internal_admin_user
- u = User.find_by_email(Configuration::contact_email)
+ u = User.find_by_email(AlaveteliConfiguration::contact_email)
if u.nil?
password = PostRedirect.generate_random_token
u = User.new(
:name => 'Internal admin user',
- :email => Configuration::contact_email,
+ :email => AlaveteliConfiguration::contact_email,
:password => password,
:password_confirmation => password
)
@@ -279,16 +266,16 @@ class User < ActiveRecord::Base
return false if self.no_limit
# Has the user issued as many as MAX_REQUESTS_PER_USER_PER_DAY requests in the past 24 hours?
- return false if Configuration::max_requests_per_user_per_day.blank?
+ return false if AlaveteliConfiguration::max_requests_per_user_per_day.blank?
recent_requests = InfoRequest.count(:conditions => ["user_id = ? and created_at > now() - '1 day'::interval", self.id])
- return (recent_requests >= Configuration::max_requests_per_user_per_day)
+ return (recent_requests >= AlaveteliConfiguration::max_requests_per_user_per_day)
end
def next_request_permitted_at
return nil if self.no_limit
- n_most_recent_requests = InfoRequest.all(:conditions => ["user_id = ? and created_at > now() - '1 day'::interval", self.id], :order => "created_at DESC", :limit => Configuration::max_requests_per_user_per_day)
- return nil if n_most_recent_requests.size < Configuration::max_requests_per_user_per_day
+ n_most_recent_requests = InfoRequest.all(:conditions => ["user_id = ? and created_at > now() - '1 day'::interval", self.id], :order => "created_at DESC", :limit => AlaveteliConfiguration::max_requests_per_user_per_day)
+ return nil if n_most_recent_requests.size < AlaveteliConfiguration::max_requests_per_user_per_day
nth_most_recent_request = n_most_recent_requests[-1]
return nth_most_recent_request.created_at + 1.day
@@ -407,6 +394,17 @@ class User < ActiveRecord::Base
self.salt = self.object_id.to_s + rand.to_s
end
+ def set_defaults
+ if self.admin_level.nil?
+ self.admin_level = 'none'
+ end
+ if self.new_record?
+ # make alert emails go out at a random time for each new user, so
+ # overall they are spread out throughout the day.
+ self.last_daily_track_email = User.random_time_in_last_day
+ end
+ end
+
def email_and_name_are_valid
if self.email != "" && !MySociety::Validate.is_valid_email(self.email)
errors.add(:email, _("Please enter a valid email address"))
diff --git a/app/models/user_info_request_sent_alert.rb b/app/models/user_info_request_sent_alert.rb
index cf20bcbf5..449a4c237 100644
--- a/app/models/user_info_request_sent_alert.rb
+++ b/app/models/user_info_request_sent_alert.rb
@@ -15,7 +15,7 @@
# given type of alert.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class UserInfoRequestSentAlert < ActiveRecord::Base
belongs_to :user
diff --git a/app/models/user_mailer.rb b/app/models/user_mailer.rb
deleted file mode 100644
index 1be4f8aa3..000000000
--- a/app/models/user_mailer.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# models/user_mailer.rb:
-# Emails relating to user accounts. e.g. Confirming a new account
-#
-# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-class UserMailer < ApplicationMailer
- def confirm_login(user, reasons, url)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from # we don't care about bounces when people are fiddling with their account
- @recipients = user.name_and_email
- @subject = reasons[:email_subject]
- @body[:reasons] = reasons
- @body[:name] = user.name
- @body[:url] = url
- end
-
- def already_registered(user, reasons, url)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from # we don't care about bounces when people are fiddling with their account
- @recipients = user.name_and_email
- @subject = reasons[:email_subject]
- @body[:reasons] = reasons
- @body[:name] = user.name
- @body[:url] = url
- end
-
- def changeemail_confirm(user, new_email, url)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from # we don't care about bounces when people are fiddling with their account
- @recipients = new_email
- @subject = _("Confirm your new email address on {{site_name}}", :site_name=>site_name)
- @body[:name] = user.name
- @body[:url] = url
- @body[:old_email] = user.email
- @body[:new_email] = new_email
- end
-
- def changeemail_already_used(old_email, new_email)
- @from = contact_from_name_and_email
- headers 'Return-Path' => blackhole_email, 'Reply-To' => @from # we don't care about bounces when people are fiddling with their account
- @recipients = new_email
- @subject = _("Unable to change email address on {{site_name}}", :site_name=>site_name)
- @body[:old_email] = old_email
- @body[:new_email] = new_email
- end
-end
-
diff --git a/app/views/admin_censor_rule/_form.rhtml b/app/views/admin_censor_rule/_form.html.erb
index 5035238d6..5035238d6 100644
--- a/app/views/admin_censor_rule/_form.rhtml
+++ b/app/views/admin_censor_rule/_form.html.erb
diff --git a/app/views/admin_censor_rule/_show.rhtml b/app/views/admin_censor_rule/_show.html.erb
index 0d4cece93..0d4cece93 100644
--- a/app/views/admin_censor_rule/_show.rhtml
+++ b/app/views/admin_censor_rule/_show.html.erb
diff --git a/app/views/admin_censor_rule/edit.rhtml b/app/views/admin_censor_rule/edit.html.erb
index 4eb99ce57..230446ed3 100644
--- a/app/views/admin_censor_rule/edit.rhtml
+++ b/app/views/admin_censor_rule/edit.html.erb
@@ -2,14 +2,14 @@
<h1><%=@title%></h1>
-<% form_tag admin_rule_update_path(@censor_rule), :class => "form form-horizontal" do %>
+<%= form_tag admin_rule_update_path(@censor_rule), :class => "form form-horizontal" do %>
<%= render :partial => 'form', :locals => { :info_request => @censor_rule.info_request, :user => @censor_rule.user } %>
<div class="form-actions">
<%= submit_tag 'Save', :accesskey => 's', :class => "btn btn-primary" %>
</div>
<% end %>
-<% form_tag admin_rule_destroy_path(@censor_rule), :class => "form form-horizontal" do %>
+<%= form_tag admin_rule_destroy_path(@censor_rule), :class => "form form-horizontal" do %>
<%= hidden_field_tag(:censor_rule_id, @censor_rule.id) %>
<div class="form-actions">
Permanent! --&gt; <%= submit_tag "Destroy rule", :class => "btn btn-primary" %>
diff --git a/app/views/admin_censor_rule/new.rhtml b/app/views/admin_censor_rule/new.html.erb
index f6978c07c..1694308f3 100644
--- a/app/views/admin_censor_rule/new.rhtml
+++ b/app/views/admin_censor_rule/new.html.erb
@@ -1,8 +1,8 @@
-<% @title = _('New censor rule') %>
+<% @title = 'New censor rule' %>
<h1><%=@title%></h1>
-<% form_tag admin_rule_create_path, :class => "form form-horizontal" do %>
+<%= form_tag admin_rule_create_path, :class => "form form-horizontal" do %>
<%= render :partial => 'form', :locals => { :info_request => @info_request, :user => @censor_user } %>
<div class="form-actions">
<%= submit_tag "Create", :class => "btn btn-primary" %>
diff --git a/app/views/admin_general/_admin_navbar.rhtml b/app/views/admin_general/_admin_navbar.html.erb
index 5cc740f70..5cc740f70 100644
--- a/app/views/admin_general/_admin_navbar.rhtml
+++ b/app/views/admin_general/_admin_navbar.html.erb
diff --git a/app/views/admin_general/debug.rhtml b/app/views/admin_general/debug.html.erb
index 7fd256025..bf984c2e1 100644
--- a/app/views/admin_general/debug.rhtml
+++ b/app/views/admin_general/debug.html.erb
@@ -21,16 +21,13 @@ RUBY_VERSION <%=h RUBY_VERSION %>
<br>
Rails::VERSION::STRING <%=h Rails::VERSION::STRING%>
<br>
-TMail::VERSION::STRING <%=h TMail::VERSION::STRING%>
-<br>
Xapian::version_string <%=h Xapian::version_string%>
</p>
<h2>Configuration</h2>
-<p>environment: <%=h Rails::configuration.environment %>
-<br>environment_path: <%=h Rails::configuration.environment_path %>
-<br>framework_paths: <%=h Rails::configuration.framework_paths.to_yaml %>
+<p>Rails env: <%=h Rails.env %>
+<br>Rails root: <%=h Rails.root %>
</p>
<h2>Environment variables</h2>
diff --git a/app/views/admin_general/index.rhtml b/app/views/admin_general/index.html.erb
index b239a2b3f..b239a2b3f 100644
--- a/app/views/admin_general/index.rhtml
+++ b/app/views/admin_general/index.html.erb
diff --git a/app/views/admin_general/stats.rhtml b/app/views/admin_general/stats.html.erb
index 27dc25ee0..27dc25ee0 100644
--- a/app/views/admin_general/stats.rhtml
+++ b/app/views/admin_general/stats.html.erb
diff --git a/app/views/admin_general/timeline.rhtml b/app/views/admin_general/timeline.html.erb
index 8fd8875b6..8fd8875b6 100644
--- a/app/views/admin_general/timeline.rhtml
+++ b/app/views/admin_general/timeline.html.erb
diff --git a/app/views/admin_public_body/_form.rhtml b/app/views/admin_public_body/_form.html.erb
index 3f346842c..c577d1e18 100644
--- a/app/views/admin_public_body/_form.rhtml
+++ b/app/views/admin_public_body/_form.html.erb
@@ -18,11 +18,10 @@
prefix = "public_body[translated_versions][]"
object = @public_body.new_record? ?
PublicBody::Translation.new :
- @public_body.translation(locale.to_s) || PublicBody::Translation.new
+ @public_body.find_translation_by_locale(locale.to_s) || PublicBody::Translation.new
end
-
- fields_for prefix, object do |t|
%>
+ <%= fields_for prefix, object do |t| %>
<div class="tab-pane" id="div-locale-<%=locale.to_s%>">
<div class="control-group">
<%= t.hidden_field :locale, :value => locale.to_s %>
diff --git a/app/views/admin_public_body/_one_list.rhtml b/app/views/admin_public_body/_one_list.html.erb
index d8746bae7..8f1d719ec 100644
--- a/app/views/admin_public_body/_one_list.rhtml
+++ b/app/views/admin_public_body/_one_list.html.erb
@@ -31,7 +31,7 @@
<% end %>
</div>
-<% form_tag(admin_body_mass_tag_add_url, :method => "post", :class => "form form-inline" ) do %>
+<%= form_tag(admin_body_mass_tag_add_url, :method => "post", :class => "form form-inline" ) do %>
<p>
<%= text_field_tag 'new_tag', params[:new_tag], { :size => 15, :id => "mass_add_tag_new_tag_" + table_name } %>
<%= hidden_field_tag(:query, params[:query], { :id => "mass_add_tag_query_" + table_name } ) %>
diff --git a/app/views/admin_public_body/_tag_help.rhtml b/app/views/admin_public_body/_tag_help.html.erb
index b64e65877..b64e65877 100644
--- a/app/views/admin_public_body/_tag_help.rhtml
+++ b/app/views/admin_public_body/_tag_help.html.erb
diff --git a/app/views/admin_public_body/_tags.rhtml b/app/views/admin_public_body/_tags.html.erb
index 26526f304..26526f304 100644
--- a/app/views/admin_public_body/_tags.rhtml
+++ b/app/views/admin_public_body/_tags.html.erb
diff --git a/app/views/admin_public_body/edit.rhtml b/app/views/admin_public_body/edit.html.erb
index eb0c45f19..a24122671 100644
--- a/app/views/admin_public_body/edit.rhtml
+++ b/app/views/admin_public_body/edit.html.erb
@@ -20,7 +20,7 @@
</div>
<% if @public_body.info_requests.empty? %>
- <% form_tag(admin_body_destroy_path(@public_body), :class => "form form-inline") do %>
+ <%= form_tag(admin_body_destroy_path(@public_body), :class => "form form-inline") do %>
<%= hidden_field_tag(:public_body_id, { :value => @public_body.id } ) %>
<%= submit_tag _("Destroy {{name}}", :name => @public_body.name), :class => "btn btn-danger" %> (this is permanent!)
<% end %>
diff --git a/app/views/admin_public_body/import_csv.rhtml b/app/views/admin_public_body/import_csv.html.erb
index bfe1b0c3b..afda5a468 100644
--- a/app/views/admin_public_body/import_csv.rhtml
+++ b/app/views/admin_public_body/import_csv.html.erb
@@ -9,7 +9,7 @@
<pre id="error"><%=@errors %></pre>
<% end %>
-<% form_tag 'import_csv', :multipart => true do %>
+<%= form_tag 'import_csv', :multipart => true do %>
<p>
<% if @original_csv_file && @temporary_csv_file %>
CSV file:
diff --git a/app/views/admin_public_body/list.rhtml b/app/views/admin_public_body/list.html.erb
index acc05f50d..3d7d9c4cd 100644
--- a/app/views/admin_public_body/list.rhtml
+++ b/app/views/admin_public_body/list.html.erb
@@ -15,7 +15,7 @@
</div>
</div>
-<% form_tag({}, :method => "get", :class => "form form-search") do %>
+<%= form_tag({}, :method => "get", :class => "form form-search") do %>
<%= text_field_tag 'query', params[:query], { :size => 30, :class => "input-large search-query" } %>
<%= submit_tag "Search", :class => "btn" %>
<% if !@query.nil? %>
@@ -35,7 +35,6 @@
<h2>All authorities</h2>
<% else %>
<h2>Substring search matches (<%= @public_bodies.total_entries %> total)</h2>
-
<% end %>
<%= render :partial => 'one_list', :locals => { :bodies => @public_bodies, :table_name => 'substring' } %>
<% end %>
diff --git a/app/views/admin_public_body/missing_scheme.rhtml b/app/views/admin_public_body/missing_scheme.html.erb
index 2ea55ae00..2ea55ae00 100644
--- a/app/views/admin_public_body/missing_scheme.rhtml
+++ b/app/views/admin_public_body/missing_scheme.html.erb
diff --git a/app/views/admin_public_body/new.rhtml b/app/views/admin_public_body/new.html.erb
index 6ead1810c..13e8238d6 100644
--- a/app/views/admin_public_body/new.rhtml
+++ b/app/views/admin_public_body/new.html.erb
@@ -4,7 +4,7 @@
<div class="row">
<div class="span8">
<div id="public_body_form">
- <% form_for :public_body, @public_body, :url => admin_body_create_path, :html => {:class => "form form-horizontal"} do |f| %>
+ <%= form_for @public_body, :as => :public_body, :url => admin_body_create_path, :html => {:class => "form form-horizontal"} do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<div class="form-actions">
<%= f.submit "Create", :class => "btn btn-primary" %>
diff --git a/app/views/admin_public_body/show.rhtml b/app/views/admin_public_body/show.html.erb
index cfb10b24e..cfb10b24e 100644
--- a/app/views/admin_public_body/show.rhtml
+++ b/app/views/admin_public_body/show.html.erb
diff --git a/app/views/admin_request/_incoming_message_actions.rhtml b/app/views/admin_request/_incoming_message_actions.html.erb
index 84c29dcc3..653e73337 100644
--- a/app/views/admin_request/_incoming_message_actions.rhtml
+++ b/app/views/admin_request/_incoming_message_actions.html.erb
@@ -1,6 +1,6 @@
<fieldset class="form-horizontal">
<legend>Actions</legend>
- <% form_tag admin_request_redeliver_incoming_path, :class => "form form-inline" do %>
+ <%= form_tag admin_request_redeliver_incoming_path, :class => "form form-inline" do %>
<div class="control-group">
<label class="control-label" for="url_title_<%= incoming_message.id %>">Redeliver message to one or more other requests</label>
<div class="controls">
@@ -22,7 +22,7 @@
</div>
</div>
- <% form_tag admin_request_destroy_incoming_path, :class => "form form-inline" do %>
+ <%= form_tag admin_request_destroy_incoming_path, :class => "form form-inline" do %>
<div class="control-group">
<label class="control-label" for="destroy_message_<%= incoming_message.id %>">Destroy message</label>
<div class="controls">
diff --git a/app/views/admin_request/_some_requests.rhtml b/app/views/admin_request/_some_requests.html.erb
index cff94956d..cff94956d 100644
--- a/app/views/admin_request/_some_requests.rhtml
+++ b/app/views/admin_request/_some_requests.html.erb
diff --git a/app/views/admin_request/_tags.rhtml b/app/views/admin_request/_tags.html.erb
index 22fbf13c8..22fbf13c8 100644
--- a/app/views/admin_request/_tags.rhtml
+++ b/app/views/admin_request/_tags.html.erb
diff --git a/app/views/admin_request/edit.rhtml b/app/views/admin_request/edit.html.erb
index 1cf5d4f12..0e9c68aea 100644
--- a/app/views/admin_request/edit.rhtml
+++ b/app/views/admin_request/edit.html.erb
@@ -2,7 +2,7 @@
<%= error_messages_for 'info_request' %>
-<% form_tag admin_request_update_path(@info_request) do %>
+<%= form_tag admin_request_update_path(@info_request) do %>
<p><label for="info_request_title"><strong>Title</strong></label> (warning: editing this will break URLs right now)<br/>
<%= text_field 'info_request', 'title', :size => 50 %></p>
@@ -49,7 +49,7 @@
<hr>
-<% form_tag admin_request_destroy_path(@info_request) do %>
+<%= form_tag admin_request_destroy_path(@info_request) do %>
<p>
<strong>This is permanent and irreversible!</strong> <%= submit_tag 'Destroy request entirely' %>
<br>Use it mainly if someone posts private information, e.g. made a Data Protection request. It
diff --git a/app/views/admin_request/edit_comment.rhtml b/app/views/admin_request/edit_comment.html.erb
index 07031f5f2..2cf49a4a8 100644
--- a/app/views/admin_request/edit_comment.rhtml
+++ b/app/views/admin_request/edit_comment.html.erb
@@ -2,7 +2,7 @@
<%= error_messages_for 'comment' %>
-<% form_tag admin_request_update_comment_path(@comment) do %>
+<%= form_tag admin_request_update_comment_path(@comment) do %>
<p><label for="comment_body">Body of annotation</label><br/>
<%= text_area 'comment', 'body', :rows => 10, :cols => 60 %></p>
diff --git a/app/views/admin_request/edit_outgoing.rhtml b/app/views/admin_request/edit_outgoing.html.erb
index ab209be0d..a0c60520a 100644
--- a/app/views/admin_request/edit_outgoing.rhtml
+++ b/app/views/admin_request/edit_outgoing.html.erb
@@ -2,7 +2,7 @@
<%= error_messages_for 'outgoing_message' %>
-<% form_tag admin_request_update_outgoing_path(@outgoing_message) do %>
+<%= form_tag admin_request_update_outgoing_path(@outgoing_message) do %>
<p><label for="outgoing_message_body">Body of message</label><br/>
<%= text_area 'outgoing_message', 'body', :rows => 10, :cols => 60 %></p>
@@ -22,7 +22,7 @@
<%= link_to 'List all', admin_request_list_path %>
</p>
-<% form_tag admin_request_destroy_outgoing_path do %>
+<%= form_tag admin_request_destroy_outgoing_path do %>
<div>
<%= hidden_field_tag 'outgoing_message_id', @outgoing_message.id %>
Warning, this is permanent! ---&gt;
diff --git a/app/views/admin_request/hidden_user_explanation.html.erb b/app/views/admin_request/hidden_user_explanation.html.erb
new file mode 100644
index 000000000..d0a5d727d
--- /dev/null
+++ b/app/views/admin_request/hidden_user_explanation.html.erb
@@ -0,0 +1,10 @@
+<%= _("Dear {{name}},", :name => name_to) %>
+
+<%= _("Your request '{{request}}' at {{url}} has been reviewed by moderators.", :request => info_request.title.html_safe, :url => info_request_url) %>
+
+<%= reason == 'not_foi' ? _("We consider it is not a valid FOI request, and have therefore hidden it from other users.") : _("We consider it to be vexatious, and have therefore hidden it from other users.") %> <%= _("You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further.") %>
+
+<%= _("Yours,") %>
+
+<%= _("The {{site_name}} team.", :site_name => site_name) %>
+
diff --git a/app/views/admin_request/hidden_user_explanation.rhtml b/app/views/admin_request/hidden_user_explanation.rhtml
deleted file mode 100644
index 7084e986f..000000000
--- a/app/views/admin_request/hidden_user_explanation.rhtml
+++ /dev/null
@@ -1,10 +0,0 @@
-Dear <%= name_to %>,
-
-Your request '<%= info_request.title.html_safe %>' at <%= info_request_url %> has been reviewed by moderators.
-
-We consider it <% if reason == 'not_foi' %>is not a valid FOI request<% else %>to be vexatious<% end%>, and have therefore hidden it from other users. You will still be able to view it while logged in to the site. Please reply to this email if you would like to discuss this decision further.
-
-Yours,
-
-The <%= site_name %> team.
-
diff --git a/app/views/admin_request/list.rhtml b/app/views/admin_request/list.html.erb
index 10b39d3a2..2bd3e3326 100644
--- a/app/views/admin_request/list.rhtml
+++ b/app/views/admin_request/list.html.erb
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<% form_tag({}, :method => "get", :class => "form form-search") do %>
+<%= form_tag({}, :method => "get", :class => "form form-search") do %>
<%= text_field_tag 'query', params[:query], { :size => 30, :class => "input-large search-query" } %>
<%= submit_tag "Search", :class => "btn" %> (substring search, titles only)
<% end %>
diff --git a/app/views/admin_request/show.rhtml b/app/views/admin_request/show.html.erb
index 8606d21fa..9cbcb68f0 100644
--- a/app/views/admin_request/show.rhtml
+++ b/app/views/admin_request/show.html.erb
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<% form_tag admin_request_move_request_path, { :class => "form form-horizontal" } do %>
+<%= form_tag admin_request_move_request_path, { :class => "form form-horizontal" } do %>
<%= hidden_field_tag 'info_request_id', @info_request.id %>
<div class="accordion" id="info_request">
<div class="accordion-group">
@@ -121,7 +121,7 @@
<p class="help-block">(see also option to general URLs for individual incoming messages below)</p>
</div>
</div>
- <% form_tag admin_request_hide_path(@info_request), :class => "form form-inline", :id => "hide_request_form", 'data-info-request-id' => @info_request.id.to_s do %>
+ <%= form_tag admin_request_hide_path(@info_request), :class => "form form-inline", :id => "hide_request_form", 'data-info-request-id' => @info_request.id.to_s do %>
<div class="control-group">
<% if @info_request.is_external? %>
<label class="control-label">Hide the request:</label>
@@ -149,7 +149,7 @@
<div class="control-group" id="request_hidden_user_subject">
<label for="request_hidden_user_subject_field" class="control-label">Subject of email:</label>
<div class="controls">
- <%= text_field_tag "subject", "Your request on WhatDoTheyKnow.com hidden", {:id => "request_hidden_user_subject_field", :cols => 100} %>
+ <%= text_field_tag "subject", _("Your request on {{site_name}} hidden", :site_name => site_name), {:id => "request_hidden_user_subject_field", :cols => 100} %>
</div>
</div>
@@ -191,7 +191,7 @@
<tr>
<td>
<% if info_request_event.described_state != 'waiting_clarification' and info_request_event.event_type == 'response' %>
- <% form_tag admin_request_clarification_path, :class => "form form-inline admin-table-form admin-inline-form" do %>
+ <%= form_tag admin_request_clarification_path, :class => "form form-inline admin-table-form admin-inline-form" do %>
<%= hidden_field_tag 'info_request_event_id', info_request_event.id, :id => nil %>
<%= submit_tag "Was clarification request", :class => "btn btn-mini btn-primary" %>
<% end %>
@@ -207,7 +207,7 @@
</td>
<td>
<% if column_name == 'params_yaml' %>
- <%= info_request_event.params_yaml_as_html %>
+ <%= info_request_event.params_yaml_as_html.html_safe %>
<% elsif value.nil? %>
nil
<% elsif %w(text string).include?(type) %>
@@ -233,7 +233,7 @@
<div class="accordion-group">
<div class="accordion-heading">
<a href="#outgoing_<%=outgoing_message.id%>" data-toggle="collapse" data-parent="#outgoing_messages"><%= chevron_right %></a>
- <% link_to admin_request_edit_outgoing_path(outgoing_message) do %>
+ <%= link_to admin_request_edit_outgoing_path(outgoing_message) do %>
#<%= outgoing_message.id %> -- <%= outgoing_message.status.humanize %> <%= outgoing_message.message_type.humanize %>
<% end %>
<blockquote>
@@ -245,7 +245,7 @@
<tbody>
<tr>
<td colspan="2">
- <% form_tag admin_request_resend_path, :class => "admin-table-form" do %>
+ <%= form_tag admin_request_resend_path, :class => "admin-table-form" do %>
<%= hidden_field_tag 'outgoing_message_id', outgoing_message.id %>
<%= submit_tag "Resend", :class => "btn" %>
<% end %>
@@ -306,7 +306,7 @@
<%= simple_format( truncate(value, :length => 400, :omission => link_to("...", "#", :class => "toggle-hidden"))) %>
<div style="display:none;"><%= simple_format(value) %></div>
<% else %>
- <%= simple_format(value) %>
+ <%= simple_format(value.to_s) %>
<% end %>
</td>
</tr>
@@ -326,7 +326,7 @@
<div class="accordion-group">
<div class="accordion-heading">
<a href="#comment_<%=comment.id%>" data-toggle="collapse" data-parent="#comments"><%= chevron_right %></a>
- <% link_to admin_request_edit_comment_path(comment) do %>
+ <%= link_to admin_request_edit_comment_path(comment) do %>
#<%=comment.id%>
--
<%=h(comment.user.name)%>
diff --git a/app/views/admin_request/show_raw_email.rhtml b/app/views/admin_request/show_raw_email.html.erb
index 72c782ad6..72c782ad6 100644
--- a/app/views/admin_request/show_raw_email.rhtml
+++ b/app/views/admin_request/show_raw_email.html.erb
diff --git a/app/views/admin_track/_some_tracks.rhtml b/app/views/admin_track/_some_tracks.html.erb
index 95101cb55..e9facfb5d 100644
--- a/app/views/admin_track/_some_tracks.rhtml
+++ b/app/views/admin_track/_some_tracks.html.erb
@@ -32,7 +32,7 @@
<% if include_destroy %>
<tr>
<td colspan="2">
- <% form_tag admin_user_destroy_track_path, :class => "form form-inline admin-table-form" do %>
+ <%= form_tag admin_user_destroy_track_path, :class => "form form-inline admin-table-form" do %>
<div>
<%= hidden_field_tag 'track_id', track_thing.id %>
<%= submit_tag "Destroy track", :class => "btn btn-warning" %>
@@ -70,3 +70,5 @@
<% end %>
</div>
<% end %>
+</table>
+
diff --git a/app/views/admin_track/list.rhtml b/app/views/admin_track/list.html.erb
index 9cff5635b..5e967a926 100644
--- a/app/views/admin_track/list.rhtml
+++ b/app/views/admin_track/list.html.erb
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<% form_tag({}, :method => "get", :class => "form form-search") do %>
+<%= form_tag({}, :method => "get", :class => "form form-search") do %>
<%= text_field_tag 'query', params[:query], { :size => 30, :class => "input-large search-query" } %>
<%= submit_tag "Search", :class => "btn" %> (substring search the query – so use url_names_for_a_particular_request_or_authority_or_person)
<% end %>
diff --git a/app/views/admin_user/_form.rhtml b/app/views/admin_user/_form.html.erb
index e7175d09c..e7175d09c 100644
--- a/app/views/admin_user/_form.rhtml
+++ b/app/views/admin_user/_form.html.erb
diff --git a/app/views/admin_user/_user_table.rhtml b/app/views/admin_user/_user_table.html.erb
index 57066bf3f..57066bf3f 100644
--- a/app/views/admin_user/_user_table.rhtml
+++ b/app/views/admin_user/_user_table.html.erb
diff --git a/app/views/admin_user/edit.rhtml b/app/views/admin_user/edit.html.erb
index 3333a1e48..e641a13d6 100644
--- a/app/views/admin_user/edit.rhtml
+++ b/app/views/admin_user/edit.html.erb
@@ -1,6 +1,6 @@
<h1><%=@title%></h1>
-<% form_tag admin_user_update_path(@admin_user), :class => "form form-horizontal" do %>
+<%= form_tag admin_user_update_path(@admin_user), :class => "form form-horizontal" do %>
<%= render :partial => 'form' %>
<div class="form-actions">
<%= submit_tag 'Save', :accesskey => 's', :class => "btn btn-primary" %>
diff --git a/app/views/admin_user/list.rhtml b/app/views/admin_user/list.html.erb
index 23f75c159..b1238f87a 100644
--- a/app/views/admin_user/list.rhtml
+++ b/app/views/admin_user/list.html.erb
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<% form_tag({}, :method => "get", :class => "form form-search") do %>
+<%= form_tag({}, :method => "get", :class => "form form-search") do %>
<%= text_field_tag 'query', params[:query], { :size => 30, :class => "input-large search-query"} %>
<%= submit_tag "Search", :class => "btn" %> (substring search, names and emails)
<%= link_to 'Banned users', admin_user_list_banned_path, :class => "btn btn-info" %>
diff --git a/app/views/admin_user/list_banned.rhtml b/app/views/admin_user/list_banned.html.erb
index e535415e6..e535415e6 100644
--- a/app/views/admin_user/list_banned.rhtml
+++ b/app/views/admin_user/list_banned.html.erb
diff --git a/app/views/admin_user/show.rhtml b/app/views/admin_user/show.html.erb
index 279758f03..c93c08e50 100644
--- a/app/views/admin_user/show.rhtml
+++ b/app/views/admin_user/show.html.erb
@@ -4,7 +4,7 @@
<% if @admin_user.profile_photo %>
<div class="user_photo_on_admin">
- <% form_tag admin_clear_profile_photo_path(@admin_user), :multipart => true, :class => "form" do %>
+ <%= form_tag admin_clear_profile_photo_path(@admin_user), :multipart => true, :class => "form" do %>
<img src="<%= get_profile_photo_url(:url_name => @admin_user.url_name) %>">
<br>
<%= submit_tag "Clear photo", :class => "btn btn-info" %>
@@ -32,13 +32,13 @@
<%=link_to @admin_user.email, "mailto:#{h @admin_user.email}"%>
<% elsif column_name == 'email_bounce_message' %>
<% unless @admin_user.email_bounce_message.empty? %>
- <%= link_to _("See bounce message"), admin_user_show_bounce(@admin_user.id) %>
+ <%= link_to _("See bounce message"), admin_user_show_bounce_path(@admin_user.id) %>
<% end %>
<% else %>
<%=h admin_value(value)%>
<% end %>
<% if column_name == 'email_bounced_at' && !@admin_user.email_bounced_at.nil? %>
- <% form_tag admin_user_clear_bounce_path(@admin_user), :class => "form form-inline" do %>
+ <%= form_tag admin_user_clear_bounce_path(@admin_user), :class => "form form-inline" do %>
<input type="submit" name="action" value="Clear bounce" class="btn btn-info">
<% end %>
<% end %>
diff --git a/app/views/admin_user/show_bounce_message.rhtml b/app/views/admin_user/show_bounce_message.html.erb
index ad643a13e..ad643a13e 100644
--- a/app/views/admin_user/show_bounce_message.rhtml
+++ b/app/views/admin_user/show_bounce_message.html.erb
diff --git a/app/views/comment/_comment_form.rhtml b/app/views/comment/_comment_form.html.erb
index 120929643..91cd8f7d0 100644
--- a/app/views/comment/_comment_form.rhtml
+++ b/app/views/comment/_comment_form.html.erb
@@ -1,4 +1,4 @@
-<% form_for(:comment, @comment, :url => { :controller => "comment", :action => "new", :type => "request" }, :html => { :id => 'comment_form' } ) do |f| %>
+<%= form_for(@comment, :as => :comment, :url => { :controller => "comment", :action => "new", :type => "request" }, :html => { :id => 'comment_form' } ) do |f| %>
<p>
<%= f.text_area :body, :rows => 10, :cols => 55 %>
</p>
diff --git a/app/views/comment/_single_comment.rhtml b/app/views/comment/_single_comment.html.erb
index 421a9d4ba..421a9d4ba 100644
--- a/app/views/comment/_single_comment.rhtml
+++ b/app/views/comment/_single_comment.html.erb
diff --git a/app/views/comment/new.rhtml b/app/views/comment/new.html.erb
index 578732cdb..578732cdb 100644
--- a/app/views/comment/new.rhtml
+++ b/app/views/comment/new.html.erb
diff --git a/app/views/comment/preview.rhtml b/app/views/comment/preview.html.erb
index 702bd9a9b..cd966e6a5 100644
--- a/app/views/comment/preview.rhtml
+++ b/app/views/comment/preview.html.erb
@@ -1,6 +1,6 @@
<% @title = _("Preview new annotation on '{{info_request_title}}'",:info_request_title=>h(@info_request.title)) %>
-<% form_for(:comment, @comment, :html => { :id => 'preview_form' }, :url => { :controller => "comment", :action => "new", :type => "request" } ) do |f| %>
+<%= form_for(@comment, :html => { :id => 'preview_form' }, :url => { :controller => "comment", :action => "new", :type => "request" } ) do |f| %>
<h1><%= _('Now preview your annotation') %></h1>
diff --git a/app/views/contact_mailer/from_admin_message.rhtml b/app/views/contact_mailer/from_admin_message.text.erb
index 4169d8d3a..4169d8d3a 100644
--- a/app/views/contact_mailer/from_admin_message.rhtml
+++ b/app/views/contact_mailer/from_admin_message.text.erb
diff --git a/app/views/contact_mailer/to_admin_message.rhtml b/app/views/contact_mailer/to_admin_message.text.erb
index dc9b1090b..dc9b1090b 100644
--- a/app/views/contact_mailer/to_admin_message.rhtml
+++ b/app/views/contact_mailer/to_admin_message.text.erb
diff --git a/app/views/contact_mailer/user_message.rhtml b/app/views/contact_mailer/user_message.text.erb
index afa1494db..afa1494db 100644
--- a/app/views/contact_mailer/user_message.rhtml
+++ b/app/views/contact_mailer/user_message.text.erb
diff --git a/app/views/general/_advanced_search_tips.rhtml b/app/views/general/_advanced_search_tips.html.erb
index 08ce04439..08ce04439 100644
--- a/app/views/general/_advanced_search_tips.rhtml
+++ b/app/views/general/_advanced_search_tips.html.erb
diff --git a/app/views/general/_before_body_end.rhtml b/app/views/general/_before_body_end.html.erb
index 25fdf4684..25fdf4684 100644
--- a/app/views/general/_before_body_end.rhtml
+++ b/app/views/general/_before_body_end.html.erb
diff --git a/app/views/general/_before_head_end.rhtml b/app/views/general/_before_head_end.html.erb
index 8886745ab..8886745ab 100644
--- a/app/views/general/_before_head_end.rhtml
+++ b/app/views/general/_before_head_end.html.erb
diff --git a/app/views/general/_credits.rhtml b/app/views/general/_credits.html.erb
index b1a9ce05e..b1a9ce05e 100644
--- a/app/views/general/_credits.rhtml
+++ b/app/views/general/_credits.html.erb
diff --git a/app/views/general/_custom_state_descriptions.rhtml b/app/views/general/_custom_state_descriptions.html.erb
index 913a6d50a..913a6d50a 100644
--- a/app/views/general/_custom_state_descriptions.rhtml
+++ b/app/views/general/_custom_state_descriptions.html.erb
diff --git a/app/views/general/_custom_state_transitions_complete.rhtml b/app/views/general/_custom_state_transitions_complete.html.erb
index e69de29bb..e69de29bb 100644
--- a/app/views/general/_custom_state_transitions_complete.rhtml
+++ b/app/views/general/_custom_state_transitions_complete.html.erb
diff --git a/app/views/general/_custom_state_transitions_pending.rhtml b/app/views/general/_custom_state_transitions_pending.html.erb
index e69de29bb..e69de29bb 100644
--- a/app/views/general/_custom_state_transitions_pending.rhtml
+++ b/app/views/general/_custom_state_transitions_pending.html.erb
diff --git a/app/views/general/_footer.rhtml b/app/views/general/_footer.html.erb
index 36f3919f0..990093694 100644
--- a/app/views/general/_footer.rhtml
+++ b/app/views/general/_footer.html.erb
@@ -1,6 +1,6 @@
<div id="footer">
<%= link_to _("Contact {{site_name}}", :site_name => site_name), help_contact_path %>
-| <img src="/images/twitter-16.png" alt="twitter icon" class="twitter-icon"> <a href="https://twitter.com/<%= Configuration::twitter_username %>"><%= _("Follow us on twitter") %></a>
+| <img src="/images/twitter-16.png" alt="twitter icon" class="twitter-icon"> <a href="https://twitter.com/<%= AlaveteliConfiguration::twitter_username %>"><%= _("Follow us on twitter") %></a>
<%= render :partial => 'general/credits' %>
</div>
<div class="after-footer">&nbsp;</div>
diff --git a/app/views/general/_frontpage_bodies_list.rhtml b/app/views/general/_frontpage_bodies_list.html.erb
index 54400602b..54400602b 100644
--- a/app/views/general/_frontpage_bodies_list.rhtml
+++ b/app/views/general/_frontpage_bodies_list.html.erb
diff --git a/app/views/general/_frontpage_intro_sentence.rhtml b/app/views/general/_frontpage_intro_sentence.html.erb
index 74b849fc9..74b849fc9 100644
--- a/app/views/general/_frontpage_intro_sentence.rhtml
+++ b/app/views/general/_frontpage_intro_sentence.html.erb
diff --git a/app/views/general/_frontpage_new_request.rhtml b/app/views/general/_frontpage_new_request.html.erb
index 499b60eb5..499b60eb5 100644
--- a/app/views/general/_frontpage_new_request.rhtml
+++ b/app/views/general/_frontpage_new_request.html.erb
diff --git a/app/views/general/_frontpage_requests_list.rhtml b/app/views/general/_frontpage_requests_list.html.erb
index fa498dfa7..fa498dfa7 100644
--- a/app/views/general/_frontpage_requests_list.rhtml
+++ b/app/views/general/_frontpage_requests_list.html.erb
diff --git a/app/views/general/_frontpage_search_box.rhtml b/app/views/general/_frontpage_search_box.html.erb
index 890602416..890602416 100644
--- a/app/views/general/_frontpage_search_box.rhtml
+++ b/app/views/general/_frontpage_search_box.html.erb
diff --git a/app/views/general/_locale_switcher.rhtml b/app/views/general/_locale_switcher.html.erb
index d0040bb0d..d0040bb0d 100644
--- a/app/views/general/_locale_switcher.rhtml
+++ b/app/views/general/_locale_switcher.html.erb
diff --git a/app/views/general/_localised_datepicker.rhtml b/app/views/general/_localised_datepicker.html.erb
index ec6593ea0..ec6593ea0 100644
--- a/app/views/general/_localised_datepicker.rhtml
+++ b/app/views/general/_localised_datepicker.html.erb
diff --git a/app/views/general/_orglink.rhtml b/app/views/general/_orglink.html.erb
index 66002c021..66002c021 100644
--- a/app/views/general/_orglink.rhtml
+++ b/app/views/general/_orglink.html.erb
diff --git a/app/views/general/_popup_banner.rhtml b/app/views/general/_popup_banner.html.erb
index 8b1378917..8b1378917 100644
--- a/app/views/general/_popup_banner.rhtml
+++ b/app/views/general/_popup_banner.html.erb
diff --git a/app/views/general/_stylesheet_includes.rhtml b/app/views/general/_stylesheet_includes.html.erb
index 7a03680f8..5b6e12258 100644
--- a/app/views/general/_stylesheet_includes.rhtml
+++ b/app/views/general/_stylesheet_includes.html.erb
@@ -16,6 +16,6 @@
<![endif]-->
<!-- the following method for customising CSS is deprecated; see `doc/THEMES.md` for detail -->
<%= stylesheet_link_tag 'custom', :title => "Main", :rel => "stylesheet" %>
- <% if Configuration::force_registration_on_new_request %>
+ <% if AlaveteliConfiguration::force_registration_on_new_request %>
<%= stylesheet_link_tag 'jquery.fancybox-1.3.4', :rel => "stylesheet" %>
<% end %>
diff --git a/app/views/general/_topnav.rhtml b/app/views/general/_topnav.html.erb
index c7f2cedea..c7f2cedea 100644
--- a/app/views/general/_topnav.rhtml
+++ b/app/views/general/_topnav.html.erb
diff --git a/app/views/general/blog.rhtml b/app/views/general/blog.html.erb
index d42b32282..7146aab5d 100644
--- a/app/views/general/blog.rhtml
+++ b/app/views/general/blog.html.erb
@@ -7,9 +7,9 @@
<img src="/images/twitter-16.png" alt="twitter icon" class="twitter-icon"> <a href="https://twitter.com/<%= @twitter_user %>"><%= _("Follow us on twitter") %></a><br/><br/>
<img src="/images/feed-16.png" alt="RSS icon"> <a href="<%= @feed_url %>"><%= _("Subscribe to blog") %></a>
</div>
- <% if Configuration::twitter_widget_id %>
+ <% if AlaveteliConfiguration::twitter_widget_id %>
<div id="twitter">
- <a class="twitter-timeline" data-dnt=true href="https://twitter.com/<%= Configuration::twitter_username %>" data-widget-id="<%= Configuration::twitter_widget_id %>">Tweets by @<%= Configuration::twitter_username %></a>
+ <a class="twitter-timeline" data-dnt=true href="https://twitter.com/<%= AlaveteliConfiguration::twitter_username %>" data-widget-id="<%= AlaveteliConfiguration::twitter_widget_id %>">Tweets by @<%= AlaveteliConfiguration::twitter_username %></a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</div>
<% end %>
@@ -20,15 +20,15 @@
<h1><%=@title %></h1>
<div id="blog">
- <% for item in @blog_items: %>
+ <% @blog_items.each do |item| %>
<div class="blog_post">
- <h2 id="<%= Time.parse(item['pubDate'][0]).to_i %>"><a href="<%=item['link']%>"><%=h item['title'] %></a></h2>
- <p class="subtitle"><%= _("Posted on {{date}} by {{author}}", :date=>simple_date(Time.parse(item['pubDate'][0])), :author=>item['creator']) %></p>
+ <h2 id="<%= Time.parse(item['pubDate'][0]).to_i %>"><a href="<%=item['link'][0]%>"><%=h item['title'][0] %></a></h2>
+ <p class="subtitle"><%= _("Posted on {{date}} by {{author}}", :date=>simple_date(Time.parse(item['pubDate'][0])), :author=>item['creator'][0]) %></p>
<div>
<% if item['encoded'] %>
- <%= raw item['encoded'] %>
+ <%= raw item['encoded'][0] %>
<% elsif item['description'] %>
- <%= raw item['description'] %>
+ <%= raw item['description'][0] %>
<% end %>
</div>
<p><em>
diff --git a/app/views/general/custom_css.rhtml b/app/views/general/custom_css.html.erb
index 0def82ed0..0def82ed0 100644
--- a/app/views/general/custom_css.rhtml
+++ b/app/views/general/custom_css.html.erb
diff --git a/app/views/general/exception_caught.rhtml b/app/views/general/exception_caught.html.erb
index f8fe4343b..8d78e2e92 100644
--- a/app/views/general/exception_caught.rhtml
+++ b/app/views/general/exception_caught.html.erb
@@ -7,7 +7,7 @@
<ul>
<li><%= _("Check for mistakes if you typed or copied the address.")%></li>
<li><%= _("Search the site to find what you were looking for.")%>
- <% form_tag({:controller => "general", :action => "search_redirect"}, {:id => "search_form" }) do %>
+ <%= form_tag({:controller => "general", :action => "search_redirect"}, {:id => "search_form" }) do %>
<%= text_field_tag 'query', params[:query], { :size => 30, :title => "type your search term here" } %>
<%= submit_tag _("Search") %>
<% end %>
diff --git a/app/views/general/frontpage.rhtml b/app/views/general/frontpage.html.erb
index 6eceb3b28..bf5261d15 100644
--- a/app/views/general/frontpage.rhtml
+++ b/app/views/general/frontpage.html.erb
@@ -1,4 +1,4 @@
-<%# TODO: Cache for 5 minutes %>
+<% # TODO: Cache for 5 minutes %>
<div id="frontpage_splash">
<div id="left_column">
<%= render :partial => "frontpage_new_request" %>
diff --git a/app/views/general/search.rhtml b/app/views/general/search.html.erb
index 50f9f9286..7072ab90f 100644
--- a/app/views/general/search.rhtml
+++ b/app/views/general/search.html.erb
@@ -22,7 +22,7 @@
<% if @advanced %>
<div id="advanced-search">
<p><%= _('To use the advanced search, combine phrases and labels as described in the search tips below.') %></p>
- <% form_tag(advanced_search_url, :method => "get") do %>
+ <%= form_tag(advanced_search_url, :method => "get") do %>
<p>
<%= text_field_tag :query, @query, { :size => 60 } %>
<%= hidden_field_tag 'sortby', @inputted_sortby %>
@@ -35,7 +35,7 @@
<% end %>
</div>
<% else %>
- <% form_tag(request.url, {:method => "get", :id => "search_form"}) do %>
+ <%= form_tag(request.url, {:method => "get", :id => "search_form"}) do %>
<p>
<%= text_field_tag 'query', params[:query], { :size => 40, :title => "type your search term here" } %>
<%= hidden_field_tag 'sortby', @inputted_sortby %>
diff --git a/app/views/help/_sidebar.rhtml b/app/views/help/_sidebar.html.erb
index 2b7ed5647..2b7ed5647 100644
--- a/app/views/help/_sidebar.rhtml
+++ b/app/views/help/_sidebar.html.erb
diff --git a/app/views/help/_why_they_should_reply_by_email.rhtml b/app/views/help/_why_they_should_reply_by_email.html.erb
index faaa2b2e2..faaa2b2e2 100644
--- a/app/views/help/_why_they_should_reply_by_email.rhtml
+++ b/app/views/help/_why_they_should_reply_by_email.html.erb
diff --git a/app/views/help/about.rhtml b/app/views/help/about.html.erb
index 477f0e750..477f0e750 100644
--- a/app/views/help/about.rhtml
+++ b/app/views/help/about.html.erb
diff --git a/app/views/help/alaveteli.rhtml b/app/views/help/alaveteli.html.erb
index 6210f9f24..6210f9f24 100644
--- a/app/views/help/alaveteli.rhtml
+++ b/app/views/help/alaveteli.html.erb
diff --git a/app/views/help/api.rhtml b/app/views/help/api.html.erb
index 57390d65a..57390d65a 100644
--- a/app/views/help/api.rhtml
+++ b/app/views/help/api.html.erb
diff --git a/app/views/help/contact.rhtml b/app/views/help/contact.html.erb
index b1b5d4f24..ad89db9ec 100644
--- a/app/views/help/contact.rhtml
+++ b/app/views/help/contact.html.erb
@@ -40,13 +40,13 @@
<% end %>
</div>
-<% form_for :contact do |f| %>
+<%= form_for :contact do |f| %>
<% if not @user %>
<p>
<label class="form_label" for="contact_name">Your name:</label>
<%= f.text_field :name, :size => 20 %>
- (or <%= link_to "sign in", signin_path(:r => request.request_uri) %>)
+ (or <%= link_to "sign in", signin_path(:r => request.fullpath) %>)
</p>
<p>
diff --git a/app/views/help/credits.rhtml b/app/views/help/credits.html.erb
index 02f1e40e8..02f1e40e8 100644
--- a/app/views/help/credits.rhtml
+++ b/app/views/help/credits.html.erb
diff --git a/app/views/help/officers.rhtml b/app/views/help/officers.html.erb
index 6db706f78..6db706f78 100644
--- a/app/views/help/officers.rhtml
+++ b/app/views/help/officers.html.erb
diff --git a/app/views/help/privacy.rhtml b/app/views/help/privacy.html.erb
index 8e5293892..8e5293892 100644
--- a/app/views/help/privacy.rhtml
+++ b/app/views/help/privacy.html.erb
diff --git a/app/views/help/requesting.rhtml b/app/views/help/requesting.html.erb
index e7cfdd199..e7cfdd199 100644
--- a/app/views/help/requesting.rhtml
+++ b/app/views/help/requesting.html.erb
diff --git a/app/views/help/unhappy.rhtml b/app/views/help/unhappy.html.erb
index 79e3f8273..79e3f8273 100644
--- a/app/views/help/unhappy.rhtml
+++ b/app/views/help/unhappy.html.erb
diff --git a/app/views/holiday/due_date.rhtml b/app/views/holiday/due_date.html.erb
index 6f8c2e51a..6f8c2e51a 100644
--- a/app/views/holiday/due_date.rhtml
+++ b/app/views/holiday/due_date.html.erb
diff --git a/app/views/layouts/admin.rhtml b/app/views/layouts/admin.html.erb
index a58913892..a58913892 100644
--- a/app/views/layouts/admin.rhtml
+++ b/app/views/layouts/admin.html.erb
diff --git a/app/views/layouts/contact_mailer.rhtml b/app/views/layouts/contact_mailer.html.erb
index 3cdc75009..3cdc75009 100644
--- a/app/views/layouts/contact_mailer.rhtml
+++ b/app/views/layouts/contact_mailer.html.erb
diff --git a/app/views/layouts/default.rhtml b/app/views/layouts/default.html.erb
index a66b85e02..023a93138 100644
--- a/app/views/layouts/default.rhtml
+++ b/app/views/layouts/default.html.erb
@@ -43,7 +43,7 @@
<%= render :partial => 'general/before_head_end' %>
</head>
<body class="<%= 'front' if params[:action] == 'frontpage' %>">
- <% if Configuration::force_registration_on_new_request && !@user %>
+ <% if AlaveteliConfiguration::force_registration_on_new_request && !@user %>
<%= javascript_include_tag 'jquery.fancybox-1.3.4.pack' %>
<script type="text/javascript">
$(document).ready(function() {
@@ -93,9 +93,9 @@
<% end %>
- <%= link_to _("Sign out"), signout_path(:r => request.request_uri) %>
+ <%= link_to _("Sign out"), signout_path(:r => request.fullpath) %>
<% else %>
- <%= link_to _("Sign in or sign up"), signin_path(:r => request.request_uri) %>
+ <%= link_to _("Sign in or sign up"), signin_path(:r => request.fullpath) %>
<% end %>
</div>
<% end %>
@@ -140,13 +140,13 @@
<input type="text">
</div>
<%
- unless Configuration::ga_code.empty? || (@user && @user.super?) %>
+ unless AlaveteliConfiguration::ga_code.empty? || (@user && @user.super?) %>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
- var pageTracker = _gat._getTracker("<%= Configuration::ga_code %>");
+ var pageTracker = _gat._getTracker("<%= AlaveteliConfiguration::ga_code %>");
pageTracker._trackPageview();
</script>
diff --git a/app/views/layouts/no_chrome.rhtml b/app/views/layouts/no_chrome.html.erb
index 120ba6f28..120ba6f28 100644
--- a/app/views/layouts/no_chrome.rhtml
+++ b/app/views/layouts/no_chrome.html.erb
diff --git a/app/views/layouts/outgoing_mailer.rhtml b/app/views/layouts/outgoing_mailer.html.erb
index 8bf8ef216..8bf8ef216 100644
--- a/app/views/layouts/outgoing_mailer.rhtml
+++ b/app/views/layouts/outgoing_mailer.html.erb
diff --git a/app/views/layouts/request_mailer.rhtml b/app/views/layouts/request_mailer.html.erb
index 3cdc75009..3cdc75009 100644
--- a/app/views/layouts/request_mailer.rhtml
+++ b/app/views/layouts/request_mailer.html.erb
diff --git a/app/views/layouts/user_mailer.rhtml b/app/views/layouts/user_mailer.html.erb
index 3cdc75009..3cdc75009 100644
--- a/app/views/layouts/user_mailer.rhtml
+++ b/app/views/layouts/user_mailer.html.erb
diff --git a/app/views/outgoing_mailer/_followup_footer.rhtml b/app/views/outgoing_mailer/_followup_footer.text.erb
index d7bc7c5aa..d7bc7c5aa 100644
--- a/app/views/outgoing_mailer/_followup_footer.rhtml
+++ b/app/views/outgoing_mailer/_followup_footer.text.erb
diff --git a/app/views/outgoing_mailer/followup.rhtml b/app/views/outgoing_mailer/followup.text.erb
index 049ebc881..049ebc881 100644
--- a/app/views/outgoing_mailer/followup.rhtml
+++ b/app/views/outgoing_mailer/followup.text.erb
diff --git a/app/views/outgoing_mailer/initial_request.rhtml b/app/views/outgoing_mailer/initial_request.text.erb
index 5c418ecc7..5c418ecc7 100644
--- a/app/views/outgoing_mailer/initial_request.rhtml
+++ b/app/views/outgoing_mailer/initial_request.text.erb
diff --git a/app/views/public_body/_alphabet.rhtml b/app/views/public_body/_alphabet.html.erb
index 46b345c2a..111da5b3b 100644
--- a/app/views/public_body/_alphabet.rhtml
+++ b/app/views/public_body/_alphabet.html.erb
@@ -1,3 +1,3 @@
-<% "A".upto("Z") do |l| -%>
+<%= "A".upto("Z") do |l| -%>
<%= link_to_unless (@tag == l), l, list_public_bodies_path(:tag => l.downcase) %>
<% end %>
diff --git a/app/views/public_body/_body_listing.rhtml b/app/views/public_body/_body_listing.html.erb
index 864ab8c9b..864ab8c9b 100644
--- a/app/views/public_body/_body_listing.rhtml
+++ b/app/views/public_body/_body_listing.html.erb
diff --git a/app/views/public_body/_body_listing_single.rhtml b/app/views/public_body/_body_listing_single.html.erb
index d0496fbb8..d0496fbb8 100644
--- a/app/views/public_body/_body_listing_single.rhtml
+++ b/app/views/public_body/_body_listing_single.html.erb
diff --git a/app/views/public_body/_list_sidebar_extra.rhtml b/app/views/public_body/_list_sidebar_extra.html.erb
index d3d65fec8..d3d65fec8 100644
--- a/app/views/public_body/_list_sidebar_extra.rhtml
+++ b/app/views/public_body/_list_sidebar_extra.html.erb
diff --git a/app/views/public_body/_search_ahead.rhtml b/app/views/public_body/_search_ahead.html.erb
index 7ade89b8e..b1af2464d 100644
--- a/app/views/public_body/_search_ahead.rhtml
+++ b/app/views/public_body/_search_ahead.html.erb
@@ -13,7 +13,7 @@
<%= render :partial => 'body_listing_single', :locals => { :public_body => result[:model] } %>
<% end %>
</div>
- <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @xapian_requests.matches_estimated) %>
+ <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @xapian_requests.matches_estimated), :params => {:controller=>"request", :action => "select_authority"} %>
<% end %>
</div>
diff --git a/app/views/public_body/list.rhtml b/app/views/public_body/list.html.erb
index ea5cd9613..3d73090d4 100644
--- a/app/views/public_body/list.rhtml
+++ b/app/views/public_body/list.html.erb
@@ -32,7 +32,7 @@
<div id="left_column_flip">
<h1><%= _('Public authorities') %></h1>
-<% form_tag(list_public_bodies_default_url, :method => "get", :id=>"search_form") do %>
+<%= form_tag(list_public_bodies_default_url, :method => "get", :id=>"search_form") do %>
<div>
<%= text_field_tag(:public_body_query, params[:public_body_query], { :title => "type your search term here" } ) %>
<%= submit_tag(_("Search")) %>
diff --git a/app/views/public_body/show.rhtml b/app/views/public_body/show.html.erb
index df6346e4f..df6346e4f 100644
--- a/app/views/public_body/show.rhtml
+++ b/app/views/public_body/show.html.erb
diff --git a/app/views/public_body/view_email.rhtml b/app/views/public_body/view_email.html.erb
index 3799d227b..3799d227b 100644
--- a/app/views/public_body/view_email.rhtml
+++ b/app/views/public_body/view_email.html.erb
diff --git a/app/views/public_body/view_email_captcha.rhtml b/app/views/public_body/view_email_captcha.html.erb
index 6f301e055..4f6db5b67 100644
--- a/app/views/public_body/view_email_captcha.rhtml
+++ b/app/views/public_body/view_email_captcha.html.erb
@@ -4,7 +4,7 @@
<p><%= _('To view the email address that we use to send FOI requests to {{public_body_name}}, please enter these words.', :public_body_name => h(@public_body.name))%></p>
-<% form_for :contact do |f| %>
+<%= form_for :contact do |f| %>
<%= recaptcha_tags %>
<%= hidden_field_tag(:submitted_view_email, { :value => 1 } ) %>
diff --git a/app/views/request/_after_actions.rhtml b/app/views/request/_after_actions.html.erb
index d3ddb981b..d3ddb981b 100644
--- a/app/views/request/_after_actions.rhtml
+++ b/app/views/request/_after_actions.html.erb
diff --git a/app/views/request/_bubble.rhtml b/app/views/request/_bubble.html.erb
index 94498612a..94498612a 100644
--- a/app/views/request/_bubble.rhtml
+++ b/app/views/request/_bubble.html.erb
diff --git a/app/views/request/_correspondence.rhtml b/app/views/request/_correspondence.html.erb
index 68711b259..68711b259 100644
--- a/app/views/request/_correspondence.rhtml
+++ b/app/views/request/_correspondence.html.erb
diff --git a/app/views/request/_describe_state.rhtml b/app/views/request/_describe_state.html.erb
index 0b65024fd..05cce013e 100644
--- a/app/views/request/_describe_state.rhtml
+++ b/app/views/request/_describe_state.html.erb
@@ -1,6 +1,6 @@
<% if @is_owning_user %>
- <% form_for(:incoming_message, @info_request, :url => describe_state_url(:id => @info_request.id)) do |f| %>
+ <%= form_for(@info_request, :as => :incoming_message, :url => describe_state_url(:id => @info_request.id), :html => {:id => "describe_form_#{id_suffix}"}) do |f| %>
<h2><%= _('What best describes the status of this request now?') %></h2>
<hr>
@@ -101,13 +101,13 @@
</p>
<% end %>
<% elsif @old_unclassified %>
- <%= render :partial => 'other_describe_state', :locals => {:id_suffix => id_suffix } %>
+ <%= render :partial => 'request/other_describe_state', :locals => {:id_suffix => id_suffix } %>
<% else %>
<% if !@info_request.is_external? %>
<%= _('We don\'t know whether the most recent response to this request contains
information or not
&ndash;
- if you are {{user_link}} please <a href="{{url}}">sign in</a> and let everyone know.',:user_link=>user_link(@info_request.user), :url=>signin_url(:r => request.request_uri)) %>
+ if you are {{user_link}} please <a href="{{url}}">sign in</a> and let everyone know.',:user_link=>user_link(@info_request.user), :url=>signin_url(:r => request.fullpath)) %>
<% end %>
<% end %>
diff --git a/app/views/request/_followup.rhtml b/app/views/request/_followup.html.erb
index bccfccca7..6d2282613 100644
--- a/app/views/request/_followup.rhtml
+++ b/app/views/request/_followup.html.erb
@@ -79,7 +79,7 @@
</p>
<% end %>
- <% form_for(:outgoing_message, @outgoing_message, :html => { :id => 'followup_form' }, :url => incoming_message.nil? ? show_response_no_followup_url(:id => @info_request.id) : show_response_url(:id => @info_request.id, :incoming_message_id => incoming_message.id)) do |o| %>
+ <%= form_for(@outgoing_message, :html => { :id => 'followup_form' }, :url => incoming_message.nil? ? show_response_no_followup_url(:id => @info_request.id) : show_response_url(:id => @info_request.id, :incoming_message_id => incoming_message.id)) do |o| %>
<p>
<%= o.text_area :body, :rows => 15, :cols => 55 %>
</p>
diff --git a/app/views/request/_hidden_correspondence.rhtml b/app/views/request/_hidden_correspondence.html.erb
index 0873b312f..a5e680385 100644
--- a/app/views/request/_hidden_correspondence.rhtml
+++ b/app/views/request/_hidden_correspondence.html.erb
@@ -8,20 +8,20 @@
<div class="correspondence" id="incoming-<%=incoming_message.id.to_s%>">
<p>
<%= raw(_('This response has been hidden. See annotations to find out why.
- If you are the requester, then you may <a href="%s">sign in</a> to view the response.') % [signin_url(:r => request.request_uri)]) %>
+ If you are the requester, then you may <a href="%s">sign in</a> to view the response.') % [signin_url(:r => request.fullpath)]) %>
</p>
</div>
<% elsif [ 'sent', 'followup_sent', 'resent', 'followup_resent' ].include?(info_request_event.event_type) %>
<div class="correspondence" id="outgoing-<%=outgoing_message.id.to_s%>">
<p>
<%= raw(_('This outgoing message has been hidden. See annotations to
- find out why. If you are the requester, then you may <a href="%s">sign in</a> to view the response.') % [signin_url(:r => request.request_uri)]) %>
+ find out why. If you are the requester, then you may <a href="%s">sign in</a> to view the response.') % [signin_url(:r => request.fullpath)]) %>
</p>
</div>
<% elsif info_request_event.event_type == 'comment' %>
<div class="comment_in_request" id="comment-<%=comment.id.to_s%>">
<p><%= raw(_('This comment has been hidden. See annotations to
- find out why. If you are the requester, then you may <a href="%s">sign in</a> to view the response.') % [signin_url(:r => request.request_uri)]) %>
+ find out why. If you are the requester, then you may <a href="%s">sign in</a> to view the response.') % [signin_url(:r => request.fullpath)]) %>
</p>
</div>
<% end %>
diff --git a/app/views/request/_next_actions.rhtml b/app/views/request/_next_actions.html.erb
index f318df6e4..f318df6e4 100644
--- a/app/views/request/_next_actions.rhtml
+++ b/app/views/request/_next_actions.html.erb
diff --git a/app/views/request/_other_describe_state.rhtml b/app/views/request/_other_describe_state.html.erb
index 3a80823c6..e49f9ecb3 100644
--- a/app/views/request/_other_describe_state.rhtml
+++ b/app/views/request/_other_describe_state.html.erb
@@ -1,6 +1,6 @@
-<% form_for(:incoming_message, @info_request, :url => describe_state_url(:id => @info_request.id)) do |f| %>
+<%= form_for(@info_request, :as => :incoming_message, :url => describe_state_url(:id => @info_request.id), :html => {:id => "describe_form_#{id_suffix}"}) do |f| %>
<h2><%= _('Hi! We need your help. The person who made the following request
hasn\'t told us whether or not it was successful. Would you mind taking
a moment to read it and help us keep the place tidy for everyone?
diff --git a/app/views/request/_request_filter_form.rhtml b/app/views/request/_request_filter_form.html.erb
index 0c215a9b6..090db01df 100644
--- a/app/views/request/_request_filter_form.rhtml
+++ b/app/views/request/_request_filter_form.html.erb
@@ -1,7 +1,7 @@
<%= render :partial => 'general/localised_datepicker' %>
<div id="list-filter">
- <% form_tag(request.path, :method => "get", :id=>"filter_requests_form") do %>
+ <%= form_tag(request.path, :method => "get", :id=>"filter_requests_form") do %>
<div class="list-filter-item">
<%= label_tag(:query, _("Keywords"), :class=>"form_label title") %>
<%= text_field_tag(:query, params[:query]) %>
diff --git a/app/views/request/_request_listing.rhtml b/app/views/request/_request_listing.html.erb
index 492f874f3..492f874f3 100644
--- a/app/views/request/_request_listing.rhtml
+++ b/app/views/request/_request_listing.html.erb
diff --git a/app/views/request/_request_listing_short_via_event.rhtml b/app/views/request/_request_listing_short_via_event.html.erb
index c2f6474a1..c2f6474a1 100644
--- a/app/views/request/_request_listing_short_via_event.rhtml
+++ b/app/views/request/_request_listing_short_via_event.html.erb
diff --git a/app/views/request/_request_listing_single.rhtml b/app/views/request/_request_listing_single.html.erb
index 56737fd3e..56737fd3e 100644
--- a/app/views/request/_request_listing_single.rhtml
+++ b/app/views/request/_request_listing_single.html.erb
diff --git a/app/views/request/_request_listing_via_event.rhtml b/app/views/request/_request_listing_via_event.html.erb
index cc8bae8a9..cc8bae8a9 100644
--- a/app/views/request/_request_listing_via_event.rhtml
+++ b/app/views/request/_request_listing_via_event.html.erb
diff --git a/app/views/request/_search_ahead.rhtml b/app/views/request/_search_ahead.html.erb
index 1e65a5458..1e65a5458 100644
--- a/app/views/request/_search_ahead.rhtml
+++ b/app/views/request/_search_ahead.html.erb
diff --git a/app/views/request/_sidebar.rhtml b/app/views/request/_sidebar.html.erb
index af33d31a2..80536da3e 100644
--- a/app/views/request/_sidebar.rhtml
+++ b/app/views/request/_sidebar.html.erb
@@ -11,12 +11,12 @@
<% if @info_request.attention_requested %>
<% if @info_request.prominence == 'hidden' %>
<%# The eccentric formatting of the following string is in order that it be identical
- to the corresponding string in request/show.rhtml %>
+ to the corresponding string in request/show.html.erb %>
<p><%= _('This request has prominence \'hidden\'. You can only see it because you are logged
in as a super user.') %></p>
<% elsif @info_request.prominence == 'requester_only' %>
<%# The eccentric formatting of the following string is in order that it be identical
- to the corresponding string in request/show.rhtml %>
+ to the corresponding string in request/show.html.erb %>
<p><%= raw(_('This request is hidden, so that only you the requester can see it. Please
<a href="%s">contact us</a> if you are not sure why.') % [help_requesting_path]) %></p>
<% else %>
@@ -25,26 +25,23 @@
<% else %>
<p><%= _('Requests for personal information and vexatious requests are not considered valid for FOI purposes (<a href="/help/about">read more</a>).') %></p>
<p><%= _('If you believe this request is not suitable, you can report it for attention by the site administrators') %></p>
- <%= button_to _("Report this request"), report_path, :class => "link_button_green" %>
+ <%= button_to _("Report this request"), report_path(:url_title => @info_request.url_title), :class => "link_button_green" %>
<% end %>
<% end %>
<h2><%= _("Act on what you've learnt") %></h2>
<div class="act_link">
- <%
- # Cast "related" to normal string because html safe string (from rails_xss gem) and CGI::escape
- # interact badly with ':' character. Go figure! Might go away in rails 3
- %>
- <% link_to "https://twitter.com/share?" + {:url => request.url, :via => Configuration::twitter_username, :text => @info_request.title, :related => _('alaveteli_foi:The software that runs {{site_name}}', :site_name => site_name).to_str}.to_query do %>
+ <% tweet_link = "https://twitter.com/share?url=#{h(request.url)}&via=#{h(AlaveteliConfiguration::twitter_username)}&text='#{h(@info_request.title)}'&related=#{_('alaveteli_foi:The software that runs {{site_name}}', :site_name => h(site_name))}" %>
+ <%= link_to tweet_link do %>
<%= image_tag "twitter-16.png", :alt => "twitter icon" %>
- <%= _("Tweet this request") %>
<% end %>
+ <%= link_to _("Tweet this request"), tweet_link %>
</div>
<div class="act_link">
- <% link_to "http://wordpress.com/" do %>
+ <%= link_to "http://wordpress.com/" do %>
<%= image_tag "wordpress.png", :class => "rss" %>
- <%= _("Start your own blog") %>
<% end %>
+ <%= link_to _("Start your own blog"), "http://wordpress.com/"%>
</div>
<%= render :partial => 'request/next_actions' %>
diff --git a/app/views/request/_sidebar_request_listing.rhtml b/app/views/request/_sidebar_request_listing.html.erb
index ec5a5813d..ec5a5813d 100644
--- a/app/views/request/_sidebar_request_listing.rhtml
+++ b/app/views/request/_sidebar_request_listing.html.erb
diff --git a/app/views/request/_summary_suggestion.rhtml b/app/views/request/_summary_suggestion.html.erb
index a5da09cda..a5da09cda 100644
--- a/app/views/request/_summary_suggestion.rhtml
+++ b/app/views/request/_summary_suggestion.html.erb
diff --git a/app/views/request/_view_html_prefix.rhtml b/app/views/request/_view_html_prefix.html.erb
index 3a9946745..3a9946745 100644
--- a/app/views/request/_view_html_prefix.rhtml
+++ b/app/views/request/_view_html_prefix.html.erb
diff --git a/app/views/request/_view_html_stylesheet.rhtml b/app/views/request/_view_html_stylesheet.html.erb
index d6cb932a8..d6cb932a8 100644
--- a/app/views/request/_view_html_stylesheet.rhtml
+++ b/app/views/request/_view_html_stylesheet.html.erb
diff --git a/app/views/request/_wall_listing.rhtml b/app/views/request/_wall_listing.html.erb
index b6b4b38b1..b6b4b38b1 100644
--- a/app/views/request/_wall_listing.rhtml
+++ b/app/views/request/_wall_listing.html.erb
diff --git a/app/views/request/describe_state_message.rhtml b/app/views/request/describe_state_message.html.erb
index 1427fea22..73237759f 100644
--- a/app/views/request/describe_state_message.rhtml
+++ b/app/views/request/describe_state_message.html.erb
@@ -9,7 +9,7 @@
<% end %>
</p>
-<% form_for :incoming_message, :url => describe_state_url(:id => @info_request.id) do |f| %>
+<%= form_for :incoming_message, :url => describe_state_url(:id => @info_request.id) do |f| %>
<p>
<label class="form_label" for="incoming_message_message">Please tell us more:</label>
diff --git a/app/views/request/details.rhtml b/app/views/request/details.html.erb
index 3cb2f5afe..3cb2f5afe 100644
--- a/app/views/request/details.rhtml
+++ b/app/views/request/details.html.erb
diff --git a/app/views/request/followup_bad.rhtml b/app/views/request/followup_bad.html.erb
index c892263e6..c892263e6 100644
--- a/app/views/request/followup_bad.rhtml
+++ b/app/views/request/followup_bad.html.erb
diff --git a/app/views/request/followup_preview.rhtml b/app/views/request/followup_preview.html.erb
index 50c64138f..55afc0245 100644
--- a/app/views/request/followup_preview.rhtml
+++ b/app/views/request/followup_preview.html.erb
@@ -2,7 +2,7 @@
<div id="followup">
-<% form_for(:outgoing_message, @outgoing_message, :html => { :id => 'preview_form' }, :url => (@incoming_message.nil? ? show_response_no_followup_url(:id => @info_request.id) : show_response_url(:id => @info_request.id, :incoming_message_id => @incoming_message.id)) + "#followup" ) do |o| %>
+<%= form_for(@outgoing_message, :html => { :id => 'preview_form' }, :url => (@incoming_message.nil? ? show_response_no_followup_url(:id => @info_request.id) : show_response_url(:id => @info_request.id, :incoming_message_id => @incoming_message.id)) + "#followup" ) do |o| %>
<% if @internal_review %>
<h1><%= _('Now preview your message asking for an internal review') %></h1>
@@ -15,7 +15,7 @@
<li><%= _('Your message will appear in <strong>search engines</strong>') %></li>
</ul>
- <% fields_for :outgoing_message do |o| %>
+ <%= fields_for :outgoing_message do |o| %>
<div class="correspondence" id="outgoing-0">
<p class="preview_subject">
diff --git a/app/views/request/hidden.rhtml b/app/views/request/hidden.html.erb
index 2d038a663..41b2ff7e4 100644
--- a/app/views/request/hidden.rhtml
+++ b/app/views/request/hidden.html.erb
@@ -12,7 +12,7 @@ various reasons why we might have done this, sorry we can\'t be more specific he
</p>
<% if @info_request.prominence == 'requester_only' %>
<p>
- <%= raw(_('If you are the requester, then you may <a href="%s">sign in</a> to view the request.') % [signin_url(:r => request.request_uri)]) %>
+ <%= raw(_('If you are the requester, then you may <a href="%s">sign in</a> to view the request.') % [signin_url(:r => request.fullpath)]) %>
</p>
<% end %>
diff --git a/app/views/request/list.rhtml b/app/views/request/list.html.erb
index 062b77c3e..062b77c3e 100644
--- a/app/views/request/list.rhtml
+++ b/app/views/request/list.html.erb
diff --git a/app/views/request/new.rhtml b/app/views/request/new.html.erb
index 4766c981b..398147041 100644
--- a/app/views/request/new.rhtml
+++ b/app/views/request/new.html.erb
@@ -33,7 +33,7 @@
<%= foi_error_messages_for :info_request, :outgoing_message %>
- <% form_for(:info_request, @info_request, :html => { :id => 'write_form' } ) do |f| %>
+ <%= form_for(@info_request, :url => new_request_path, :html => { :id => 'write_form' } ) do |f| %>
<div id="request_header">
<div id="request_header_body">
@@ -103,7 +103,7 @@
</div>
<div id="request_form">
- <% fields_for :outgoing_message do |o| %>
+ <%= fields_for :outgoing_message do |o| %>
<p>
<label class="form_label" for="outgoing_message_body"><%= _('Your request:') %></label>
<%= o.text_area :body, :rows => 20, :cols => 60 %>
diff --git a/app/views/request/new_bad_contact.rhtml b/app/views/request/new_bad_contact.html.erb
index 56f3f4168..56f3f4168 100644
--- a/app/views/request/new_bad_contact.rhtml
+++ b/app/views/request/new_bad_contact.html.erb
diff --git a/app/views/request/new_please_describe.rhtml b/app/views/request/new_please_describe.html.erb
index ff27405b8..6a193e70d 100644
--- a/app/views/request/new_please_describe.rhtml
+++ b/app/views/request/new_please_describe.html.erb
@@ -13,7 +13,7 @@ if they are successful yet or not.') %>
</ul>
<p>
- <%= raw(_('When you\'re done, <strong>come back here</strong>, <a href="%s">reload this page</a> and file your new request.') % [request.request_uri]) %>
+ <%= raw(_('When you\'re done, <strong>come back here</strong>, <a href="%s">reload this page</a> and file your new request.') % [request.fullpath]) %>
</p>
<p>
diff --git a/app/views/request/preview.rhtml b/app/views/request/preview.html.erb
index 8d1fd753e..84be15ed2 100644
--- a/app/views/request/preview.rhtml
+++ b/app/views/request/preview.html.erb
@@ -1,7 +1,7 @@
<% @title = "Preview new " + h(@info_request.law_used_short) + " request to '" + h(@info_request.public_body.name) + "'" %>
-<% form_for(:info_request, @info_request, :html => { :id => 'preview_form' } ) do |f| %>
-
+<%= form_for(@info_request, :url => new_request_path, :html => { :id => 'preview_form' } ) do |f| %>
+
<h1><%= _('3. Now check your request') %></h1>
<ul>
<li><%= _('Check you haven\'t included any <strong>personal information</strong>.') %></li>
@@ -10,7 +10,7 @@
</li>
</ul>
- <% fields_for :outgoing_message do |o| %>
+ <%= fields_for :outgoing_message do |o| %>
<div class="correspondence" id="outgoing-0">
<p class="preview_subject">
@@ -45,4 +45,4 @@
<p><strong><%= _('Tags:') %></strong> <%=h @info_request.tag_string %></p>
<% end %>
-<% end %> \ No newline at end of file
+<% end %>
diff --git a/app/views/request/select_authority.rhtml b/app/views/request/select_authority.html.erb
index 94e690e64..43a91beff 100644
--- a/app/views/request/select_authority.rhtml
+++ b/app/views/request/select_authority.html.erb
@@ -30,7 +30,7 @@
<h1 style="clear: left"><%= _('1. Select an authority') %></h1>
<div id="authority_selection">
- <% form_tag({:controller => "request", :action => "select_authority"}, {:id => "search_form", :method => "get"}) do %>
+ <%= form_tag({:controller => "request", :action => "select_authority"}, {:id => "search_form", :method => "get"}) do %>
<div>
<p>
<%= raw(_('First, type in the <strong>name of the UK public authority</strong> you\'d
diff --git a/app/views/request/show.rhtml b/app/views/request/show.html.erb
index ef49ef958..54006b291 100644
--- a/app/views/request/show.rhtml
+++ b/app/views/request/show.html.erb
@@ -106,7 +106,7 @@
<%= _('The request is <strong>waiting for clarification</strong>.') %>
<% if !@info_request.is_external? %>
<%= _('If you are {{user_link}}, please',:user_link=>user_link_for_request(@info_request)) %>
- <%= link_to _("sign in"), signin_path(:r => request.request_uri) %> <%= _('to send a follow up message.') %>
+ <%= link_to _("sign in"), signin_path(:r => request.fullpath) %> <%= _('to send a follow up message.') %>
<% end %>
<% end %>
<% elsif @status == 'gone_postal' %>
diff --git a/app/views/request/show_response.rhtml b/app/views/request/show_response.html.erb
index ac1f04227..ac1f04227 100644
--- a/app/views/request/show_response.rhtml
+++ b/app/views/request/show_response.html.erb
diff --git a/app/views/request/similar.rhtml b/app/views/request/similar.html.erb
index 0d53f6919..0d53f6919 100644
--- a/app/views/request/similar.rhtml
+++ b/app/views/request/similar.html.erb
diff --git a/app/views/request/simple_correspondence.rhtml b/app/views/request/simple_correspondence.html.erb
index 0da9ef172..461fa3912 100644
--- a/app/views/request/simple_correspondence.rhtml
+++ b/app/views/request/simple_correspondence.html.erb
@@ -1,4 +1,4 @@
-<%= _('This is a plain-text version of the Freedom of Information request "{{request_title}}". The latest, full version is available online at {{full_url}}', :request_title => @info_request.title, :full_url => "http://#{Configuration::domain}#{show_request_path(:url_title=>@info_request.url_title)}") %>.
+<%= _('This is a plain-text version of the Freedom of Information request "{{request_title}}". The latest, full version is available online at {{full_url}}', :request_title => @info_request.title, :full_url => "http://#{AlaveteliConfiguration::domain}#{show_request_path(:url_title=>@info_request.url_title)}") %>.
<% for info_request_event in @info_request_events %>
<%
diff --git a/app/views/request/upload_response.rhtml b/app/views/request/upload_response.html.erb
index 675951595..158d5d3c4 100644
--- a/app/views/request/upload_response.rhtml
+++ b/app/views/request/upload_response.html.erb
@@ -30,7 +30,7 @@
<p><%= raw(_('Enter your response below. You may attach one file (use email, or
<a href="%s">contact us</a> if you need more).')% [help_contact_path]) %></p>
- <% form_tag '', :id => 'upload_response_form', :multipart => true do %>
+ <%= form_tag '', :id => 'upload_response_form', :multipart => true do %>
<p>
<label class="form_label" for="body"><% _('Response:')%></label>
<%= text_area_tag :body, "", :rows => 10, :cols => 55 %>
diff --git a/app/views/request_game/play.rhtml b/app/views/request_game/play.html.erb
index d5aa0d00e..d5aa0d00e 100644
--- a/app/views/request_game/play.rhtml
+++ b/app/views/request_game/play.html.erb
diff --git a/app/views/request_mailer/comment_on_alert.rhtml b/app/views/request_mailer/comment_on_alert.text.erb
index 691e6f9bb..691e6f9bb 100644
--- a/app/views/request_mailer/comment_on_alert.rhtml
+++ b/app/views/request_mailer/comment_on_alert.text.erb
diff --git a/app/views/request_mailer/comment_on_alert_plural.rhtml b/app/views/request_mailer/comment_on_alert_plural.text.erb
index a495b8e08..a495b8e08 100644
--- a/app/views/request_mailer/comment_on_alert_plural.rhtml
+++ b/app/views/request_mailer/comment_on_alert_plural.text.erb
diff --git a/app/views/request_mailer/external_response.rhtml b/app/views/request_mailer/external_response.rhtml
deleted file mode 100644
index 896054a43..000000000
--- a/app/views/request_mailer/external_response.rhtml
+++ /dev/null
@@ -1 +0,0 @@
-<%= raw @body %>
diff --git a/app/views/request_mailer/external_response.text.erb b/app/views/request_mailer/external_response.text.erb
new file mode 100644
index 000000000..fab256adf
--- /dev/null
+++ b/app/views/request_mailer/external_response.text.erb
@@ -0,0 +1 @@
+<%= @message_body %>
diff --git a/app/views/request_mailer/fake_response.rhtml b/app/views/request_mailer/fake_response.rhtml
deleted file mode 100644
index 896054a43..000000000
--- a/app/views/request_mailer/fake_response.rhtml
+++ /dev/null
@@ -1 +0,0 @@
-<%= raw @body %>
diff --git a/app/views/request_mailer/fake_response.text.erb b/app/views/request_mailer/fake_response.text.erb
new file mode 100644
index 000000000..fab256adf
--- /dev/null
+++ b/app/views/request_mailer/fake_response.text.erb
@@ -0,0 +1 @@
+<%= @message_body %>
diff --git a/app/views/request_mailer/new_response.rhtml b/app/views/request_mailer/new_response.text.erb
index 672212f20..672212f20 100644
--- a/app/views/request_mailer/new_response.rhtml
+++ b/app/views/request_mailer/new_response.text.erb
diff --git a/app/views/request_mailer/new_response_reminder_alert.rhtml b/app/views/request_mailer/new_response_reminder_alert.text.erb
index c196dafe6..c196dafe6 100644
--- a/app/views/request_mailer/new_response_reminder_alert.rhtml
+++ b/app/views/request_mailer/new_response_reminder_alert.text.erb
diff --git a/app/views/request_mailer/not_clarified_alert.rhtml b/app/views/request_mailer/not_clarified_alert.text.erb
index 2408452b3..2408452b3 100644
--- a/app/views/request_mailer/not_clarified_alert.rhtml
+++ b/app/views/request_mailer/not_clarified_alert.text.erb
diff --git a/app/views/request_mailer/old_unclassified_updated.rhtml b/app/views/request_mailer/old_unclassified_updated.text.erb
index 5b8534832..5b8534832 100644
--- a/app/views/request_mailer/old_unclassified_updated.rhtml
+++ b/app/views/request_mailer/old_unclassified_updated.text.erb
diff --git a/app/views/request_mailer/overdue_alert.rhtml b/app/views/request_mailer/overdue_alert.text.erb
index 249bf6bb8..249bf6bb8 100644
--- a/app/views/request_mailer/overdue_alert.rhtml
+++ b/app/views/request_mailer/overdue_alert.text.erb
diff --git a/app/views/request_mailer/requires_admin.rhtml b/app/views/request_mailer/requires_admin.text.erb
index b2e58295e..b2e58295e 100644
--- a/app/views/request_mailer/requires_admin.rhtml
+++ b/app/views/request_mailer/requires_admin.text.erb
diff --git a/app/views/request_mailer/stopped_responses.rhtml b/app/views/request_mailer/stopped_responses.text.erb
index 9cd156860..9cd156860 100644
--- a/app/views/request_mailer/stopped_responses.rhtml
+++ b/app/views/request_mailer/stopped_responses.text.erb
diff --git a/app/views/request_mailer/very_overdue_alert.rhtml b/app/views/request_mailer/very_overdue_alert.text.erb
index 80597473c..80597473c 100644
--- a/app/views/request_mailer/very_overdue_alert.rhtml
+++ b/app/views/request_mailer/very_overdue_alert.text.erb
diff --git a/app/views/track/_tracking_links.rhtml b/app/views/track/_tracking_links.html.erb
index d89c0e4a9..a16dbc78f 100644
--- a/app/views/track/_tracking_links.rhtml
+++ b/app/views/track/_tracking_links.html.erb
@@ -9,7 +9,7 @@
<% elsif existing_track %>
<p><%= track_thing.params[:verb_on_page_already] %></p>
<div class="feed_link feed_link_<%=location%>">
- <%= link_to _("Unsubscribe"), {:controller => 'track', :action => 'update', :track_id => existing_track.id, :track_medium => "delete", :r => request.request_uri}, :class => "link_button_green" %>
+ <%= link_to _("Unsubscribe"), {:controller => 'track', :action => 'update', :track_id => existing_track.id, :track_medium => "delete", :r => request.fullpath}, :class => "link_button_green" %>
</div>
<% elsif track_thing %>
<div class="feed_link feed_link_<%=location%>">
diff --git a/app/views/track/atom_feed.atom.erb b/app/views/track/atom_feed.atom.erb
index 23c932308..a12b9eff0 100644
--- a/app/views/track/atom_feed.atom.erb
+++ b/app/views/track/atom_feed.atom.erb
@@ -9,7 +9,7 @@
# Get the HTML content from the same partial template as website search does
content = ''
if result[:model].class.to_s == 'InfoRequestEvent'
- content += render :partial => 'request/request_listing_via_event', :locals => { :event => result[:model], :info_request => result[:model].info_request }
+ content += render :partial => 'request/request_listing_via_event.html', :locals => { :event => result[:model], :info_request => result[:model].info_request }
else
content = "<p><strong>Unknown search result type " + result[:model].class.to_s + "</strong></p>"
end
diff --git a/app/views/track_mailer/event_digest.rhtml b/app/views/track_mailer/event_digest.text.erb
index 8dbc7fe06..8dbc7fe06 100644
--- a/app/views/track_mailer/event_digest.rhtml
+++ b/app/views/track_mailer/event_digest.text.erb
diff --git a/app/views/user/_change_receive_email.rhtml b/app/views/user/_change_receive_email.html.erb
index 83e5d8601..12824f711 100644
--- a/app/views/user/_change_receive_email.rhtml
+++ b/app/views/user/_change_receive_email.html.erb
@@ -1,4 +1,4 @@
-<% form_tag(:controller=>"user", :action=>"set_receive_email_alerts") do %>
+<%= form_tag(:controller=>"user", :action=>"set_receive_email_alerts") do %>
<div>
<% if @user.receive_email_alerts %>
<%= _('You are currently receiving notification of new activity on your wall by email.', :wall_url => show_user_wall_path) %><br><br>
diff --git a/app/views/user/_show_user_info.rhtml b/app/views/user/_show_user_info.html.erb
index 305300236..305300236 100644
--- a/app/views/user/_show_user_info.rhtml
+++ b/app/views/user/_show_user_info.html.erb
diff --git a/app/views/user/_signin.rhtml b/app/views/user/_signin.html.erb
index 7db07e4b4..afc55d249 100644
--- a/app/views/user/_signin.rhtml
+++ b/app/views/user/_signin.html.erb
@@ -1,6 +1,6 @@
<div id="signin">
-<% form_tag({:action => "signin"}, {:id => "signin_form"}) do %>
+<%= form_tag({:action => "signin"}, {:id => "signin_form"}) do %>
<%= foi_error_messages_for :user_signin %>
<!--<% if not sign_in_as_existing_user %>
diff --git a/app/views/user/_signup.rhtml b/app/views/user/_signup.html.erb
index 89ab19b7e..ac4fd3e10 100644
--- a/app/views/user/_signup.rhtml
+++ b/app/views/user/_signup.html.erb
@@ -1,6 +1,6 @@
<div id="signup">
-<% form_tag({:action => "signup"}, {:id => "signup_form"}) do %>
+<%= form_tag({:action => "signup"}, {:id => "signup_form"}) do %>
<%= foi_error_messages_for :user_signup %>
<!--<h2><%= _('If you\'re new to {{site_name}}', :site_name=>site_name)%></h2>-->
diff --git a/app/views/user/_user_listing_single.rhtml b/app/views/user/_user_listing_single.html.erb
index ed1b95718..ed1b95718 100644
--- a/app/views/user/_user_listing_single.rhtml
+++ b/app/views/user/_user_listing_single.html.erb
diff --git a/app/views/user/bad_token.rhtml b/app/views/user/bad_token.html.erb
index 538bc5606..538bc5606 100644
--- a/app/views/user/bad_token.rhtml
+++ b/app/views/user/bad_token.html.erb
diff --git a/app/views/user/banned.rhtml b/app/views/user/banned.html.erb
index 475c10977..475c10977 100644
--- a/app/views/user/banned.rhtml
+++ b/app/views/user/banned.html.erb
diff --git a/app/views/user/confirm.rhtml b/app/views/user/confirm.html.erb
index bc70a1f36..bc70a1f36 100644
--- a/app/views/user/confirm.rhtml
+++ b/app/views/user/confirm.html.erb
diff --git a/app/views/user/contact.rhtml b/app/views/user/contact.html.erb
index 333b72334..6d23dd1ed 100644
--- a/app/views/user/contact.rhtml
+++ b/app/views/user/contact.html.erb
@@ -6,7 +6,7 @@
<%= foi_error_messages_for :contact %>
-<% form_for :contact do |f| %>
+<%= form_for :contact do |f| %>
<div class="form_note">
<h1><%= _("Contact {{recipient}}", :recipient => h(@recipient_user.name)) %></h1>
diff --git a/app/views/user/no_cookies.rhtml b/app/views/user/no_cookies.html.erb
index c291367f2..c291367f2 100644
--- a/app/views/user/no_cookies.rhtml
+++ b/app/views/user/no_cookies.html.erb
diff --git a/app/views/user/rate_limited.rhtml b/app/views/user/rate_limited.html.erb
index d52deebab..54a4e0461 100644
--- a/app/views/user/rate_limited.rhtml
+++ b/app/views/user/rate_limited.html.erb
@@ -2,7 +2,7 @@
<h1><%=@title%></h1>
-<p><%= _("You have hit the rate limit on new requests. Users are ordinarily limited to {{max_requests_per_user_per_day}} requests in any rolling 24-hour period. You will be able to make another request in {{can_make_another_request}}.", :max_requests_per_user_per_day => Configuration::max_requests_per_user_per_day, :can_make_another_request => distance_of_time_in_words(Time.now, @next_request_permitted_at))%></p>
+<p><%= _("You have hit the rate limit on new requests. Users are ordinarily limited to {{max_requests_per_user_per_day}} requests in any rolling 24-hour period. You will be able to make another request in {{can_make_another_request}}.", :max_requests_per_user_per_day => AlaveteliConfiguration::max_requests_per_user_per_day, :can_make_another_request => distance_of_time_in_words(Time.now, @next_request_permitted_at))%></p>
<p><%= _("There is a limit on the number of requests you can make in a day, because we don’t want public authorities to be bombarded with large numbers of inappropriate requests. If you feel you have a good reason to ask for the limit to be lifted in your case, please <a href='{{help_contact_path}}'>get in touch</a>.", :help_contact_path => help_contact_path) %></p>
diff --git a/app/views/user/river.rhtml b/app/views/user/river.html.erb
index 9618e0aa8..9618e0aa8 100644
--- a/app/views/user/river.rhtml
+++ b/app/views/user/river.html.erb
diff --git a/app/views/user/set_crop_profile_photo.rhtml b/app/views/user/set_crop_profile_photo.html.erb
index eed0304d2..fea7ccab8 100644
--- a/app/views/user/set_crop_profile_photo.rhtml
+++ b/app/views/user/set_crop_profile_photo.html.erb
@@ -9,7 +9,7 @@
<div id="set_crop_profile_photo">
-<% form_tag 'set_photo', :id => 'set_crop_profile_photo_form', :multipart => true do %>
+<%= form_tag 'set_photo', :id => 'set_crop_profile_photo_form', :multipart => true do %>
<table>
<tr>
diff --git a/app/views/user/set_draft_profile_photo.rhtml b/app/views/user/set_draft_profile_photo.html.erb
index 757498249..b4bdd80f3 100644
--- a/app/views/user/set_draft_profile_photo.rhtml
+++ b/app/views/user/set_draft_profile_photo.html.erb
@@ -8,7 +8,7 @@
<div id="set_draft_profile_photo">
-<% form_tag 'set_photo', :id => 'set_draft_profile_photo_form', :multipart => true do %>
+<%= form_tag 'set_photo', :id => 'set_draft_profile_photo_form', :multipart => true do %>
<p>
<label class="form_label" for="file_1"><%= _('Photo of you:')%></label>
<%= file_field_tag :file, :size => 35, :id => 'file_1' %>
@@ -45,7 +45,7 @@
<h2><%= _('OR remove the existing photo')%></h2>
- <% form_tag 'clear_photo', :id => 'clear_profile_photo_form', :multipart => true do %>
+ <%= form_tag 'clear_photo', :id => 'clear_profile_photo_form', :multipart => true do %>
<%= submit_tag _("Clear photo") %>
<% end %>
diff --git a/app/views/user/set_profile_about_me.rhtml b/app/views/user/set_profile_about_me.html.erb
index 4fe1047da..fb7de7e97 100644
--- a/app/views/user/set_profile_about_me.rhtml
+++ b/app/views/user/set_profile_about_me.html.erb
@@ -4,7 +4,7 @@
<%= foi_error_messages_for :about_me %>
-<% form_for :about_me do |f| %>
+<%= form_for :about_me do |f| %>
<div class="form_note">
<h1><%= _('Edit text about you')%></h1>
<p>
@@ -26,7 +26,7 @@
<%= _(' Include relevant links, such as to a campaign page, your blog or a
twitter account. They will be made clickable.
e.g.')%>
- <a href="https://twitter.com/<%= Configuration::twitter_username %>">https://twitter.com/<%= Configuration::twitter_username %></a>
+ <a href="https://twitter.com/<%= AlaveteliConfiguration::twitter_username %>">https://twitter.com/<%= AlaveteliConfiguration::twitter_username %></a>
</p>
</div>
diff --git a/app/views/user/show.rhtml b/app/views/user/show.html.erb
index a3dea619d..b92ffcff2 100644
--- a/app/views/user/show.rhtml
+++ b/app/views/user/show.html.erb
@@ -97,7 +97,7 @@
<% if not @is_you %>
<p id="user_not_logged_in">
- <%= raw(_('<a href="%s">Sign in</a> to change password, subscriptions and more ({{user_name}} only)',:user_name=>h(@display_user.name)) % [signin_url(:r => request.request_uri)]) %>
+ <%= raw(_('<a href="%s">Sign in</a> to change password, subscriptions and more ({{user_name}} only)',:user_name=>h(@display_user.name)) % [signin_url(:r => request.fullpath)]) %>
</p>
<% end %>
</div>
@@ -107,7 +107,7 @@
<% if @show_requests %>
<div id="user_profile_search">
- <% form_tag(show_user_url, :method => "get", :id=>"search_form") do %>
+ <%= form_tag(show_user_url, :method => "get", :id=>"search_form") do %>
<div>
<%= text_field_tag(:user_query, params[:user_query], {:title => "type your search term here" }) %>
<% if @is_you %>
@@ -181,12 +181,12 @@
<p><%= _("You're not following anything.")%></p>
<% else %>
<% if @track_things_grouped.size == 1 %>
- <% form_tag({:controller => 'track', :action => 'delete_all_type'}, :class => "feed_form") do %>
+ <%= form_tag({:controller => 'track', :action => 'delete_all_type'}, :class => "feed_form") do %>
<h3>
<%=TrackThing.track_type_description(@track_things[0].track_type)%>
<%= hidden_field_tag 'track_type', @track_things[0].track_type %>
<%= hidden_field_tag 'user', @display_user.id %>
- <%= hidden_field_tag 'r', request.request_uri %>
+ <%= hidden_field_tag 'r', request.fullpath %>
<% if @track_things.size > 1 %>
<%= submit_tag _('unsubscribe all') %>
<% end %>
@@ -195,12 +195,12 @@
<% end %>
<% for track_type, track_things in @track_things_grouped %>
<% if @track_things_grouped.size > 1 %>
- <% form_tag({:controller => 'track', :action => 'delete_all_type'}, :class => "feed_form") do %>
+ <%= form_tag({:controller => 'track', :action => 'delete_all_type'}, :class => "feed_form") do %>
<h3>
<%=TrackThing.track_type_description(track_type)%>
<%= hidden_field_tag 'track_type', track_type %>
<%= hidden_field_tag 'user', @display_user.id %>
- <%= hidden_field_tag 'r', request.request_uri %>
+ <%= hidden_field_tag 'r', request.fullpath %>
<% if track_things.size > 1 %>
<%= submit_tag _('unsubscribe all')%>
<% end %>
@@ -211,11 +211,11 @@
<ul>
<% for track_thing in track_things %>
<li>
- <% form_tag({:controller => 'track', :action => 'update', :track_id => track_thing.id}, :class => "feed_form") do %>
+ <%= form_tag({:controller => 'track', :action => 'update', :track_id => track_thing.id}, :class => "feed_form") do %>
<div>
<%= track_thing.params[:list_description] %>
<%= hidden_field_tag 'track_medium', "delete", { :id => 'track_medium_' + track_thing.id.to_s } %>
- <%= hidden_field_tag 'r', request.request_uri, { :id => 'r_' + track_thing.id.to_s } %>
+ <%= hidden_field_tag 'r', request.fullpath, { :id => 'r_' + track_thing.id.to_s } %>
<%= submit_tag _('unsubscribe') %>
</div>
<% end %>
diff --git a/app/views/user/sign.rhtml b/app/views/user/sign.html.erb
index 5e8cced91..8291cdace 100644
--- a/app/views/user/sign.rhtml
+++ b/app/views/user/sign.html.erb
@@ -12,7 +12,7 @@
<% end %>
</p>
<% if @post_redirect.post_params["controller"] == "admin_general" %>
- <% unless Configuration::disable_emergency_user %>
+ <% unless AlaveteliConfiguration::disable_emergency_user %>
<p id="superuser_message">Don't have a superuser account yet? <%= link_to "Sign in as the emergency user", @post_redirect.uri + "?emergency=1" %></p>
<% end %>
<% end %>
diff --git a/app/views/user/signchangeemail.rhtml b/app/views/user/signchangeemail.html.erb
index 0f8b76bc5..7308179f4 100644
--- a/app/views/user/signchangeemail.rhtml
+++ b/app/views/user/signchangeemail.html.erb
@@ -4,7 +4,7 @@
<div id="change_email">
-<% form_tag({:action => "signchangeemail"}, {:id => "signchangeemail_form"}) do %>
+<%= form_tag({:action => "signchangeemail"}, {:id => "signchangeemail_form"}) do %>
<%= foi_error_messages_for :signchangeemail %>
<div class="form_note">
diff --git a/app/views/user/signchangeemail_confirm.rhtml b/app/views/user/signchangeemail_confirm.html.erb
index bfedbac2d..bfedbac2d 100644
--- a/app/views/user/signchangeemail_confirm.rhtml
+++ b/app/views/user/signchangeemail_confirm.html.erb
diff --git a/app/views/user/signchangepassword.rhtml b/app/views/user/signchangepassword.html.erb
index edb980b9f..51bcb466d 100644
--- a/app/views/user/signchangepassword.rhtml
+++ b/app/views/user/signchangepassword.html.erb
@@ -4,7 +4,7 @@
<div id="change_password">
-<% form_tag({:action => "signchangepassword"}, {:id => "signchangepassword_form"}) do %>
+<%= form_tag({:action => "signchangepassword"}, {:id => "signchangepassword_form"}) do %>
<%= foi_error_messages_for :user %>
<div class="form_note">
diff --git a/app/views/user/signchangepassword_confirm.rhtml b/app/views/user/signchangepassword_confirm.html.erb
index 63b6515cd..63b6515cd 100644
--- a/app/views/user/signchangepassword_confirm.rhtml
+++ b/app/views/user/signchangepassword_confirm.html.erb
diff --git a/app/views/user/signchangepassword_send_confirm.rhtml b/app/views/user/signchangepassword_send_confirm.html.erb
index 84ee28f07..850237c34 100644
--- a/app/views/user/signchangepassword_send_confirm.rhtml
+++ b/app/views/user/signchangepassword_send_confirm.html.erb
@@ -2,7 +2,7 @@
<div id="change_password">
-<% form_tag({:action => "signchangepassword"}, {:id => "signchangepassword_form"}) do %>
+<%= form_tag({:action => "signchangepassword"}, {:id => "signchangepassword_form"}) do %>
<%= foi_error_messages_for :signchangepassword %>
<div class="form_note">
diff --git a/app/views/user/signin_successful.rhtml b/app/views/user/signin_successful.html.erb
index 675701d74..675701d74 100644
--- a/app/views/user/signin_successful.rhtml
+++ b/app/views/user/signin_successful.html.erb
diff --git a/app/views/user/wall.rhtml b/app/views/user/wall.html.erb
index 190cc0a6d..190cc0a6d 100644
--- a/app/views/user/wall.rhtml
+++ b/app/views/user/wall.html.erb
diff --git a/app/views/user/wrong_user.rhtml b/app/views/user/wrong_user.html.erb
index 30256a639..30256a639 100644
--- a/app/views/user/wrong_user.rhtml
+++ b/app/views/user/wrong_user.html.erb
diff --git a/app/views/user/wrong_user_unknown_email.rhtml b/app/views/user/wrong_user_unknown_email.html.erb
index c59c56941..c59c56941 100644
--- a/app/views/user/wrong_user_unknown_email.rhtml
+++ b/app/views/user/wrong_user_unknown_email.html.erb
diff --git a/app/views/user_mailer/already_registered.rhtml b/app/views/user_mailer/already_registered.text.erb
index 32c2c7e63..32c2c7e63 100644
--- a/app/views/user_mailer/already_registered.rhtml
+++ b/app/views/user_mailer/already_registered.text.erb
diff --git a/app/views/user_mailer/changeemail_already_used.rhtml b/app/views/user_mailer/changeemail_already_used.text.erb
index 1d74dda35..1d74dda35 100644
--- a/app/views/user_mailer/changeemail_already_used.rhtml
+++ b/app/views/user_mailer/changeemail_already_used.text.erb
diff --git a/app/views/user_mailer/changeemail_confirm.rhtml b/app/views/user_mailer/changeemail_confirm.text.erb
index c73e9486b..c73e9486b 100644
--- a/app/views/user_mailer/changeemail_confirm.rhtml
+++ b/app/views/user_mailer/changeemail_confirm.text.erb
diff --git a/app/views/user_mailer/confirm_login.rhtml b/app/views/user_mailer/confirm_login.text.erb
index fa86dc2b1..fa86dc2b1 100644
--- a/app/views/user_mailer/confirm_login.rhtml
+++ b/app/views/user_mailer/confirm_login.text.erb
diff --git a/config.ru b/config.ru
index 30b00bfa1..74748fd45 100644
--- a/config.ru
+++ b/config.ru
@@ -1,2 +1,4 @@
-require File.dirname(__FILE__) + '/config/environment'
-run ActionController::Dispatcher.new
+# This file is used by Rack-based servers to start the application.
+
+require ::File.expand_path('../config/environment', __FILE__)
+run Alaveteli::Application
diff --git a/config/application.rb b/config/application.rb
new file mode 100644
index 000000000..f5b525a36
--- /dev/null
+++ b/config/application.rb
@@ -0,0 +1,72 @@
+require File.expand_path('../boot', __FILE__)
+
+require 'rails/all'
+
+require File.dirname(__FILE__) + '/../lib/configuration'
+
+# If you have a Gemfile, require the gems listed there, including any gems
+# you've limited to :test, :development, or :production.
+Bundler.require(:default, Rails.env) if defined?(Bundler)
+
+module Alaveteli
+ class Application < Rails::Application
+ # Settings in config/environments/* take precedence over those specified here.
+ # Application configuration should go into files in config/initializers
+ # -- all .rb files in that directory are automatically loaded.
+
+ # Custom directories with classes and modules you want to be autoloadable.
+ # config.autoload_paths += %W(#{config.root}/extras)
+
+ # Only load the plugins named here, in the order given (default is alphabetical).
+ # :all can be used as a placeholder for all plugins not explicitly named.
+ # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
+
+ # Activate observers that should always be running.
+ # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
+
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
+ # config.time_zone = 'Central Time (US & Canada)'
+
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
+ # config.i18n.default_locale = :de
+
+ # JavaScript files you want as :defaults (application.js is always included).
+ # config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
+
+ # Configure the default encoding used in templates for Ruby 1.9.
+ config.encoding = "utf-8"
+
+ # Configure sensitive parameters which will be filtered from the log file.
+ config.filter_parameters += [:password]
+
+ # Use SQL instead of Active Record's schema dumper when creating the test database.
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
+ # like if you have constraints or database-specific column types
+ config.active_record.schema_format = :sql
+
+ # Make Active Record use UTC-base instead of local time
+ config.active_record.default_timezone = :utc
+
+ # This is the timezone that times and dates are displayed in
+ # Note that having set a zone, the Active Record
+ # time_zone_aware_attributes flag is on, so times from models
+ # will be in this time zone
+ config.time_zone = ::AlaveteliConfiguration::time_zone
+
+ config.after_initialize do
+ require 'routing_filters.rb'
+ end
+
+ config.autoload_paths << "#{Rails.root.to_s}/lib/mail_handler"
+
+ # See Rails::Configuration for more options
+ ENV['RECAPTCHA_PUBLIC_KEY'] = ::AlaveteliConfiguration::recaptcha_public_key
+ ENV['RECAPTCHA_PRIVATE_KEY'] = ::AlaveteliConfiguration::recaptcha_private_key
+
+ # Insert a bit of middleware code to prevent uneeded cookie setting.
+ require "#{Rails.root}/lib/whatdotheyknow/strip_empty_sessions"
+ config.middleware.insert_before ActionDispatch::Session::CookieStore, WhatDoTheyKnow::StripEmptySessions, :key => '_wdtk_cookie_session', :path => "/", :httponly => true
+ end
+end
diff --git a/config/boot.rb b/config/boot.rb
index 906a2bace..a810be358 100644
--- a/config/boot.rb
+++ b/config/boot.rb
@@ -1,135 +1,15 @@
-# Don't change this file!
-# Configure your app in config/environment.rb and config/environments/*.rb
+require 'rubygems'
-# Hmmm, that's a bit daft - 'production' needs setting not only in the web
-# server, it also needs setting in all the scripts, so a central place seems
-# better. Look for a config/rails_env file, and read stuff from there if
+# Set up gems listed in the Gemfile.
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
+
+require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
+
+# TODO: Remove this. This is a hacky system for having a default environment.
+# It looks for a config/rails_env.rb file, and reads stuff from there if
# it exists. Put just a line like this in there:
# ENV['RAILS_ENV'] = 'production'
rails_env_file = File.expand_path(File.join(File.dirname(__FILE__), 'rails_env.rb'))
if File.exists?(rails_env_file)
require rails_env_file
end
-
-RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
-
-module Rails
- class << self
- def boot!
- unless booted?
- preinitialize
- pick_boot.run
- end
- end
-
- def booted?
- defined? Rails::Initializer
- end
-
- def pick_boot
- (vendor_rails? ? VendorBoot : GemBoot).new
- end
-
- def vendor_rails?
- File.exist?("#{RAILS_ROOT}/vendor/rails/Rakefile")
- end
-
- def preinitialize
- load(preinitializer_path) if File.exist?(preinitializer_path)
- end
-
- def preinitializer_path
- "#{RAILS_ROOT}/config/preinitializer.rb"
- end
- end
-
- class Boot
- def run
- load_initializer
-
- Rails::Initializer.class_eval do
- def load_gems
- @bundler_loaded ||= Bundler.require :default, Rails.env
- end
- end
-
- Rails::Initializer.run(:set_load_path)
- end
- end
-
- class VendorBoot < Boot
- def load_initializer
- require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
- Rails::Initializer.run(:install_gem_spec_stubs)
- Rails::GemDependency.add_frozen_gem_path
- end
- end
-
- class GemBoot < Boot
- def load_initializer
- self.class.load_rubygems
- load_rails_gem
- require 'initializer'
- end
-
- def load_rails_gem
- if version = self.class.gem_version
- gem 'rails', version
- else
- gem 'rails'
- end
- rescue Gem::LoadError => load_error
- if load_error.message =~ /Could not find RubyGem rails/
- STDERR.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
- exit 1
- else
- raise
- end
- end
-
- class << self
- def rubygems_version
- Gem::RubyGemsVersion rescue nil
- end
-
- def gem_version
- if defined? RAILS_GEM_VERSION
- RAILS_GEM_VERSION
- elsif ENV.include?('RAILS_GEM_VERSION')
- ENV['RAILS_GEM_VERSION']
- else
- parse_gem_version(read_environment_rb)
- end
- end
-
- def load_rubygems
- min_version = '1.3.2'
- require 'rubygems'
-
- unless rubygems_version >= min_version
- $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
- exit 1
- end
-
- rescue LoadError
- $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
- exit 1
- end
-
- def parse_gem_version(text)
- $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
- end
-
- private
- def read_environment_rb
- File.read("#{RAILS_ROOT}/config/environment.rb")
- end
- end
- end
-end
-
-
-
-# All that for this:
-Rails.boot!
-
diff --git a/config/crontab.ugly b/config/crontab.ugly
index ef3455113..d33450df4 100644
--- a/config/crontab.ugly
+++ b/config/crontab.ugly
@@ -2,7 +2,7 @@
# Timed tasks for FOI site. Template file.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org. WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org. WWW: http://www.mysociety.org/
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=cron-!!(*= $site *)!!@mysociety.org
diff --git a/config/deploy.yml.example b/config/deploy.yml.example
index aea045dff..61931e50e 100644
--- a/config/deploy.yml.example
+++ b/config/deploy.yml.example
@@ -1,12 +1,12 @@
# Site-specific deployment configuration lives in this file
production:
- repository: git://github.com:mysociety/alaveteli.git
+ repository: git://github.com/mysociety/alaveteli.git
branch: master
server: www.example.com
user: deploy
deploy_to: /srv/www/alaveteli_production
staging:
- repository: git://github.com:mysociety/alaveteli.git
+ repository: git://github.com/mysociety/alaveteli.git
branch: develop
server: test.example.com
user: deploy
diff --git a/config/environment.rb b/config/environment.rb
index 8a5c7a605..196680b23 100644
--- a/config/environment.rb
+++ b/config/environment.rb
@@ -1,154 +1,5 @@
-# Be sure to restart your web server when you modify this file.
-if RUBY_VERSION.to_f >= 1.9
- # the default encoding for IO is utf-8, and we use utf-8 internally
- Encoding.default_external = Encoding.default_internal = Encoding::UTF_8
- # Suppress warning messages and require inflector to avoid iconv deprecation message
- # "iconv will be deprecated in the future, use String#encode instead." when loading
- # it as part of rails
- original_verbose, $VERBOSE = $VERBOSE, nil
- require 'active_support/inflector'
- # Activate warning messages again.
- $VERBOSE = original_verbose
- require 'yaml'
- YAML::ENGINE.yamler = "syck"
-end
+# Load the rails application
+require File.expand_path('../application', __FILE__)
-# Uncomment below to force Rails into production mode when
-# you don't control web/app server and can't set it the proper way
-# ENV['RAILS_ENV'] ||= 'production'
-
-# Specifies gem version of Rails to use when vendor/rails is not present
-RAILS_GEM_VERSION = '2.3.18' unless defined? RAILS_GEM_VERSION
-
-# Bootstrap the Rails environment, frameworks, and default configuration
-require File.join(File.dirname(__FILE__), 'boot')
-
-# MySociety specific helper functions
-$:.push(File.join(File.dirname(__FILE__), '../commonlib/rblib'))
-# ... if these fail to include, you need the commonlib submodule from git
-# (type "git submodule update --init" in the whatdotheyknow directory)
-
-$:.unshift(File.join(File.dirname(__FILE__), '../vendor/plugins/globalize2/lib'))
-
-load "validate.rb"
-load "config.rb"
-load "format.rb"
-load "debug_helpers.rb"
-load "util.rb"
-# Patch Rails::GemDependency to cope with older versions of rubygems, e.g. in Debian Lenny
-# Restores override removed in https://github.com/rails/rails/commit/c20a4d18e36a13b5eea3155beba36bb582c0cc87
-# without effecting method behaviour
-# and adds fallback gem call removed in https://github.com/rails/rails/commit/4c3725723f15fab0a424cb1318b82b460714b72f
-require File.join(File.dirname(__FILE__), '../lib/old_rubygems_patch')
-require 'configuration'
-
-# Application version
-ALAVETELI_VERSION = '0.8'
-
-Rails::Initializer.run do |config|
- # Load intial mySociety config
- if ENV["RAILS_ENV"] == "test"
- MySociety::Config.set_file(File.join(config.root_path, 'config', 'test'), true)
- else
- MySociety::Config.set_file(File.join(config.root_path, 'config', 'general'), true)
- end
- MySociety::Config.load_default
-
- # Settings in config/environments/* take precedence over those specified here
-
- # Skip frameworks you're not going to use (only works if using vendor/rails)
- # config.frameworks -= [ :action_web_service, :action_mailer ]
-
- # Only load the plugins named here, by default all plugins in vendor/plugins are loaded
- # config.plugins = %W( exception_notification ssl_requirement )
-
- # Add additional load paths for your own custom dirs
- # config.load_paths += %W( #{Rails.root}/extras )
-
- # Force all environments to use the same logger level
- # (by default production uses :info, the others :debug)
- # TEMP: uncomment this to turn on logging in production environments
- # config.log_level = :debug
- #
- # Specify gems that this application depends on and have them installed with rake gems:install
- #GettextI18nRails.translations_are_html_safe = true
-
- # Use SQL instead of Active Record's schema dumper when creating the test database.
- # This is necessary if your schema can't be completely dumped by the schema dumper,
- # like if you have constraints or database-specific column types
- config.active_record.schema_format = :sql
-
- # Activate observers that should always be running
- # config.active_record.observers = :cacher, :garbage_collector
-
- # Make Active Record use UTC-base instead of local time
- config.active_record.default_timezone = :utc
-
- # This is the timezone that times and dates are displayed in
- # Note that having set a zone, the Active Record
- # time_zone_aware_attributes flag is on, so times from models
- # will be in this time zone
- config.time_zone = Configuration::time_zone
-
- config.after_initialize do
- require 'routing_filters.rb'
- end
-
- config.autoload_paths << "#{RAILS_ROOT}/lib/mail_handler"
-
- # See Rails::Configuration for more options
- ENV['RECAPTCHA_PUBLIC_KEY'] = Configuration::recaptcha_public_key
- ENV['RECAPTCHA_PRIVATE_KEY'] = Configuration::recaptcha_private_key
-end
-
-# Add new inflection rules using the following format
-# (all these examples are active by default):
-# Inflector.inflections do |inflect|
-# inflect.plural /^(ox)$/i, '\1en'
-# inflect.singular /^(ox)en/i, '\1'
-# inflect.irregular 'person', 'people'
-# inflect.uncountable %w( fish sheep )
-# end
-
-# Add new mime types for use in respond_to blocks:
-# Mime::Type.register "text/richtext", :rtf
-# Mime::Type.register "application/x-mobile", :mobile
-
-# Domain for URLs (so can work for scripts, not just web pages)
-ActionMailer::Base.default_url_options[:host] = Configuration::domain
-if Configuration::force_ssl
- ActionMailer::Base.default_url_options[:protocol] = "https"
-end
-
-# fallback locale and available locales
-available_locales = Configuration::available_locales.split(/ /)
-default_locale = Configuration::default_locale
-
-FastGettext.default_available_locales = available_locales
-I18n.locale = default_locale
-I18n.available_locales = available_locales.map {|locale_name| locale_name.to_sym}
-I18n.default_locale = default_locale
-
-# Customise will_paginate URL generation
-WillPaginate::ViewHelpers.pagination_options[:renderer] = 'WillPaginateExtension::LinkRenderer'
-
-# Load monkey patches and other things from lib/
-require 'ruby19.rb'
-require 'activesupport_cache_extensions.rb'
-require 'timezone_fixes.rb'
-require 'use_spans_for_errors.rb'
-require 'activerecord_errors_extensions.rb'
-require 'willpaginate_extension.rb'
-require 'sendmail_return_path.rb'
-require 'i18n_fixes.rb'
-require 'rack_quote_monkeypatch.rb'
-require 'world_foi_websites.rb'
-require 'alaveteli_external_command.rb'
-require 'quiet_opener.rb'
-require 'mail_handler'
-require "cookie_store_with_line_break_fix"
-
-if !Configuration.exception_notifications_from.blank? && !Configuration.exception_notifications_to.blank?
- ExceptionNotification::Notifier.sender_address = Configuration::exception_notifications_from
- ExceptionNotification::Notifier.exception_recipients = Configuration::exception_notifications_to
-end
+# Initialize the rails application
+Alaveteli::Application.initialize!
diff --git a/config/environments/development.rb b/config/environments/development.rb
index c43cdb049..54ab2977f 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -1,29 +1,30 @@
-# Settings specified here will take precedence over those in config/environment.rb
+Alaveteli::Application.configure do
+ # Settings specified here will take precedence over those in config/environment.rb
-config.log_level = :info
+ # In the development environment your application's code is reloaded on
+ # every request. This slows down response time but is perfect for development
+ # since you don't have to restart the webserver when you make code changes.
+ config.cache_classes = false
-# In the development environment your application's code is reloaded on
-# every request. This slows down response time but is perfect for development
-# since you don't have to restart the webserver when you make code changes.
-config.cache_classes = false
+ # Log error messages when you accidentally call methods on nil.
+ config.whiny_nils = true
-# Log error messages when you accidentally call methods on nil.
-config.whiny_nils = true
+ # Show full error reports and disable caching
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
-# Show full error reports and disable caching
-config.action_controller.consider_all_requests_local = true
-config.action_controller.perform_caching = false
-config.action_view.debug_rjs = true
+ # Don't care if the mailer can't send
+ config.action_mailer.raise_delivery_errors = false
+ config.action_mailer.perform_deliveries = true
+ # Use mailcatcher in development
+ config.action_mailer.delivery_method = :smtp # so is queued, rather than giving immediate errors
+ config.action_mailer.smtp_settings = { :address => "localhost", :port => 1025 }
-# Don't care if the mailer can't send
-config.action_mailer.raise_delivery_errors = false
-config.action_mailer.perform_deliveries = true
-# Use mailcatcher in development
-config.action_mailer.delivery_method = :smtp # so is queued, rather than giving immediate errors
-config.action_mailer.smtp_settings = { :address => "localhost", :port => 1025 }
+ # Writes useful log files to debug memory leaks, of the sort where have
+ # unintentionally kept references to objects, especially strings.
+ # require 'memory_profiler'
+ # MemoryProfiler.start :string_debug => true, :delay => 10
-
-# Writes useful log files to debug memory leaks, of the sort where have
-# unintentionally kept references to objects, especially strings.
-# require 'memory_profiler'
-# MemoryProfiler.start :string_debug => true, :delay => 10
+ # Print deprecation notices to the Rails logger
+ config.active_support.deprecation = :log
+end
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 097944196..0c1929366 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -1,26 +1,34 @@
-# Settings specified here will take precedence over those in config/environment.rb
+Alaveteli::Application.configure do
+ # Settings specified here will take precedence over those in config/environment.rb
-# The production environment is meant for finished, "live" apps.
-# Code is not reloaded between requests
-config.cache_classes = true
+ # The production environment is meant for finished, "live" apps.
+ # Code is not reloaded between requests
+ config.cache_classes = true
-# Use a different logger for distributed setups
-# config.logger = SyslogLogger.new
+ # Use a different logger for distributed setups
+ # config.logger = SyslogLogger.new
-# Full error reports are disabled and caching is turned on
-config.action_controller.consider_all_requests_local = false
-config.action_controller.perform_caching = true
+ # Full error reports are disabled and caching is turned on
+ config.consider_all_requests_local = false
+ config.action_controller.perform_caching = true
-# Enable serving of images, stylesheets, and javascripts from an asset server
-# config.action_controller.asset_host = "http://assets.example.com"
+ # Enable serving of images, stylesheets, and javascripts from an asset server
+ # config.action_controller.asset_host = "http://assets.example.com"
-# Disable delivery errors, bad email addresses will be ignored
-# config.action_mailer.raise_delivery_errors = false
-config.action_mailer.delivery_method = :sendmail # so is queued, rather than giving immediate errors
+ # Disable delivery errors, bad email addresses will be ignored
+ # config.action_mailer.raise_delivery_errors = false
+ config.action_mailer.delivery_method = :sendmail # so is queued, rather than giving immediate errors
-require 'rack/ssl'
-if ::Configuration::force_ssl
- config.middleware.insert_after ActionController::Failsafe, ::Rack::SSL
- # For Rails 3.x this will need to change to
- #config.middleware.insert_before ActionDispatch::Cookies, ::Rack::SSL
+ config.active_support.deprecation = :notify
+
+ if !AlaveteliConfiguration.exception_notifications_from.blank? && !AlaveteliConfiguration.exception_notifications_to.blank?
+ middleware.use ExceptionNotifier,
+ :sender_address => AlaveteliConfiguration::exception_notifications_from,
+ :exception_recipients => AlaveteliConfiguration::exception_notifications_to
+ end
+
+ require 'rack/ssl'
+ if AlaveteliConfiguration::force_ssl
+ config.middleware.insert_before ActionDispatch::Cookies, ::Rack::SSL
+ end
end
diff --git a/config/environments/staging.rb b/config/environments/staging.rb
index 84a8f5965..0bb0db71a 100644
--- a/config/environments/staging.rb
+++ b/config/environments/staging.rb
@@ -1,19 +1,21 @@
-# Settings specified here will take precedence over those in config/environment.rb
+Alaveteli::Application.configure do
+ # Settings specified here will take precedence over those in config/environment.rb
-# The production environment is meant for finished, "live" apps.
-# Code is not reloaded between requests
-config.cache_classes = true
+ # The production environment is meant for finished, "live" apps.
+ # Code is not reloaded between requests
+ config.cache_classes = true
-# Use a different logger for distributed setups
-# config.logger = SyslogLogger.new
+ # Use a different logger for distributed setups
+ # config.logger = SyslogLogger.new
-# Full error reports are disabled and caching is turned on
-config.action_controller.consider_all_requests_local = false
-config.action_controller.perform_caching = true
+ # Full error reports are disabled and caching is turned on
+ config.action_controller.consider_all_requests_local = false
+ config.action_controller.perform_caching = true
-# Enable serving of images, stylesheets, and javascripts from an asset server
-# config.action_controller.asset_host = "http://assets.example.com"
+ # Enable serving of images, stylesheets, and javascripts from an asset server
+ # config.action_controller.asset_host = "http://assets.example.com"
-# Disable delivery errors, bad email addresses will be ignored
-# config.action_mailer.raise_delivery_errors = false
-config.action_mailer.delivery_method = :sendmail # so is queued, rather than giving immediate errors
+ # Disable delivery errors, bad email addresses will be ignored
+ # config.action_mailer.raise_delivery_errors = false
+ config.action_mailer.delivery_method = :sendmail # so is queued, rather than giving immediate errors
+end
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 784ea18d3..df39e8873 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -1,25 +1,27 @@
-# Settings specified here will take precedence over those in config/environment.rb
+Alaveteli::Application.configure do
+ # Settings specified here will take precedence over those in config/environment.rb
-require 'patches/fixtures_constraint_disabling'
+ # The test environment is used exclusively to run your application's
+ # test suite. You never need to work with it otherwise. Remember that
+ # your test database is "scratch space" for the test suite and is wiped
+ # and recreated between test runs. Don't rely on the data there!
+ config.cache_classes = true
-# The test environment is used exclusively to run your application's
-# test suite. You never need to work with it otherwise. Remember that
-# your test database is "scratch space" for the test suite and is wiped
-# and recreated between test runs. Don't rely on the data there!
-config.cache_classes = true
+ # Log error messages when you accidentally call methods on nil.
+ config.whiny_nils = true
-# Log error messages when you accidentally call methods on nil.
-config.whiny_nils = true
+ # Show full error reports and disable caching
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
-# Show full error reports and disable caching
-config.action_controller.consider_all_requests_local = true
-config.action_controller.perform_caching = false
+ # Tell ActionMailer not to deliver emails to the real world.
+ # The :test delivery method accumulates sent emails in the
+ # ActionMailer::Base.deliveries array.
+ config.action_mailer.delivery_method = :test
-# Tell ActionMailer not to deliver emails to the real world.
-# The :test delivery method accumulates sent emails in the
-# ActionMailer::Base.deliveries array.
-config.action_mailer.delivery_method = :test
-
-# Disable request forgery protection in test environment
-config.action_controller.allow_forgery_protection = false
+ # Disable request forgery protection in test environment
+ config.action_controller.allow_forgery_protection = false
+ # Print deprecation notices to the stderr
+ config.active_support.deprecation = :stderr
+end
diff --git a/config/httpd.conf b/config/httpd.conf
index acf37d97c..e468a1e96 100644
--- a/config/httpd.conf
+++ b/config/httpd.conf
@@ -4,7 +4,7 @@
# Ruby on Rails application.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org
# This is needed for the PHP spell checker
<Location /fcgi>
diff --git a/config/initializers/alaveteli.rb b/config/initializers/alaveteli.rb
new file mode 100644
index 000000000..06d05563b
--- /dev/null
+++ b/config/initializers/alaveteli.rb
@@ -0,0 +1,61 @@
+# MySociety specific helper functions
+$:.push(File.join(File.dirname(__FILE__), '../../commonlib/rblib'))
+# ... if these fail to include, you need the commonlib submodule from git
+# (type "git submodule update --init" in the whatdotheyknow directory)
+
+load "validate.rb"
+load "config.rb"
+load "format.rb"
+load "debug_helpers.rb"
+load "util.rb"
+
+# Application version
+ALAVETELI_VERSION = '0.8'
+
+# Add new inflection rules using the following format
+# (all these examples are active by default):
+# Inflector.inflections do |inflect|
+# inflect.plural /^(ox)$/i, '\1en'
+# inflect.singular /^(ox)en/i, '\1'
+# inflect.irregular 'person', 'people'
+# inflect.uncountable %w( fish sheep )
+# end
+
+# Add new mime types for use in respond_to blocks:
+# Mime::Type.register "text/richtext", :rtf
+# Mime::Type.register "application/x-mobile", :mobile
+
+# The Rails cache is set up by the Interlock plugin to use memcached
+
+# Domain for URLs (so can work for scripts, not just web pages)
+ActionMailer::Base.default_url_options[:host] = AlaveteliConfiguration::domain
+# https links in emails if forcing SSL
+if AlaveteliConfiguration::force_ssl
+ ActionMailer::Base.default_url_options[:protocol] = "https"
+end
+
+# fallback locale and available locales
+available_locales = AlaveteliConfiguration::available_locales.split(/ /)
+default_locale = AlaveteliConfiguration::default_locale
+
+FastGettext.default_available_locales = available_locales
+I18n.locale = default_locale
+I18n.available_locales = available_locales.map {|locale_name| locale_name.to_sym}
+I18n.default_locale = default_locale
+
+# Customise will_paginate URL generation
+WillPaginate::ViewHelpers.pagination_options[:renderer] = 'WillPaginateExtension::LinkRenderer'
+
+# Load monkey patches and other things from lib/
+require 'ruby19.rb'
+require 'activesupport_cache_extensions.rb'
+require 'use_spans_for_errors.rb'
+require 'activerecord_errors_extensions.rb'
+require 'willpaginate_extension.rb'
+require 'i18n_fixes.rb'
+require 'world_foi_websites.rb'
+require 'alaveteli_external_command.rb'
+require 'quiet_opener.rb'
+require 'mail_handler'
+require 'public_body_categories'
+require 'ability'
diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb
new file mode 100644
index 000000000..59385cdf3
--- /dev/null
+++ b/config/initializers/backtrace_silencers.rb
@@ -0,0 +1,7 @@
+# Be sure to restart your server when you modify this file.
+
+# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
+# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
+
+# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
+# Rails.backtrace_cleaner.remove_silencers!
diff --git a/config/initializers/fast_gettext.rb b/config/initializers/fast_gettext.rb
index 1cd6440e4..752448a41 100644
--- a/config/initializers/fast_gettext.rb
+++ b/config/initializers/fast_gettext.rb
@@ -3,4 +3,4 @@ FastGettext.default_text_domain = 'app'
I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
-RoutingFilter::Locale.include_default_locale = Configuration::include_default_locale_in_urls \ No newline at end of file
+RoutingFilter::Locale.include_default_locale = AlaveteliConfiguration::include_default_locale_in_urls
diff --git a/config/initializers/gettext_i18n_rails.rb b/config/initializers/gettext_i18n_rails.rb
new file mode 100644
index 000000000..ef306682b
--- /dev/null
+++ b/config/initializers/gettext_i18n_rails.rb
@@ -0,0 +1,3 @@
+# FIXME: Audit the translations for XSS opportunities. Ultimately it would be
+# good to get rid of this and explicitly mark strings as html_safe
+GettextI18nRails.translations_are_html_safe = true
diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb
new file mode 100644
index 000000000..9e8b0131f
--- /dev/null
+++ b/config/initializers/inflections.rb
@@ -0,0 +1,10 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new inflection rules using the following format
+# (all these examples are active by default):
+# ActiveSupport::Inflector.inflections do |inflect|
+# inflect.plural /^(ox)$/i, '\1en'
+# inflect.singular /^(ox)en/i, '\1'
+# inflect.irregular 'person', 'people'
+# inflect.uncountable %w( fish sheep )
+# end
diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb
new file mode 100644
index 000000000..72aca7e44
--- /dev/null
+++ b/config/initializers/mime_types.rb
@@ -0,0 +1,5 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new mime types for use in respond_to blocks:
+# Mime::Type.register "text/richtext", :rtf
+# Mime::Type.register_alias "text/html", :iphone
diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb
new file mode 100644
index 000000000..f82348169
--- /dev/null
+++ b/config/initializers/secret_token.rb
@@ -0,0 +1,7 @@
+# Be sure to restart your server when you modify this file.
+
+# Your secret key for verifying the integrity of signed cookies.
+# If you change this key, all old signed cookies will become invalid!
+# Make sure the secret is at least 30 characters and all random,
+# no regular words or you'll be exposed to dictionary attacks.
+Alaveteli::Application.config.secret_token = AlaveteliConfiguration::cookie_store_session_secret
diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb
index 8cfa333f2..ca283d4e0 100644
--- a/config/initializers/session_store.rb
+++ b/config/initializers/session_store.rb
@@ -1,17 +1,2 @@
# Be sure to restart your server when you modify this file.
-
-# Your secret key for verifying cookie session data integrity.
-# If you change this key, all old sessions will become invalid!
-# Make sure the secret is at least 30 characters and all random,
-# no regular words or you'll be exposed to dictionary attacks.
-
-ActionController::Base.session = {
- :key => '_wdtk_cookie_session',
- :secret => Configuration::cookie_store_session_secret
-}
-ActionController::Base.session_store = :cookie_store
-
-# Insert a bit of middleware code to prevent uneeded cookie setting.
-require "#{Rails.root}/lib/whatdotheyknow/strip_empty_sessions"
-ActionController::Dispatcher.middleware.insert_before ActionController::Base.session_store, WhatDoTheyKnow::StripEmptySessions, :key => '_wdtk_cookie_session', :path => "/", :httponly => true
-
+Rails.application.config.session_store :cookie_store, :key => '_wdtk_cookie_session'
diff --git a/config/initializers/single_quote_escape_workaround.rb b/config/initializers/single_quote_escape_workaround.rb
deleted file mode 100644
index 2e713b982..000000000
--- a/config/initializers/single_quote_escape_workaround.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-class ERB
- module Util
-
- if "html_safe exists".respond_to?(:html_safe)
- def html_escape(s)
- s = s.to_s
- if s.html_safe?
- s
- else
- Rack::Utils.escape_html(s).html_safe
- end
- end
- else
- def html_escape(s)
- s = s.to_s
- Rack::Utils.escape_html(s).html_safe
- end
- end
-
- remove_method :h
- alias h html_escape
-
- class << self
- remove_method :html_escape
- remove_method :h
- end
-
- module_function :html_escape
- module_function :h
- end
-end
diff --git a/config/initializers/strip_nil_parameters_patch.rb b/config/initializers/strip_nil_parameters_patch.rb
deleted file mode 100644
index 35d0a28c5..000000000
--- a/config/initializers/strip_nil_parameters_patch.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# Stolen from https://raw.github.com/mysociety/fixmytransport/fa9b014eb2628c300693e055f129cb8959772082/config/initializers/strip_nil_parameters_patch.rb
-
-# Monkey patch for CVE-2012-2660 on Rails 2.3.14
-
-# Strip [nil] from parameters hash
-# based on a pull request from @sebbacon
-# https://github.com/rails/rails/pull/6580
-
-module ActionController
- class Request < Rack::Request
- protected
- def deep_munge(hash)
- hash.each_value do |v|
- case v
- when Array
- v.grep(Hash) { |x| deep_munge(x) }
- when Hash
- deep_munge(v)
- end
- end
-
- keys = hash.keys.find_all { |k| hash[k] == [nil] }
- keys.each { |k| hash[k] = nil }
- hash
- end
-
- private
-
- def normalize_parameters(value)
- case value
- when Hash
- if value.has_key?(:tempfile)
- upload = value[:tempfile]
- upload.extend(UploadedFile)
- upload.original_path = value[:filename]
- upload.content_type = value[:type]
- upload
- else
- h = {}
- value.each { |k, v| h[k] = normalize_parameters(v) }
- deep_munge(h.with_indifferent_access)
- end
- when Array
- value.map { |e| normalize_parameters(e) }
- else
- value
- end
- end
-
- end
-end
diff --git a/config/initializers/theme_loader.rb b/config/initializers/theme_loader.rb
index 877149e9d..4c8967c97 100644
--- a/config/initializers/theme_loader.rb
+++ b/config/initializers/theme_loader.rb
@@ -3,7 +3,7 @@
$alaveteli_route_extensions = []
if ENV["RAILS_ENV"] != "test" # Don't let the themes interfere with Alaveteli specs
- for url in Configuration::theme_urls.reverse
+ for url in AlaveteliConfiguration::theme_urls.reverse
theme_name = url.sub(/.*\/(.*).git/, "\\1")
theme_main_include = File.expand_path "../../../vendor/plugins/#{theme_name}/lib/alavetelitheme.rb", __FILE__
if File.exists? theme_main_include
diff --git a/config/routes.rb b/config/routes.rb
index a18295f7b..10f6a3284 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -2,254 +2,244 @@
# Mapping URLs to controllers for FOIFA.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
# Allow easy extension from themes. Note these will have the highest priority.
$alaveteli_route_extensions.each do |f|
load File.join('config', f)
end
-ActionController::Routing::Routes.draw do |map|
-
- # The priority is based upon order of creation: first created -> highest priority.
-
- # Sample of regular route:
- # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
- # Keep in mind you can assign values other than :controller and :action
-
- map.with_options :controller => 'general' do |general|
- general.frontpage '/', :action => 'frontpage'
- general.blog '/blog', :action => 'blog'
- general.custom_css '/stylesheets/custom.css', :action => 'custom_css'
- general.search_redirect '/search', :action => 'search_redirect'
- general.search_redirect '/search/all', :action => 'search_redirect'
- # XXX combined is the search query, and then if sorted a "/newest" at the end.
- # Couldn't find a way to do this in routes which also picked up multiple other slashes
- # and dots and other characters that can appear in search query. So we sort it all
- # out in the controller.
- general.search_general '/search/*combined/all', :action => 'search', :view => 'all'
- general.search_general '/search/*combined', :action => 'search'
- general.advanced_search '/advancedsearch', :action => 'search_redirect', :advanced => true
-
- general.random_request '/random', :action => 'random_request'
- end
-
- map.with_options :controller => 'request' do |request|
- request.request_list_recent '/list/recent', :action => 'list', :view => 'recent'
- request.request_list_all '/list/all', :action => 'list', :view => 'all'
- request.request_list_successful '/list/successful', :action => 'list', :view => 'successful'
- request.request_list_unsuccessful '/list/unsuccessful', :action => 'list', :view => 'unsuccessful'
- request.request_list_awaiting '/list/awaiting', :action => 'list', :view => 'awaiting'
- request.request_list '/list', :action => 'list'
-
- request.select_authority '/select_authority', :action => 'select_authority'
-
- request.new_request '/new', :action => 'new'
- request.new_request_to_body '/new/:url_name', :action => 'new'
-
- request.search_ahead '/request/search_ahead', :action => 'search_typeahead'
-
- request.show_request '/request/:url_title.:format', :action => 'show'
- request.show_new_request '/request/:url_title/new', :action => 'show'
- request.details_request '/details/request/:url_title', :action => 'details'
- request.similar_request '/similar/request/:url_title', :action => 'similar'
-
- request.describe_state '/request/:id/describe', :action => 'describe_state', :conditions => {:method => :post}
- request.describe_state_message '/request/:url_title/describe/:described_state', :action => 'describe_state_message'
- request.show_response_no_followup '/request/:id/response', :action => 'show_response'
- request.show_response '/request/:id/response/:incoming_message_id', :action => 'show_response'
- request.get_attachment_as_html '/request/:id/response/:incoming_message_id/attach/html/:part/*file_name', :action => 'get_attachment_as_html'
- request.get_attachment '/request/:id/response/:incoming_message_id/attach/:part/*file_name', :action => 'get_attachment'
-
- request.info_request_event '/request_event/:info_request_event_id', :action => 'show_request_event'
-
- request.upload_response "/upload/request/:url_title", :action => 'upload_response'
- request.download_entire_request '/request/:url_title/download', :action => 'download_entire_request'
-
- # It would be nice to add :conditions => { :method => :post } to this next one,
- # because it ought not really to be available as a GET request since it changes
- # the server state. Unfortunately this doesn’t play well with the PostRedirect
- # mechanism, which assumes all post-login actions are available via GET, so we
- # refrain.
- request.report '/request/:url_title/report', :action => 'report_request'
-
- end
-
+Alaveteli::Application.routes.draw do
+ #### General contoller
+ match '/' => 'general#frontpage', :as => :frontpage
+ match '/blog' => 'general#blog', :as => :blog
+ match '/stylesheets/custom.css' => 'general#custom_css', :as => :custom_css
+ match '/search' => 'general#search_redirect', :as => :search_redirect
+ match '/search/all' => 'general#search_redirect', :as => :search_redirect
+ # XXX combined is the search query, and then if sorted a "/newest" at the end.
+ # Couldn't find a way to do this in routes which also picked up multiple other slashes
+ # and dots and other characters that can appear in search query. So we sort it all
+ # out in the controller.
+ match '/search/*combined/all' => 'general#search', :as => :search_general, :view => 'all'
+ match '/search(/*combined)' => 'general#search', :as => :search_general
+ match '/advancedsearch' => 'general#search_redirect', :as => :advanced_search, :advanced => true
+
+ match '/random' => 'general#random_request', :as => :random_request
+ #####
+
+ ##### Request controller
+ match '/list/recent' => 'request#list', :as => :request_list_recent, :view => 'recent'
+ match '/list/all' => 'request#list', :as => :request_list_all, :view => 'all'
+ match '/list/successful' => 'request#list', :as => :request_list_successful, :view => 'successful'
+ match '/list/unsuccessful' => 'request#list', :as => :request_list_unsuccessful, :view => 'unsuccessful'
+ match '/list/awaiting' => 'request#list', :as => :request_list_awaiting, :view => 'awaiting'
+ match '/list' => 'request#list', :as => :request_list
+
+ match '/select_authority' => 'request#select_authority', :as => :select_authority
+
+ match '/new' => 'request#new', :as => :new_request
+ match '/new/:url_name' => 'request#new', :as => :new_request_to_body
+
+ match '/request/search_ahead' => 'request#search_typeahead', :as => :search_ahead
+
+ match '/request/:url_title' => 'request#show', :as => :show_request
+ match '/request/:url_title/new' => 'request#show', :as => :show_new_request
+ match '/details/request/:url_title' => 'request#details', :as => :details_request
+ match '/similar/request/:url_title' => 'request#similar', :as => :similar_request
+
+ match '/request/:id/describe' => 'request#describe_state', :as => :describe_state
+ match '/request/:url_title/describe/:described_state' => 'request#describe_state_message', :as => :describe_state_message
+ match '/request/:id/response' => 'request#show_response', :as => :show_response_no_followup
+ match '/request/:id/response/:incoming_message_id' => 'request#show_response', :as => :show_response
+ match '/request/:id/response/:incoming_message_id/attach/html/:part/*file_name' => 'request#get_attachment_as_html', :as => :get_attachment_as_html
+ match '/request/:id/response/:incoming_message_id/attach/:part(/*file_name)' => 'request#get_attachment', :as => :get_attachment
+
+ match '/request_event/:info_request_event_id' => 'request#show_request_event', :as => :info_request_event
+
+ match '/upload/request/:url_title' => 'request#upload_response', :as => :upload_response
+ match '/request/:url_title/download' => 'request#download_entire_request', :as => :download_entire_request
+
+ # It would be nice to add :conditions => { :method => :post } to this next one,
+ # because it ought not really to be available as a GET request since it changes
+ # the server state. Unfortunately this doesn’t play well with the PostRedirect
+ # mechanism, which assumes all post-login actions are available via GET, so we
+ # refrain.
+ match '/request/:url_title/report' => 'request#report_request', :as => :report
+ ####
+
+ #### User controller
# Use /profile for things to do with the currently signed in user.
# Use /user/XXXX for things that anyone can see about that user.
# Note that /profile isn't indexed by search (see robots.txt)
- map.with_options :controller => 'user' do |user|
- user.signin '/profile/sign_in', :action => 'signin'
- user.signup '/profile/sign_up', :action => 'signup'
- user.signout '/profile/sign_out', :action => 'signout'
-
- user.confirm '/c/:email_token', :action => 'confirm'
- user.show_user '/user/:url_name.:format', :action => 'show'
- user.show_user_profile '/user/:url_name/profile.:format', :action => 'show', :view => 'profile'
- user.show_user_requests '/user/:url_name/requests.:format', :action => 'show', :view => 'requests'
- user.show_user_wall '/user/:url_name/wall.:format', :action => 'wall'
- user.contact_user '/user/contact/:id', :action => 'contact'
-
- user.signchangepassword '/profile/change_password', :action => 'signchangepassword'
- user.signchangeemail '/profile/change_email', :action => 'signchangeemail'
-
- user.set_profile_photo '/profile/set_photo', :action => 'set_profile_photo'
- user.clear_profile_photo '/profile/clear_photo', :action => 'clear_profile_photo'
- user.get_profile_photo '/user/:url_name/photo.png', :action => 'get_profile_photo'
- user.get_draft_profile_photo '/profile/draft_photo/:id.png', :action => 'get_draft_profile_photo'
- user.set_profile_about_me '/profile/set_about_me', :action => 'set_profile_about_me'
- user.set_receive_email_alerts '/profile/set_receive_alerts', :action => 'set_receive_email_alerts'
- user.river '/profile/river', :action => 'river'
- end
-
- map.with_options :controller => 'public_body' do |body|
- body.search_ahead_bodies '/body/search_ahead', :action => 'search_typeahead'
- body.list_public_bodies "/body", :action => 'list'
- body.list_public_bodies_default "/body/list/all", :action => 'list'
- body.list_public_bodies "/body/list/:tag", :action => 'list'
- body.list_public_bodies_redirect "/local/:tag", :action => 'list_redirect'
- body.all_public_bodies_csv "/body/all-authorities.csv", :action => 'list_all_csv'
- body.show_public_body "/body/:url_name.:format", :action => 'show', :view => 'all'
- body.show_public_body_all "/body/:url_name/all", :action => 'show', :view => 'all'
- body.show_public_body_successful "/body/:url_name/successful", :action => 'show', :view => "successful"
- body.show_public_body_unsuccessful "/body/:url_name/unsuccessful", :action => 'show', :view => "unsuccessful"
- body.show_public_body_awaiting "/body/:url_name/awaiting", :action => 'show', :view => "awaiting"
- body.view_public_body_email "/body/:url_name/view_email", :action => 'view_email'
- body.show_public_body_tag "/body/:url_name/:tag", :action => 'show'
- body.show_public_body_tag_view "/body/:url_name/:tag/:view", :action => 'show'
- end
-
- map.with_options :controller => 'comment' do |comment|
- comment.new_comment "/annotate/request/:url_title", :action => 'new', :type => 'request'
- end
-
- map.with_options :controller => 'services' do |service|
- service.other_country_message "/country_message", :action => 'other_country_message'
- service.hidden_user_explanation "/hidden_user_explanation", :action => 'hidden_user_explanation'
- end
-
- map.with_options :controller => 'track' do |track|
- # /track/ is for setting up an email alert for the item
- # /feed/ is a direct RSS feed of the item
- track.track_request '/:feed/request/:url_title.:format', :action => 'track_request', :feed => /(track|feed)/
- track.track_list '/:feed/list/:view.:format', :action => 'track_list', :view => nil, :feed => /(track|feed)/
- track.track_public_body "/:feed/body/:url_name.:format", :action => 'track_public_body', :feed => /(track|feed)/
- track.track_user "/:feed/user/:url_name.:format", :action => 'track_user', :feed => /(track|feed)/
- # XXX must be better way of getting dots and slashes in search queries to work than this *query_array
- # Also, the :format doesn't work. See hacky code in the controller that makes up for this.
- track.track_search "/:feed/search/*query_array.:format", :action => 'track_search_query' , :feed => /(track|feed)/
-
- track.update '/track/update/:track_id', :action => 'update'
- track.delete_all_type '/track/delete_all_type', :action => 'delete_all_type'
- track.atom_feed '/track/feed/:track_id', :action => 'atom_feed'
- end
-
- map.with_options :controller => 'help' do |help|
- help.help_unhappy '/help/unhappy/:url_title', :action => 'unhappy'
- help.help_about '/help/about', :action => 'about'
- help.help_alaveteli '/help/alaveteli', :action => 'alaveteli'
- help.help_contact '/help/contact', :action => 'contact'
- help.help_officers '/help/officers', :action => 'officers'
- help.help_requesting '/help/requesting', :action => 'requesting'
- help.help_privacy '/help/privacy', :action => 'privacy'
- help.help_api '/help/api', :action => 'api'
- help.help_credits '/help/credits', :action => 'credits'
- help.help_general '/help/:action', :action => :action
- end
-
- map.with_options :controller => 'holiday' do |holiday|
- holiday.due_date "/due_date/:holiday", :action => 'due_date'
- end
-
- map.with_options :controller => 'request_game' do |game|
- game.categorise_play '/categorise/play', :action => 'play'
- game.categorise_request '/categorise/request/:url_title', :action => 'show'
- game.categorise_stop '/categorise/stop', :action => 'stop'
- end
-
- map.with_options :controller => 'admin_public_body' do |body|
- body.admin_body_missing '/admin/missing_scheme', :action => 'missing_scheme'
- body.admin_body_index '/admin/body', :action => 'index'
- body.admin_body_list '/admin/body/list', :action => 'list'
- body.admin_body_show '/admin/body/show/:id', :action => 'show'
- body.admin_body_new '/admin/body/new', :action => 'new'
- body.admin_body_edit '/admin/body/edit/:id', :action => 'edit'
- body.admin_body_update '/admin/body/update/:id', :action => 'update'
- body.admin_body_create '/admin/body/create', :action => 'create'
- body.admin_body_destroy '/admin/body/destroy/:id', :action => 'destroy'
- body.admin_body_import_csv '/admin/body/import_csv', :action => 'import_csv'
- body.admin_body_mass_tag_add '/admin/body/mass_tag_add', :action => 'mass_tag_add'
- end
-
- map.with_options :controller => 'admin_general' do |admin|
- admin.admin_general_index '/admin', :action => 'index'
- admin.admin_timeline '/admin/timeline', :action => 'timeline'
- admin.admin_debug '/admin/debug', :action => 'debug'
- admin.admin_stats '/admin/stats', :action => 'stats'
- admin.admin_js '/admin/javascripts/admin.js', :action => 'admin_js'
- end
-
- map.with_options :controller => 'admin_request' do |admin|
- admin.admin_request_index '/admin/request', :action => 'index'
- admin.admin_request_list '/admin/request/list', :action => 'list'
- admin.admin_request_show '/admin/request/show/:id', :action => 'show'
- admin.admin_request_resend '/admin/request/resend', :action => 'resend'
- admin.admin_request_edit '/admin/request/edit/:id', :action => 'edit'
- admin.admin_request_update '/admin/request/update/:id', :action => 'update'
- admin.admin_request_destroy '/admin/request/destroy/:id', :action => 'fully_destroy'
- admin.admin_request_edit_outgoing '/admin/request/edit_outgoing/:id', :action => 'edit_outgoing'
- admin.admin_request_destroy_outgoing '/admin/request/destroy_outgoing', :action => 'destroy_outgoing'
- admin.admin_request_update_outgoing '/admin/request/update_outgoing/:id', :action => 'update_outgoing'
- admin.admin_request_edit_comment '/admin/request/edit_comment/:id', :action => 'edit_comment'
- admin.admin_request_update_comment '/admin/request/update_comment/:id', :action => 'update_comment'
- admin.admin_request_destroy_incoming '/admin/request/destroy_incoming', :action => 'destroy_incoming'
- admin.admin_request_redeliver_incoming '/admin/request/redeliver_incoming', :action => 'redeliver_incoming'
- admin.admin_request_move_request '/admin/request/move_request', :action => 'move_request'
- admin.admin_request_generate_upload_url '/admin/request/generate_upload_url/:id', :action => 'generate_upload_url'
- admin.admin_request_show_raw_email '/admin/request/show_raw_email/:id', :action => 'show_raw_email'
- admin.admin_request_download_raw_email '/admin/request/download_raw_email/:id', :action => 'download_raw_email'
- admin.admin_request_clarification '/admin/request/mark_event_as_clarification', :action => 'mark_event_as_clarification'
- admin.admin_request_hide '/admin/request/hide/:id', :action => 'hide_request'
- end
-
- map.with_options :controller => 'admin_user' do |user|
- user.admin_user_index '/admin/user', :action => 'index'
- user.admin_user_list '/admin/user/list', :action => 'list'
- user.admin_user_list_banned '/admin/user/banned', :action => 'list_banned'
- user.admin_user_show '/admin/user/show/:id', :action => 'show'
- user.admin_user_edit '/admin/user/edit/:id', :action => 'edit'
- user.admin_user_show_bounce '/admin/user/show_bounce_message/:id', :action => 'show_bounce_message'
- user.admin_user_update '/admin/user/update/:id', :action => 'update'
- user.admin_user_clear_bounce '/admin/user/clear_bounce/:id', :action => 'clear_bounce'
- user.admin_user_destroy_track '/admin/user/destroy_track', :action => 'destroy_track'
- user.admin_user_login_as '/admin/user/login_as/:id', :action => 'login_as'
- user.admin_clear_profile_photo '/admin/user/clear_profile_photo/:id', :action => 'clear_profile_photo'
- end
-
- map.with_options :controller => 'admin_track' do |track|
- track.admin_track_list '/admin/track/list', :action => 'list'
- end
-
- map.with_options :controller => 'admin_censor_rule' do |rule|
- rule.admin_rule_new '/admin/censor/new', :action => 'new'
- rule.admin_rule_create '/admin/censor/create', :action => 'create'
- rule.admin_rule_edit '/admin/censor/edit/:id', :action => 'edit'
- rule.admin_rule_update '/admin/censor/update/:id', :action => 'update'
- rule.admin_rule_destroy '/admin/censor/destroy/:censor_rule_id', :action => 'destroy'
- end
-
- map.with_options :controller => 'api' do |api|
- api.api_create_request '/api/v2/request.json', :action => 'create_request', :conditions => { :method => :post }
-
- api.api_show_request '/api/v2/request/:id.json', :action => 'show_request', :conditions => { :method => :get }
- api.api_add_correspondence '/api/v2/request/:id.json', :action => 'add_correspondence', :conditions => { :method => :post }
-
- api.api_body_request_events '/api/v2/body/:id/request_events.:feed_type', :action => 'body_request_events', :feed_type => '^(json|atom)$'
- end
-
- map.filter('conditionallyprependlocale')
-
- # Allow downloading Web Service WSDL as a file with an extension
- # instead of a file named 'wsdl'
- # map.connect ':controller/service.wsdl', :action => 'wsdl'
+ match '/profile/sign_in' => 'user#signin', :as => :signin
+ match '/profile/sign_up' => 'user#signup', :as => :signup
+ match '/profile/sign_out' => 'user#signout', :as => :signout
+
+ match '/c/:email_token' => 'user#confirm', :as => :confirm
+ match '/user/:url_name' => 'user#show', :as => :show_user
+ match '/user/:url_name/profile' => 'user#show', :as => :show_user_profile, :view => 'profile'
+ match '/user/:url_name/requests' => 'user#show', :as => :show_user_requests, :view => 'requests'
+ match '/user/:url_name/wall' => 'user#wall', :as => :show_user_wall
+ match '/user/contact/:id' => 'user#contact', :as => :contact_user
+
+ match '/profile/change_password' => 'user#signchangepassword', :as => :signchangepassword
+ match '/profile/change_email' => 'user#signchangeemail', :as => :signchangeemail
+
+ match '/profile/set_photo' => 'user#set_profile_photo', :as => :set_profile_photo
+ match '/profile/clear_photo' => 'user#clear_profile_photo', :as => :clear_profile_photo
+ match '/user/:url_name/photo.png' => 'user#get_profile_photo', :as => :get_profile_photo
+ match '/profile/draft_photo/:id.png' => 'user#get_draft_profile_photo', :as => :get_draft_profile_photo
+ match '/profile/set_about_me' => 'user#set_profile_about_me', :as => :set_profile_about_me
+ match '/profile/set_receive_alerts' => 'user#set_receive_email_alerts', :as => :set_receive_email_alerts
+ match '/profile/river' => 'user#river', :as => :river
+ ####
+
+ #### PublicBody controller
+ match '/body/search_ahead' => 'public_body#search_typeahead', :as => :search_ahead_bodies
+ match '/body' => 'public_body#list', :as => :list_public_bodies
+ match '/body/list/all' => 'public_body#list', :as => :list_public_bodies_default
+ match '/body/list/:tag' => 'public_body#list', :as => :list_public_bodies
+ match '/local/:tag' => 'public_body#list_redirect', :as => :list_public_bodies_redirect
+ match '/body/all-authorities.csv' => 'public_body#list_all_csv', :as => :all_public_bodies_csv
+ match '/body/:url_name' => 'public_body#show', :as => :show_public_body, :view => 'all'
+ match '/body/:url_name/all' => 'public_body#show', :as => :show_public_body_all, :view => 'all'
+ match '/body/:url_name/successful' => 'public_body#show', :as => :show_public_body_successful, :view => 'successful'
+ match '/body/:url_name/unsuccessful' => 'public_body#show', :as => :show_public_body_unsuccessful, :view => 'unsuccessful'
+ match '/body/:url_name/awaiting' => 'public_body#show', :as => :show_public_body_awaiting, :view => 'awaiting'
+ match '/body/:url_name/view_email' => 'public_body#view_email', :as => :view_public_body_email
+ match '/body/:url_name/:tag' => 'public_body#show', :as => :show_public_body_tag
+ match '/body/:url_name/:tag/:view' => 'public_body#show', :as => :show_public_body_tag_view
+ ####
+
+ #### Comment controller
+ match '/annotate/request/:url_title' => 'comment#new', :as => :new_comment, :type => 'request'
+ ####
+
+ #### Services controller
+ match '/country_message' => 'services#other_country_message', :as => :other_country_message
+ match '/hidden_user_explanation' => 'services#hidden_user_explanation', :as => :hidden_user_explanation
+ ####
+
+ #### Track controller
+ # /track/ is for setting up an email alert for the item
+ # /feed/ is a direct RSS feed of the item
+ match '/:feed/request/:url_title' => 'track#track_request', :as => :track_request, :feed => /(track|feed)/
+ match '/:feed/list/:view' => 'track#track_list', :as => :track_list, :view => nil, :feed => /(track|feed)/
+ match '/:feed/body/:url_name' => 'track#track_public_body', :as => :track_public_body, :feed => /(track|feed)/
+ match '/:feed/user/:url_name' => 'track#track_user', :as => :track_user, :feed => /(track|feed)/
+ # XXX :format doesn't work. See hacky code in the controller that makes up for this.
+ match '/:feed/search/:query_array' => 'track#track_search_query',
+ :as => :track_search,
+ :feed => /(track|feed)/,
+ :constraints => { :query_array => /.*/ }
+
+ match '/track/update/:track_id' => 'track#update', :as => :update
+ match '/track/delete_all_type' => 'track#delete_all_type', :as => :delete_all_type
+ match '/track/feed/:track_id' => 'track#atom_feed', :as => :atom_feed
+ ####
+
+ #### Help controller
+ match '/help/unhappy/:url_title' => 'help#unhappy', :as => :help_unhappy
+ match '/help/about' => 'help#about', :as => :help_about
+ match '/help/alaveteli' => 'help#alaveteli', :as => :help_alaveteli
+ match '/help/contact' => 'help#contact', :as => :help_contact
+ match '/help/officers' => 'help#officers', :as => :help_officers
+ match '/help/requesting' => 'help#requesting', :as => :help_requesting
+ match '/help/privacy' => 'help#privacy', :as => :help_privacy
+ match '/help/api' => 'help#api', :as => :help_api
+ match '/help/credits' => 'help#credits', :as => :help_credits
+ match '/help/:action' => 'help#action', :as => :help_general
+ ####
+
+ #### Holiday controller
+ match '/due_date/:holiday' => 'holiday#due_date', :as => :due_date
+ ####
+
+ #### RequestGame controller
+ match '/categorise/play' => 'request_game#play', :as => :categorise_play
+ match '/categorise/request/:url_title' => 'request_game#show', :as => :categorise_request
+ match '/categorise/stop' => 'request_game#stop', :as => :categorise_stop
+ ####
+
+ #### AdminPublicBody controller
+ match '/admin/missing_scheme' => 'admin_public_body#missing_scheme', :as => :admin_body_missing
+ match '/admin/body' => 'admin_public_body#index', :as => :admin_body_index
+ match '/admin/body/list' => 'admin_public_body#list', :as => :admin_body_list
+ match '/admin/body/show/:id' => 'admin_public_body#show', :as => :admin_body_show
+ match '/admin/body/new' => 'admin_public_body#new', :as => :admin_body_new
+ match '/admin/body/edit/:id' => 'admin_public_body#edit', :as => :admin_body_edit
+ match '/admin/body/update/:id' => 'admin_public_body#update', :as => :admin_body_update
+ match '/admin/body/create' => 'admin_public_body#create', :as => :admin_body_create
+ match '/admin/body/destroy/:id' => 'admin_public_body#destroy', :as => :admin_body_destroy
+ match '/admin/body/import_csv' => 'admin_public_body#import_csv', :as => :admin_body_import_csv
+ match '/admin/body/mass_tag_add' => 'admin_public_body#mass_tag_add', :as => :admin_body_mass_tag_add
+ ####
+
+ #### AdminGeneral controller
+ match '/admin' => 'admin_general#index', :as => :admin_general_index
+ match '/admin/timeline' => 'admin_general#timeline', :as => :admin_timeline
+ match '/admin/debug' => 'admin_general#debug', :as => :admin_debug
+ match '/admin/stats' => 'admin_general#stats', :as => :admin_stats
+ match '/admin/javascripts/admin.js' => 'admin_general#admin_js', :as => :admin_js
+ ####
+
+ #### AdminRequest controller
+ match '/admin/request' => 'admin_request#index', :as => :admin_request_index
+ match '/admin/request/list' => 'admin_request#list', :as => :admin_request_list
+ match '/admin/request/show/:id' => 'admin_request#show', :as => :admin_request_show
+ match '/admin/request/resend' => 'admin_request#resend', :as => :admin_request_resend
+ match '/admin/request/edit/:id' => 'admin_request#edit', :as => :admin_request_edit
+ match '/admin/request/update/:id' => 'admin_request#update', :as => :admin_request_update
+ match '/admin/request/destroy/:id' => 'admin_request#fully_destroy', :as => :admin_request_destroy
+ match '/admin/request/edit_outgoing/:id' => 'admin_request#edit_outgoing', :as => :admin_request_edit_outgoing
+ match '/admin/request/destroy_outgoing/:id' => 'admin_request#destroy_outgoing', :as => :admin_request_destroy_outgoing
+ match '/admin/request/update_outgoing/:id' => 'admin_request#update_outgoing', :as => :admin_request_update_outgoing
+ match '/admin/request/edit_comment/:id' => 'admin_request#edit_comment', :as => :admin_request_edit_comment
+ match '/admin/request/update_comment/:id' => 'admin_request#update_comment', :as => :admin_request_update_comment
+ match '/admin/request/destroy_incoming' => 'admin_request#destroy_incoming', :as => :admin_request_destroy_incoming
+ match '/admin/request/redeliver_incoming' => 'admin_request#redeliver_incoming', :as => :admin_request_redeliver_incoming
+ match '/admin/request/move_request' => 'admin_request#move_request', :as => :admin_request_move_request
+ match '/admin/request/generate_upload_url/:id' => 'admin_request#generate_upload_url', :as => :admin_request_generate_upload_url
+ match '/admin/request/show_raw_email/:id' => 'admin_request#show_raw_email', :as => :admin_request_show_raw_email
+ match '/admin/request/download_raw_email/:id' => 'admin_request#download_raw_email', :as => :admin_request_download_raw_email
+ match '/admin/request/mark_event_as_clarification' => 'admin_request#mark_event_as_clarification', :as => :admin_request_clarification
+ match '/admin/request/hide/:id' => 'admin_request#hide_request', :as => :admin_request_hide
+ ####
+
+ #### AdminUser controller
+ match '/admin/user' => 'admin_user#index', :as => :admin_user_index
+ match '/admin/user/list' => 'admin_user#list', :as => :admin_user_list
+ match '/admin/user/banned' => 'admin_user#list_banned', :as => :admin_user_list_banned
+ match '/admin/user/show/:id' => 'admin_user#show', :as => :admin_user_show
+ match '/admin/user/edit/:id' => 'admin_user#edit', :as => :admin_user_edit
+ match '/admin/user/show_bounce_message/:id' => 'admin_user#show_bounce_message', :as => :admin_user_show_bounce
+ match '/admin/user/update/:id' => 'admin_user#update', :as => :admin_user_update
+ match '/admin/user/clear_bounce/:id' => 'admin_user#clear_bounce', :as => :admin_user_clear_bounce
+ match '/admin/user/destroy_track' => 'admin_user#destroy_track', :as => :admin_user_destroy_track
+ match '/admin/user/login_as/:id' => 'admin_user#login_as', :as => :admin_user_login_as
+ match '/admin/user/clear_profile_photo/:id' => 'admin_user#clear_profile_photo', :as => :admin_clear_profile_photo
+ ####
+
+ #### AdminTrack controller
+ match '/admin/track/list' => 'admin_track#list', :as => :admin_track_list
+ ####
+
+ #### AdminCensorRule controller
+ match '/admin/censor/new' => 'admin_censor_rule#new', :as => :admin_rule_new
+ match '/admin/censor/create' => 'admin_censor_rule#create', :as => :admin_rule_create
+ match '/admin/censor/edit/:id' => 'admin_censor_rule#edit', :as => :admin_rule_edit
+ match '/admin/censor/update/:id' => 'admin_censor_rule#update', :as => :admin_rule_update
+ match '/admin/censor/destroy/:censor_rule_id' => 'admin_censor_rule#destroy', :as => :admin_rule_destroy
+ ####
+
+ #### Api controller
+ match '/api/v2/request.json' => 'api#create_request', :as => :api_create_request, :via => :post
+
+ match '/api/v2/request/:id.json' => 'api#show_request', :as => :api_show_request, :via => :get
+ match '/api/v2/request/:id.json' => 'api#add_correspondence', :as => :api_add_correspondence, :via => :post
+
+ match '/api/v2/body/:id/request_events.:feed_type' => 'api#body_request_events', :as => :api_body_request_events, :feed_type => '^(json|atom)$'
+ ####
+
+ filter :conditionallyprependlocale
end
diff --git a/config/test.yml b/config/test.yml
index bc9ec099a..5c08e928b 100644
--- a/config/test.yml
+++ b/config/test.yml
@@ -1,7 +1,7 @@
# test.yml
# Test values for the "general" config file.
#
-# Configuration parameters, in YAML syntax.
+# AlaveteliConfiguration parameters, in YAML syntax.
#
# These may be values expected by the test suite; changing them may
# break tests.
diff --git a/db/development_structure.sql b/db/development_structure.sql
index bd4870948..47e33e373 100644
--- a/db/development_structure.sql
+++ b/db/development_structure.sql
@@ -908,168 +908,168 @@ ALTER SEQUENCE users_id_seq OWNED BY users.id;
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY acts_as_xapian_jobs ALTER COLUMN id SET DEFAULT nextval('acts_as_xapian_jobs_id_seq'::regclass);
+ALTER TABLE acts_as_xapian_jobs ALTER COLUMN id SET DEFAULT nextval('acts_as_xapian_jobs_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY censor_rules ALTER COLUMN id SET DEFAULT nextval('censor_rules_id_seq'::regclass);
+ALTER TABLE censor_rules ALTER COLUMN id SET DEFAULT nextval('censor_rules_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY comments ALTER COLUMN id SET DEFAULT nextval('comments_id_seq'::regclass);
+ALTER TABLE comments ALTER COLUMN id SET DEFAULT nextval('comments_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY foi_attachments ALTER COLUMN id SET DEFAULT nextval('foi_attachments_id_seq'::regclass);
+ALTER TABLE foi_attachments ALTER COLUMN id SET DEFAULT nextval('foi_attachments_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY has_tag_string_tags ALTER COLUMN id SET DEFAULT nextval('public_body_tags_id_seq'::regclass);
+ALTER TABLE has_tag_string_tags ALTER COLUMN id SET DEFAULT nextval('public_body_tags_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY holidays ALTER COLUMN id SET DEFAULT nextval('holidays_id_seq'::regclass);
+ALTER TABLE holidays ALTER COLUMN id SET DEFAULT nextval('holidays_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY incoming_messages ALTER COLUMN id SET DEFAULT nextval('incoming_messages_id_seq'::regclass);
+ALTER TABLE incoming_messages ALTER COLUMN id SET DEFAULT nextval('incoming_messages_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY info_request_events ALTER COLUMN id SET DEFAULT nextval('info_request_events_id_seq'::regclass);
+ALTER TABLE info_request_events ALTER COLUMN id SET DEFAULT nextval('info_request_events_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY info_requests ALTER COLUMN id SET DEFAULT nextval('info_requests_id_seq'::regclass);
+ALTER TABLE info_requests ALTER COLUMN id SET DEFAULT nextval('info_requests_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY mail_server_log_dones ALTER COLUMN id SET DEFAULT nextval('exim_log_dones_id_seq'::regclass);
+ALTER TABLE mail_server_log_dones ALTER COLUMN id SET DEFAULT nextval('exim_log_dones_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY mail_server_logs ALTER COLUMN id SET DEFAULT nextval('exim_logs_id_seq'::regclass);
+ALTER TABLE mail_server_logs ALTER COLUMN id SET DEFAULT nextval('exim_logs_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY outgoing_messages ALTER COLUMN id SET DEFAULT nextval('outgoing_messages_id_seq'::regclass);
+ALTER TABLE outgoing_messages ALTER COLUMN id SET DEFAULT nextval('outgoing_messages_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY post_redirects ALTER COLUMN id SET DEFAULT nextval('post_redirects_id_seq'::regclass);
+ALTER TABLE post_redirects ALTER COLUMN id SET DEFAULT nextval('post_redirects_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY profile_photos ALTER COLUMN id SET DEFAULT nextval('profile_photos_id_seq'::regclass);
+ALTER TABLE profile_photos ALTER COLUMN id SET DEFAULT nextval('profile_photos_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY public_bodies ALTER COLUMN id SET DEFAULT nextval('public_bodies_id_seq'::regclass);
+ALTER TABLE public_bodies ALTER COLUMN id SET DEFAULT nextval('public_bodies_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY public_body_translations ALTER COLUMN id SET DEFAULT nextval('public_body_translations_id_seq'::regclass);
+ALTER TABLE public_body_translations ALTER COLUMN id SET DEFAULT nextval('public_body_translations_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY public_body_versions ALTER COLUMN id SET DEFAULT nextval('public_body_versions_id_seq'::regclass);
+ALTER TABLE public_body_versions ALTER COLUMN id SET DEFAULT nextval('public_body_versions_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY purge_requests ALTER COLUMN id SET DEFAULT nextval('purge_requests_id_seq'::regclass);
+ALTER TABLE purge_requests ALTER COLUMN id SET DEFAULT nextval('purge_requests_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY raw_emails ALTER COLUMN id SET DEFAULT nextval('raw_emails_id_seq'::regclass);
+ALTER TABLE raw_emails ALTER COLUMN id SET DEFAULT nextval('raw_emails_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY request_classifications ALTER COLUMN id SET DEFAULT nextval('request_classifications_id_seq'::regclass);
+ALTER TABLE request_classifications ALTER COLUMN id SET DEFAULT nextval('request_classifications_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY track_things ALTER COLUMN id SET DEFAULT nextval('track_things_id_seq'::regclass);
+ALTER TABLE track_things ALTER COLUMN id SET DEFAULT nextval('track_things_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY track_things_sent_emails ALTER COLUMN id SET DEFAULT nextval('track_things_sent_emails_id_seq'::regclass);
+ALTER TABLE track_things_sent_emails ALTER COLUMN id SET DEFAULT nextval('track_things_sent_emails_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY user_info_request_sent_alerts ALTER COLUMN id SET DEFAULT nextval('user_info_request_sent_alerts_id_seq'::regclass);
+ALTER TABLE user_info_request_sent_alerts ALTER COLUMN id SET DEFAULT nextval('user_info_request_sent_alerts_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
-ALTER TABLE ONLY users ALTER COLUMN id SET DEFAULT nextval('users_id_seq'::regclass);
+ALTER TABLE users ALTER COLUMN id SET DEFAULT nextval('users_id_seq'::regclass);
--
diff --git a/db/migrate/006_version_public_body.rb b/db/migrate/006_version_public_body.rb
index 34586add2..0e4527133 100644
--- a/db/migrate/006_version_public_body.rb
+++ b/db/migrate/006_version_public_body.rb
@@ -1,6 +1,8 @@
class VersionPublicBody < ActiveRecord::Migration
def self.up
PublicBody.create_versioned_table
+
+ add_timestamps(:public_body_versions)
end
def self.down
diff --git a/db/migrate/101_add_hash_to_info_request.rb b/db/migrate/101_add_hash_to_info_request.rb
index e21bf0989..924e50829 100644
--- a/db/migrate/101_add_hash_to_info_request.rb
+++ b/db/migrate/101_add_hash_to_info_request.rb
@@ -5,13 +5,11 @@ class AddHashToInfoRequest < ActiveRecord::Migration
add_column :info_requests, :idhash, :string
# Create the missing events for requests already sent
- InfoRequest.find(:all).each do |info_request|
+ InfoRequest.all.each do |info_request|
info_request.idhash = Digest::SHA1.hexdigest(info_request.id.to_s + Configuration::incoming_email_secret)[0,8]
info_request.save!
- puts info_request.idhash
end
change_column :info_requests, :idhash, :string, :null => false
- puts InfoRequest.find_by_idhash
end
def self.down
remove_column :info_requests, :idhash
diff --git a/db/seeds.rb b/db/seeds.rb
new file mode 100644
index 000000000..664d8c74c
--- /dev/null
+++ b/db/seeds.rb
@@ -0,0 +1,7 @@
+# This file should contain all the record creation needed to seed the database with its default values.
+# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
+#
+# Examples:
+#
+# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
+# Mayor.create(:name => 'Daley', :city => cities.first)
diff --git a/doc/INSTALL.md b/doc/INSTALL.md
index 2156f4c4a..ea71454b7 100644
--- a/doc/INSTALL.md
+++ b/doc/INSTALL.md
@@ -67,15 +67,7 @@ Some of the files also have a version number listed in config/packages
# Install Ruby dependencies
-Install rubygems 1.6.2 (we're not using the Debian package because we
-need an older version; see "Troubleshooting" below for an
-explanation):
-
- wget http://rubyforge.org/frs/download.php/74445/rubygems-1.6.2.tgz -O /tmp/rubygems-1.6.2.tgz
- tar zxvf /tmp/rubygems-1.6.2.tgz -C /tmp/
- sudo ruby1.8 /tmp/rubygems-1.6.2/setup.rb
-
-To install Alaveteli's Ruby dependencies, we also need to install
+To install Alaveteli's Ruby dependencies, we need to install
bundler. In Debian, this is provided as a package (installed as part
of the package install process above). You could also install it as a
gem:
diff --git a/doc/THEMES.md b/doc/THEMES.md
index c5e4a3eee..02070644a 100644
--- a/doc/THEMES.md
+++ b/doc/THEMES.md
@@ -66,8 +66,8 @@ add custom help pages, as described below.
The core templates that comprise the layout and user interface of an
Alaveteli site live in `app/views/`. They are use Rails' ERB syntax.
For example, the template for the home page lives at
-`app/views/general/frontpage.rhtml`, and the template for the "about
-us" page is at `app/views/help/about.rhtml`.
+`app/views/general/frontpage.html.erb`, and the template for the "about
+us" page is at `app/views/help/about.html.erb`.
Obviously, you *could* edit those core files directly, but this would
be a Bad Idea, because you would find it increasingly hard to do
@@ -90,7 +90,7 @@ the main Rails app -- see `alavetelitheme/install.rb` to see how this
happens.
The partial at
-`alavetelitheme/lib/views/general/_before_head_end.rhtml` includes the
+`alavetelitheme/lib/views/general/_before_head_end.html.erb` includes the
custom CSS in your theme's stylesheet folder (by convention, in
`alavetelitheme/public/stylesheets/`), with:
@@ -137,20 +137,20 @@ The latter must have one method:
When you've added your extra states, you also need to create the following files in your theme:
-* `lib/views/general/_custom_state_descriptions.rhtml`: Descriptions
+* `lib/views/general/_custom_state_descriptions.html.erb`: Descriptions
of your new states, suitable for displaying to end users
-* `lib/views/general/_custom_state_transitions_complete.rhtml`:
+* `lib/views/general/_custom_state_transitions_complete.html.erb`:
Descriptions for any new states that you might characterise as
'completion' states, for displaying on the categorisation form that
we ask requestors to fill out
-* `lib/views/general/_custom_state_transitions_pending.rhtml`: As
+* `lib/views/general/_custom_state_transitions_pending.html.erb`: As
above, but for new states you might characterise as 'pending'
states.
You can see examples of these customisations in
[this commit](https://github.com/sebbacon/informatazyrtare-theme/commit/2b240491237bd72415990399904361ce9bfa431d)
for the Kosovan version of Alaveteli, Informata Zyrtare (ignore the
-file `lib/views/general/_custom_state_transitions.rhtml`, which is
+file `lib/views/general/_custom_state_transitions.html.erb`, which is
unused).
# Adding new pages in the navigation
diff --git a/lib/activesupport_cache_extensions.rb b/lib/activesupport_cache_extensions.rb
index f15d72894..2791d5996 100644
--- a/lib/activesupport_cache_extensions.rb
+++ b/lib/activesupport_cache_extensions.rb
@@ -2,7 +2,7 @@
# Extensions / fixes to ActiveSupport::Cache
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
# Monkeypatch! ./activesupport/lib/active_support/cache/file_store.rb
diff --git a/lib/alaveteli_external_command.rb b/lib/alaveteli_external_command.rb
index 24b4b1aa8..ac91a5867 100644
--- a/lib/alaveteli_external_command.rb
+++ b/lib/alaveteli_external_command.rb
@@ -21,14 +21,14 @@ module AlaveteliExternalCommand
program_path = program_name
else
found = false
- Configuration::utility_search_path.each do |d|
+ AlaveteliConfiguration::utility_search_path.each do |d|
program_path = File.join(d, program_name)
if File.file? program_path and File.executable? program_path
found = true
break
end
end
- raise "Could not find #{program_name} in any of #{Configuration::utility_search_path.join(', ')}" if !found
+ raise "Could not find #{program_name} in any of #{AlaveteliConfiguration::utility_search_path.join(', ')}" if !found
end
xc = ExternalCommand.new(program_path, *args)
diff --git a/lib/configuration.rb b/lib/configuration.rb
index 4a0e0339b..cc85f0db3 100644
--- a/lib/configuration.rb
+++ b/lib/configuration.rb
@@ -1,8 +1,18 @@
+require File.dirname(__FILE__) + '/../commonlib/rblib/config'
+
+# Load intial mySociety config
+if ENV["RAILS_ENV"] == "test"
+ MySociety::Config.set_file(File.join(File.dirname(__FILE__), '..', 'config', 'test'), true)
+else
+ MySociety::Config.set_file(File.join(File.dirname(__FILE__), '..', 'config', 'general'), true)
+end
+MySociety::Config.load_default
+
# Configuration values with defaults
# TODO: Make this return different values depending on the current rails environment
-module Configuration
+module AlaveteliConfiguration
DEFAULTS = {
:ADMIN_PASSWORD => '',
:ADMIN_USERNAME => '',
@@ -58,7 +68,7 @@ module Configuration
:WORKING_OR_CALENDAR_DAYS => 'working',
}
- def Configuration.method_missing(name)
+ def AlaveteliConfiguration.method_missing(name)
key = name.to_s.upcase
if DEFAULTS.has_key?(key.to_sym)
MySociety::Config.get(key, DEFAULTS[key.to_sym])
diff --git a/lib/cookie_store_with_line_break_fix.rb b/lib/cookie_store_with_line_break_fix.rb
deleted file mode 100644
index dc623fbd0..000000000
--- a/lib/cookie_store_with_line_break_fix.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# See https://makandracards.com/makandra/9443-rails-2-s-cookiestore-produces-invalid-cookie-data-causing-tests-to-break
-
-# Should be able to remove this when we upgrade to Rails 3
-
-module ActionController
- module Session
- CookieStore.class_eval do
-
- def call_with_line_break_fix(*args)
- status, headers, body = call_without_line_break_fix(*args)
- headers['Set-Cookie'].gsub! "\n\n", "\n" if headers['Set-Cookie'].present?
- [ status, headers, body ]
- end
-
- alias_method_chain :call, :line_break_fix
-
- end
- end
-end \ No newline at end of file
diff --git a/lib/mail_handler/backends/mail_backend.rb b/lib/mail_handler/backends/mail_backend.rb
index 0a12ab3bb..f7893a60d 100644
--- a/lib/mail_handler/backends/mail_backend.rb
+++ b/lib/mail_handler/backends/mail_backend.rb
@@ -60,7 +60,7 @@ module MailHandler
def get_from_address(mail)
first_from = first_from(mail)
if first_from
- if first_from.is_a?(String)
+ if first_from.is_a?(ActiveSupport::Multibyte::Chars)
return nil
else
return first_from.address
@@ -74,7 +74,7 @@ module MailHandler
def get_from_name(mail)
first_from = first_from(mail)
if first_from
- if first_from.is_a?(String)
+ if first_from.is_a?(ActiveSupport::Multibyte::Chars)
return nil
else
return first_from.display_name ? eval(%Q{"#{first_from.display_name}"}) : nil
@@ -85,7 +85,7 @@ module MailHandler
end
def get_all_addresses(mail)
- envelope_to = mail['envelope-to'] ? [mail['envelope-to'].value] : []
+ envelope_to = mail['envelope-to'] ? [mail['envelope-to'].value.to_s] : []
((mail.to || []) +
(mail.cc || []) +
(envelope_to || [])).uniq
@@ -319,4 +319,4 @@ module MailHandler
end
end
end
-end \ No newline at end of file
+end
diff --git a/lib/mail_handler/backends/mail_extensions.rb b/lib/mail_handler/backends/mail_extensions.rb
index f756abd1a..d25012e39 100644
--- a/lib/mail_handler/backends/mail_extensions.rb
+++ b/lib/mail_handler/backends/mail_extensions.rb
@@ -64,4 +64,42 @@ module Mail
end.join(";\r\n\s")
end
end
-end \ No newline at end of file
+
+ # HACK: Backport encoding fixes for Ruby 1.8 from Mail 2.5
+ # Can be removed when we no longer support Ruby 1.8
+ class Ruby18
+ def Ruby18.b_value_decode(str)
+ match = str.match(/\=\?(.+)?\?[Bb]\?(.+)?\?\=/m)
+ if match
+ encoding = match[1]
+ str = Ruby18.decode_base64(match[2])
+ str = Iconv.conv('UTF-8//IGNORE', fix_encoding(encoding), str)
+ end
+ str
+ end
+
+ def Ruby18.q_value_decode(str)
+ match = str.match(/\=\?(.+)?\?[Qq]\?(.+)?\?\=/m)
+ if match
+ encoding = match[1]
+ string = match[2].gsub(/_/, '=20')
+ # Remove trailing = if it exists in a Q encoding
+ string = string.sub(/\=$/, '')
+ str = Encodings::QuotedPrintable.decode(string)
+ str = Iconv.conv('UTF-8//IGNORE', fix_encoding(encoding), str)
+ end
+ str
+ end
+
+ private
+
+ def Ruby18.fix_encoding(encoding)
+ case encoding.upcase
+ when 'UTF8'
+ 'UTF-8'
+ else
+ encoding
+ end
+ end
+ end
+end
diff --git a/lib/mail_handler/backends/tmail_backend.rb b/lib/mail_handler/backends/tmail_backend.rb
deleted file mode 100644
index 1e241f261..000000000
--- a/lib/mail_handler/backends/tmail_backend.rb
+++ /dev/null
@@ -1,288 +0,0 @@
-module MailHandler
- module Backends
- module TmailBackend
-
- def backend()
- 'TMail'
- end
-
- # Turn raw data into a structured TMail::Mail object
- # Documentation at http://i.loveruby.net/en/projects/tmail/doc/
- def mail_from_raw_email(data)
- # Hack round bug in TMail's MIME decoding.
- # Report of TMail bug:
- # http://rubyforge.org/tracker/index.php?func=detail&aid=21810&group_id=4512&atid=17370
- copy_of_raw_data = data.gsub(/; boundary=\s+"/im,'; boundary="')
- TMail::Mail.parse(copy_of_raw_data)
- end
-
- # Extracts all attachments from the given TNEF file as a TMail::Mail object
- def mail_from_tnef(content)
- main = TMail::Mail.new
- main.set_content_type 'multipart', 'mixed', { 'boundary' => TMail.new_boundary }
- tnef_attachments(content).each do |attachment|
- tmail_attachment = TMail::Mail.new
- tmail_attachment['content-location'] = attachment[:filename]
- tmail_attachment.body = attachment[:content]
- main.parts << tmail_attachment
- end
- main
- end
-
- # Return a copy of the file name for the mail part
- def get_part_file_name(mail_part)
- part_file_name = TMail::Mail.get_part_file_name(mail_part)
- if part_file_name.nil?
- return nil
- end
- part_file_name = part_file_name.dup
- return part_file_name
- end
-
- # Get the body of a mail part
- def get_part_body(mail_part)
- mail_part.body
- end
-
- # Return the first from address if any
- def get_from_address(mail)
- if mail.from_addrs.nil? || mail.from_addrs.size == 0
- return nil
- end
- mail.from_addrs[0].spec
- end
-
- # Return the first from name if any
- def get_from_name(mail)
- mail.from_name_if_present
- end
-
- def get_all_addresses(mail)
- ((mail.to || []) +
- (mail.cc || []) +
- (mail.envelope_to || [])).uniq
- end
-
- def empty_return_path?(mail)
- return false if mail['return-path'].nil?
- return true if mail['return-path'].addr.to_s == '<>'
- return false
- end
-
- def get_auto_submitted(mail)
- mail['auto-submitted'] ? mail['auto-submitted'].body : nil
- end
-
- def get_content_type(part)
- part.content_type
- end
-
- def get_header_string(header, mail)
- mail.header_string(header)
- end
-
- # Number the attachments in depth first tree order, for use in URLs.
- # XXX This fills in part.rfc822_attachment and part.url_part_number within
- # all the parts of the email (see monkeypatches in lib/mail_handler/tmail_extensions and
- # lib/mail_handler/mail_extensions for how these attributes are added). ensure_parts_counted
- # must be called before using the attributes.
- def ensure_parts_counted(mail)
- mail.count_parts_count = 0
- _count_parts_recursive(mail, mail)
- # we carry on using these numeric ids for attachments uudecoded from within text parts
- mail.count_first_uudecode_count = mail.count_parts_count
- end
- def _count_parts_recursive(part, mail)
- if part.multipart?
- part.parts.each do |p|
- _count_parts_recursive(p, mail)
- end
- else
- part_filename = get_part_file_name(part)
- begin
- if part.content_type == 'message/rfc822'
- # An email attached as text
- # e.g. http://www.whatdotheyknow.com/request/64/response/102
- part.rfc822_attachment = mail_from_raw_email(part.body)
- elsif part.content_type == 'application/vnd.ms-outlook' || part_filename && AlaveteliFileTypes.filename_to_mimetype(part_filename) == 'application/vnd.ms-outlook'
- # An email attached as an Outlook file
- # e.g. http://www.whatdotheyknow.com/request/chinese_names_for_british_politi
- msg = Mapi::Msg.open(StringIO.new(part.body))
- part.rfc822_attachment = mail_from_raw_email(msg.to_mime.to_s)
- elsif part.content_type == 'application/ms-tnef'
- # A set of attachments in a TNEF file
- part.rfc822_attachment = mail_from_tnef(part.body)
- end
- rescue
- # If attached mail doesn't parse, treat it as text part
- part.rfc822_attachment = nil
- else
- unless part.rfc822_attachment.nil?
- _count_parts_recursive(part.rfc822_attachment, mail)
- end
- end
- if part.rfc822_attachment.nil?
- mail.count_parts_count += 1
- part.url_part_number = mail.count_parts_count
- end
- end
- end
-
- def get_attachment_attributes(mail)
- leaves = get_attachment_leaves(mail)
- # XXX we have to call ensure_parts_counted after get_attachment_leaves
- # which is really messy.
- ensure_parts_counted(mail)
- attachment_attributes = []
- for leaf in leaves
- body = get_part_body(leaf)
- # As leaf.body causes MIME decoding which uses lots of RAM, do garbage collection here
- # to prevent excess memory use. XXX not really sure if this helps reduce
- # peak RAM use overall. Anyway, maybe there is something better to do than this.
- GC.start
- if leaf.within_rfc822_attachment
- within_rfc822_subject = leaf.within_rfc822_attachment.subject
- # Test to see if we are in the first part of the attached
- # RFC822 message and it is text, if so add headers.
- # XXX should probably use hunting algorithm to find main text part, rather than
- # just expect it to be first. This will do for now though.
- if leaf.within_rfc822_attachment == leaf && leaf.content_type == 'text/plain'
- headers = ""
- for header in [ 'Date', 'Subject', 'From', 'To', 'Cc' ]
- if leaf.within_rfc822_attachment.header.include?(header.downcase)
- header_value = leaf.within_rfc822_attachment.header[header.downcase]
- if !header_value.blank?
- headers = headers + header + ": " + header_value.to_s + "\n"
- end
- end
- end
- # XXX call _convert_part_body_to_text here, but need to get charset somehow
- # e.g. http://www.whatdotheyknow.com/request/1593/response/3088/attach/4/Freedom%20of%20Information%20request%20-%20car%20oval%20sticker:%20Article%2020,%20Convention%20on%20Road%20Traffic%201949.txt
- body = headers + "\n" + body
-
- # This is quick way of getting all headers, but instead we only add some a) to
- # make it more usable, b) as at least one authority accidentally leaked security
- # information into a header.
- #attachment.body = leaf.within_rfc822_attachment.port.to_s
- end
- end
- attachment_attributes << {:url_part_number => leaf.url_part_number,
- :content_type => get_content_type(leaf),
- :filename => get_part_file_name(leaf),
- :charset => leaf.charset,
- :within_rfc822_subject => within_rfc822_subject,
- :body => body,
- :hexdigest => Digest::MD5.hexdigest(body) }
- end
- attachment_attributes
- end
-
- # (This risks losing info if the unchosen alternative is the only one to contain
- # useful info, but let's worry about that another time)
- def get_attachment_leaves(mail)
- return _get_attachment_leaves_recursive(mail, mail)
- end
- def _get_attachment_leaves_recursive(curr_mail, parent_mail, within_rfc822_attachment = nil)
- leaves_found = []
- if curr_mail.multipart?
- if curr_mail.parts.size == 0
- raise "no parts on multipart mail"
- end
-
- if curr_mail.sub_type == 'alternative'
- # Choose best part from alternatives
- best_part = nil
- # Take the last text/plain one, or else the first one
- curr_mail.parts.each do |m|
- if not best_part
- best_part = m
- elsif m.content_type == 'text/plain'
- best_part = m
- end
- end
- # Take an HTML one as even higher priority. (They tend
- # to render better than text/plain, e.g. don't wrap links here:
- # http://www.whatdotheyknow.com/request/amount_and_cost_of_freedom_of_in#incoming-72238 )
- curr_mail.parts.each do |m|
- if m.content_type == 'text/html'
- best_part = m
- end
- end
- leaves_found += _get_attachment_leaves_recursive(best_part, parent_mail, within_rfc822_attachment)
- else
- # Add all parts
- curr_mail.parts.each do |m|
- leaves_found += _get_attachment_leaves_recursive(m, parent_mail, within_rfc822_attachment)
- end
- end
- else
- # XXX Yuck. this section alters various content_types. That puts
- # it into conflict with ensure_parts_counted which it has to be
- # called both before and after. It will fail with cases of
- # attachments of attachments etc.
- charset = curr_mail.charset # save this, because overwriting content_type also resets charset
- # Don't allow nil content_types
- if curr_mail.content_type.nil?
- curr_mail.content_type = 'application/octet-stream'
- end
- # PDFs often come with this mime type, fix it up for view code
- if curr_mail.content_type == 'application/octet-stream'
- part_file_name = get_part_file_name(curr_mail)
- part_body = get_part_body(curr_mail)
- calc_mime = AlaveteliFileTypes.filename_and_content_to_mimetype(part_file_name, part_body)
- if calc_mime
- curr_mail.content_type = calc_mime
- end
- end
-
- # Use standard content types for Word documents etc.
- curr_mail.content_type = normalise_content_type(curr_mail.content_type)
- if curr_mail.content_type == 'message/rfc822'
- ensure_parts_counted(parent_mail) # fills in rfc822_attachment variable
- if curr_mail.rfc822_attachment.nil?
- # Attached mail didn't parse, so treat as text
- curr_mail.content_type = 'text/plain'
- end
- end
- if curr_mail.content_type == 'application/vnd.ms-outlook' || curr_mail.content_type == 'application/ms-tnef'
- ensure_parts_counted(parent_mail) # fills in rfc822_attachment variable
- if curr_mail.rfc822_attachment.nil?
- # Attached mail didn't parse, so treat as binary
- curr_mail.content_type = 'application/octet-stream'
- end
- end
- # If the part is an attachment of email
- if curr_mail.content_type == 'message/rfc822' || curr_mail.content_type == 'application/vnd.ms-outlook' || curr_mail.content_type == 'application/ms-tnef'
- ensure_parts_counted(parent_mail) # fills in rfc822_attachment variable
- leaves_found += _get_attachment_leaves_recursive(curr_mail.rfc822_attachment, parent_mail, curr_mail.rfc822_attachment)
- else
- # Store leaf
- curr_mail.within_rfc822_attachment = within_rfc822_attachment
- leaves_found += [curr_mail]
- end
- # restore original charset
- curr_mail.charset = charset
- end
- return leaves_found
- end
-
-
- def address_from_name_and_email(name, email)
- if !MySociety::Validate.is_valid_email(email)
- raise "invalid email " + email + " passed to address_from_name_and_email"
- end
- if name.nil?
- return TMail::Address.parse(email).to_s
- end
- # Botch an always quoted RFC address, then parse it
- name = name.gsub(/(["\\])/, "\\\\\\1")
- TMail::Address.parse('"' + name + '" <' + email + '>').to_s
- end
-
- def address_from_string(string)
- TMail::Address.parse(string).address
- end
-
- end
- end
-end \ No newline at end of file
diff --git a/lib/mail_handler/backends/tmail_extensions.rb b/lib/mail_handler/backends/tmail_extensions.rb
deleted file mode 100644
index 3576a8eca..000000000
--- a/lib/mail_handler/backends/tmail_extensions.rb
+++ /dev/null
@@ -1,138 +0,0 @@
-# lib/tmail_extensions.rb:
-# Extensions / fixes to TMail.
-#
-# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-
-require 'racc/parser'
-require 'tmail'
-require 'tmail/scanner'
-require 'tmail/utils'
-require 'tmail/interface'
-
-# Monkeypatch!
-
-# These mainly used in app/models/incoming_message.rb
-module TMail
- class Mail
- # Monkeypatch! Adding some extra members to store extra info in.
-
- attr_accessor :url_part_number
- attr_accessor :rfc822_attachment # when a whole email message is attached as text
- attr_accessor :within_rfc822_attachment # for parts within a message attached as text (for getting subject mainly)
- attr_accessor :count_parts_count
- attr_accessor :count_first_uudecode_count
-
- # Monkeypatch! (check to see if this becomes a standard function in
- # TMail::Mail, then use that, whatever it is called)
- def Mail.get_part_file_name(part)
- file_name = (part['content-location'] &&
- part['content-location'].body) ||
- part.sub_header("content-type", "name") ||
- part.sub_header("content-disposition", "filename")
- file_name = file_name.strip if file_name
- file_name
- end
-
- # Monkeypatch! Return the name part of from address, or nil if there isn't one
- def from_name_if_present
- if self.from && self.from_addrs[0].name
- return TMail::Unquoter.unquote_and_convert_to(self.from_addrs[0].name, "utf-8")
- else
- return nil
- end
- end
-
- # Monkeypatch! Generalisation of To:, Cc:
- def envelope_to(default = nil)
- # XXX assumes only one envelope-to, and no parsing needed
- val = self.header_string('envelope-to')
- return val ? [val,] : []
- end
-
- # Monkeypatch!
- # Bug fix to this function - is for message in humberside-police-odd-mime-type.email
- # Which was originally: https://secure.mysociety.org/admin/foi/request/show_raw_email/11209
- # See test in spec/lib/tmail_extensions.rb
- def set_content_type( str, sub = nil, param = nil )
- if sub
- main, sub = str, sub
- else
- main, sub = str.split(%r</>, 2)
- raise ArgumentError, "sub type missing: #{str.inspect}" unless sub
- end
- if h = @header['content-type']
- h.main_type = main
- h.sub_type = sub
- h.params.clear if !h.params.nil? # XXX this if statement is the fix # XXX disabled until works with test
- else
- store 'Content-Type', "#{main}/#{sub}"
- end
- @header['content-type'].params.replace param if param
- str
- end
- # Need to make sure this alias calls the Monkeypatch too
- alias content_type= set_content_type
-
- end
-
- module TextUtils
- # Monkeypatch! Much more aggressive list of characters to cause quoting
- # than in normal TMail. e.g. Have found real cases where @ needs quoting.
- # We list characters to allow, rather than characters not to allow.
- NEW_PHRASE_UNSAFE=/[^A-Za-z0-9!#\$%&'*+\-\/=?^_`{|}~ ]/n
- def quote_phrase( str )
- (NEW_PHRASE_UNSAFE === str) ? dquote(str) : str
- end
- end
-end
-
-# Monkeypatch! TMail 1.2.7.1 will parse only one address out of a list of addresses with
-# unquoted display parts https://github.com/mikel/tmail/issues#issue/9 - this monkeypatch
-# fixes this issue.
-module TMail
-
- class Parser < Racc::Parser
-
-module_eval <<'..end lib/tmail/parser.y modeval..id2dd1c7d21d', 'lib/tmail/parser.y', 340
-
- def self.special_quote_address(str) #:nodoc:
- # Takes a string which is an address and adds quotation marks to special
- # edge case methods that the RACC parser can not handle.
- #
- # Right now just handles two edge cases:
- #
- # Full stop as the last character of the display name:
- # Mikel L. <mikel@me.com>
- # Returns:
- # "Mikel L." <mikel@me.com>
- #
- # Unquoted @ symbol in the display name:
- # mikel@me.com <mikel@me.com>
- # Returns:
- # "mikel@me.com" <mikel@me.com>
- #
- # Any other address not matching these patterns just gets returned as is.
- case
- # This handles the missing "" in an older version of Apple Mail.app
- # around the display name when the display name contains a '@'
- # like 'mikel@me.com <mikel@me.com>'
- # Just quotes it to: '"mikel@me.com" <mikel@me.com>'
- when str =~ /\A([^"][^<]+@[^>]+[^"])\s(<.*?>)\Z/
- return "\"#{$1}\" #{$2}"
- # This handles cases where 'Mikel A. <mikel@me.com>' which is a trailing
- # full stop before the address section. Just quotes it to
- # '"Mikel A." <mikel@me.com>'
- when str =~ /\A(.*?\.)\s(<.*?>)\s*\Z/
- return "\"#{$1}\" #{$2}"
- else
- str
- end
- end
-
-..end lib/tmail/parser.y modeval..id2dd1c7d21d
- end # class Parser
-
-end # module TMail
-
-
diff --git a/lib/mail_handler/mail_handler.rb b/lib/mail_handler/mail_handler.rb
index 8b227b9ca..d9ebee854 100644
--- a/lib/mail_handler/mail_handler.rb
+++ b/lib/mail_handler/mail_handler.rb
@@ -3,17 +3,10 @@ require 'tmpdir'
module MailHandler
- if RUBY_VERSION.to_f >= 1.9
- require 'mail'
- require 'backends/mail_extensions'
- require 'backends/mail_backend'
- include Backends::MailBackend
- else
- require 'action_mailer'
- require 'backends/tmail_extensions'
- require 'backends/tmail_backend'
- include Backends::TmailBackend
- end
+ require 'mail'
+ require 'backends/mail_extensions'
+ require 'backends/mail_backend'
+ include Backends::MailBackend
# Returns a set of attachments from the given TNEF contents
# The TNEF contents also contains the message body, but in general this is the
diff --git a/lib/old_rubygems_patch.rb b/lib/old_rubygems_patch.rb
deleted file mode 100644
index 3001a7381..000000000
--- a/lib/old_rubygems_patch.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-if File.exist? File.join(File.dirname(__FILE__),'..','vendor','rails','railties','lib','rails','gem_dependency.rb')
- require File.join(File.dirname(__FILE__),'..','vendor','rails','railties','lib','rails','gem_dependency.rb')
-else
- require 'rails/gem_dependency'
-end
-
-module Rails
- class GemDependency < Gem::Dependency
-
- # This definition of the requirement method is a patch
- if !method_defined?(:requirement)
- def requirement
- req = version_requirements
- end
- end
-
- def add_load_paths
- self.class.add_frozen_gem_path
- return if @loaded || @load_paths_added
- if framework_gem?
- @load_paths_added = @loaded = @frozen = true
- return
- end
-
- begin
- dep = Gem::Dependency.new(name, requirement)
- spec = Gem.source_index.find { |_,s| s.satisfies_requirement?(dep) }.last
- spec.activate # a way that exists
- rescue
- begin
- gem self.name, self.requirement # < 1.8 unhappy way
- # This second rescue is a patch - fall back to passing Rails::GemDependency to gem
- # for older rubygems
- rescue ArgumentError
- gem self
- end
- end
-
- @spec = Gem.loaded_specs[name]
- @frozen = @spec.loaded_from.include?(self.class.unpacked_path) if @spec
- @load_paths_added = true
- rescue Gem::LoadError
- end
- end
-
-end
diff --git a/lib/patches/fixtures_constraint_disabling.rb b/lib/patches/fixtures_constraint_disabling.rb
deleted file mode 100644
index 7d97e81f7..000000000
--- a/lib/patches/fixtures_constraint_disabling.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# An alternative way of disabling foreign keys in fixture loading in Postgres and
-# does not require superuser permissions
-# http://kopongo.com/2008/7/25/postgres-ri_constrainttrigger-error
-require 'active_record/connection_adapters/postgresql_adapter'
-module ActiveRecord
- module ConnectionAdapters
- class PostgreSQLAdapter < AbstractAdapter
- def disable_referential_integrity(&block)
- transaction {
- begin
- execute "SET CONSTRAINTS ALL DEFERRED"
- yield
- ensure
- execute "SET CONSTRAINTS ALL IMMEDIATE"
- end
- }
- end
- end
- end
-end
-
diff --git a/lib/public_body_categories.rb b/lib/public_body_categories.rb
index c6f0a6690..7f548b130 100644
--- a/lib/public_body_categories.rb
+++ b/lib/public_body_categories.rb
@@ -2,7 +2,7 @@
# Categorisations of public bodies.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
class PublicBodyCategories
diff --git a/lib/rack_quote_monkeypatch.rb b/lib/rack_quote_monkeypatch.rb
deleted file mode 100644
index b477ac0cb..000000000
--- a/lib/rack_quote_monkeypatch.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# There's a bug in Rack 1.1.x which is fixed in Rack 1.2, but our
-# current version of Rails won't use that. So for now, monkeypatch,
-# This can be dropped when we move to Rails 3.
-#
-# See https://github.com/mysociety/alaveteli/issues/38 for Alaveteli
-# bug report
-#
-# More info about the monkeypatch:
-# http://thewebfellas.com/blog/2010/7/15/rails-2-3-8-rack-1-1-and-the-curious-case-of-the-missing-quotes
-
-module Rack
- module Utils
- def parse_query(qs, d = nil)
- params = {}
-
- (qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p|
- k, v = p.split('=', 2).map { |x| unescape(x) }
- if cur = params[k]
- if cur.class == Array
- params[k] << v
- else
- params[k] = [cur, v]
- end
- else
- params[k] = v
- end
- end
-
- return params
- end
- module_function :parse_query
-
- def normalize_params(params, name, v = nil)
- name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
- k = $1 || ''
- after = $' || ''
-
- return if k.empty?
-
- if after == ""
- params[k] = v
- elsif after == "[]"
- params[k] ||= []
- raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
- params[k] << v
- elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
- child_key = $1
- params[k] ||= []
- raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
- if params[k].last.is_a?(Hash) && !params[k].last.key?(child_key)
- normalize_params(params[k].last, child_key, v)
- else
- params[k] << normalize_params({}, child_key, v)
- end
- else
- params[k] ||= {}
- raise TypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Hash)
- params[k] = normalize_params(params[k], after, v)
- end
-
- return params
- end
- module_function :normalize_params
- end
-end
diff --git a/lib/sendmail_return_path.rb b/lib/sendmail_return_path.rb
deleted file mode 100644
index 23c4d4376..000000000
--- a/lib/sendmail_return_path.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# Monkeypatch!
-# Grrr, semantics of smtp and sendmail send should be the same with regard to setting return path
-
-# See test in spec/lib/sendmail_return_path_spec.rb
-
-module ActionMailer
- class Base
- def perform_delivery_sendmail(mail)
- sender = (mail['return-path'] && mail['return-path'].spec) || mail.from.first
-
- sendmail_args = sendmail_settings[:arguments].dup
- sendmail_args += " -f \"#{sender}\""
-
- IO.popen("#{sendmail_settings[:location]} #{sendmail_args}","w+") do |sm|
- sm.print(mail.encoded.gsub(/\r/, ''))
- sm.flush
- end
- end
- end
-end
-
diff --git a/spec/fixtures/track_things_sent_emails.yml b/lib/tasks/.gitkeep
index e69de29bb..e69de29bb 100644
--- a/spec/fixtures/track_things_sent_emails.yml
+++ b/lib/tasks/.gitkeep
diff --git a/lib/tasks/rspec.rake b/lib/tasks/rspec.rake
deleted file mode 100644
index d4fd4a9ff..000000000
--- a/lib/tasks/rspec.rake
+++ /dev/null
@@ -1,148 +0,0 @@
-rspec_gem_dir = nil
-Dir["#{Rails.root}/vendor/gems/*"].each do |subdir|
- rspec_gem_dir = subdir if subdir.gsub("#{Rails.root}/vendor/gems/","") =~ /^(\w+-)?rspec-(\d+)/ && File.exist?("#{subdir}/lib/spec/rake/spectask.rb")
-end
-rspec_plugin_dir = File.expand_path(File.dirname(__FILE__) + '/../../vendor/plugins/rspec')
-
-if rspec_gem_dir && (test ?d, rspec_plugin_dir)
- raise "\n#{'*'*50}\nYou have rspec installed in both vendor/gems and vendor/plugins\nPlease pick one and dispose of the other.\n#{'*'*50}\n\n"
-end
-
-if rspec_gem_dir
- $LOAD_PATH.unshift("#{rspec_gem_dir}/lib")
-elsif File.exist?(rspec_plugin_dir)
- $LOAD_PATH.unshift("#{rspec_plugin_dir}/lib")
-end
-
-# Don't load rspec if running "rake gems:*"
-unless ARGV.any? {|a| a =~ /^gems/}
-
-begin
- require 'spec/rake/spectask'
-rescue MissingSourceFile
- module Spec
- module Rake
- class SpecTask
- if defined?(::Rake::DSL)
- include ::Rake::DSL
- end
- def initialize(name)
- task name do
- # if rspec-rails is a configured gem, this will output helpful material and exit ...
- require File.expand_path(File.join(File.dirname(__FILE__),"..","..","config","environment"))
-
- # ... otherwise, do this:
- raise <<-MSG
-
-#{"*" * 80}
-* You are trying to run an rspec rake task defined in
-* #{__FILE__},
-* but rspec can not be found in vendor/gems, vendor/plugins or system gems.
-#{"*" * 80}
-MSG
- end
- end
- end
- end
- end
-end
-
-Rake.application.instance_variable_get('@tasks').delete('default')
-
-spec_prereq = File.exist?(File.join(Rails.root, 'config', 'database.yml')) ? "db:test:prepare" : :noop
-task :noop do
-end
-
-task :default => :spec
-task :stats => "spec:statsetup"
-task :test => ['spec']
-task :cruise => ['spec']
-
-desc "Run all specs in spec directory (excluding plugin specs)"
-Spec::Rake::SpecTask.new(:spec => spec_prereq) do |t|
- t.spec_opts = ['--options', "\"#{Rails.root}/spec/spec.opts\""]
- t.spec_files = FileList['spec/**/*_spec.rb']
-end
-
-namespace :spec do
- desc "Run all specs in spec directory with RCov (excluding plugin specs)"
- Spec::Rake::SpecTask.new(:rcov) do |t|
- t.spec_opts = ['--options', "\"#{Rails.root}/spec/spec.opts\""]
- t.spec_files = FileList['spec/**/*_spec.rb']
- t.rcov = true
- t.rcov_opts = lambda do
- IO.readlines("#{Rails.root}/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
- end
- end
-
- desc "Print Specdoc for all specs (excluding plugin specs)"
- Spec::Rake::SpecTask.new(:doc) do |t|
- t.spec_opts = ["--format", "specdoc", "--dry-run"]
- t.spec_files = FileList['spec/**/*_spec.rb']
- end
-
- desc "Print Specdoc for all plugin examples"
- Spec::Rake::SpecTask.new(:plugin_doc) do |t|
- t.spec_opts = ["--format", "specdoc", "--dry-run"]
- t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*')
- end
-
- [:models, :controllers, :views, :helpers, :lib, :integration].each do |sub|
- desc "Run the code examples in spec/#{sub}"
- Spec::Rake::SpecTask.new(sub => spec_prereq) do |t|
- t.spec_opts = ['--options', "\"#{Rails.root}/spec/spec.opts\""]
- t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
- end
- end
-
- desc "Run the code examples in vendor/plugins (except RSpec's own)"
- Spec::Rake::SpecTask.new(:plugins => spec_prereq) do |t|
- t.spec_opts = ['--options', "\"#{Rails.root}/spec/spec.opts\""]
- t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*').exclude("vendor/plugins/rspec-rails/*")
- end
-
- namespace :plugins do
- desc "Runs the examples for rspec_on_rails"
- Spec::Rake::SpecTask.new(:rspec_on_rails) do |t|
- t.spec_opts = ['--options', "\"#{Rails.root}/spec/spec.opts\""]
- t.spec_files = FileList['vendor/plugins/rspec-rails/spec/**/*_spec.rb']
- end
- end
-
- # Setup specs for stats
- task :statsetup do
- require 'code_statistics'
- ::STATS_DIRECTORIES << %w(Model\ specs spec/models) if File.exist?('spec/models')
- ::STATS_DIRECTORIES << %w(View\ specs spec/views) if File.exist?('spec/views')
- ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers) if File.exist?('spec/controllers')
- ::STATS_DIRECTORIES << %w(Helper\ specs spec/helpers) if File.exist?('spec/helpers')
- ::STATS_DIRECTORIES << %w(Library\ specs spec/lib) if File.exist?('spec/lib')
- ::STATS_DIRECTORIES << %w(Routing\ specs spec/routing) if File.exist?('spec/routing')
- ::STATS_DIRECTORIES << %w(Integration\ specs spec/integration) if File.exist?('spec/integration')
- ::CodeStatistics::TEST_TYPES << "Model specs" if File.exist?('spec/models')
- ::CodeStatistics::TEST_TYPES << "View specs" if File.exist?('spec/views')
- ::CodeStatistics::TEST_TYPES << "Controller specs" if File.exist?('spec/controllers')
- ::CodeStatistics::TEST_TYPES << "Helper specs" if File.exist?('spec/helpers')
- ::CodeStatistics::TEST_TYPES << "Library specs" if File.exist?('spec/lib')
- ::CodeStatistics::TEST_TYPES << "Routing specs" if File.exist?('spec/routing')
- ::CodeStatistics::TEST_TYPES << "Integration specs" if File.exist?('spec/integration')
- end
-
- namespace :db do
- namespace :fixtures do
- desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z."
- task :load => :environment do
- ActiveRecord::Base.establish_connection(Rails.env)
- base_dir = File.join(Rails.root, 'spec', 'fixtures')
- fixtures_dir = ENV['FIXTURES_DIR'] ? File.join(base_dir, ENV['FIXTURES_DIR']) : base_dir
-
- require 'active_record/fixtures'
- (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/).map {|f| File.join(fixtures_dir, f) } : Dir.glob(File.join(fixtures_dir, '*.{yml,csv}'))).each do |fixture_file|
- Fixtures.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*'))
- end
- end
- end
- end
-end
-
-end
diff --git a/lib/tasks/themes.rake b/lib/tasks/themes.rake
index 14aa15551..cbd3d123e 100644
--- a/lib/tasks/themes.rake
+++ b/lib/tasks/themes.rake
@@ -31,7 +31,7 @@ namespace :themes do
if system(clone_command)
Dir.chdir install_path do
# First try to checkout a specific branch of the theme
- tag_checked_out = checkout_remote_branch(Configuration::theme_branch) if Configuration::theme_branch
+ tag_checked_out = checkout_remote_branch(AlaveteliConfiguration::theme_branch) if AlaveteliConfiguration::theme_branch
if !tag_checked_out
# try to checkout a tag exactly matching ALAVETELI VERSION
tag_checked_out = checkout_tag(ALAVETELI_VERSION)
@@ -94,10 +94,10 @@ namespace :themes do
desc "Install themes specified in the config file's THEME_URLS"
task :install => :environment do
verbose = true
- Configuration::theme_urls.each{ |theme_url| install_theme(theme_url, verbose) }
- if ! Configuration::theme_url.blank?
+ AlaveteliConfiguration::theme_urls.each{ |theme_url| install_theme(theme_url, verbose) }
+ if ! AlaveteliConfiguration::theme_url.blank?
# Old version of the above, for backwards compatibility
- install_theme(Configuration::theme_url, verbose, deprecated=true)
+ install_theme(AlaveteliConfiguration::theme_url, verbose, deprecated=true)
end
end
-end \ No newline at end of file
+end
diff --git a/lib/tasks/translation.rake b/lib/tasks/translation.rake
index ff07fc6f6..351faef2c 100644
--- a/lib/tasks/translation.rake
+++ b/lib/tasks/translation.rake
@@ -42,14 +42,14 @@ namespace :translation do
output_file = File.open(File.join(ENV['DIR'], 'message_preview.txt'), 'w')
# outgoing mailer
- request_email = OutgoingMailer.create_initial_request(info_request, initial_request)
+ request_email = OutgoingMailer.initial_request(info_request, initial_request)
write_email(request_email, 'Initial Request', output_file)
- followup_email = OutgoingMailer.create_followup(info_request, follow_up, nil)
+ followup_email = OutgoingMailer.followup(info_request, follow_up, nil)
write_email(followup_email, 'Follow up', output_file)
# contact mailer
- contact_email = ContactMailer.create_to_admin_message(info_request.user_name,
+ contact_email = ContactMailer.to_admin_message(info_request.user_name,
info_request.user.email,
'A test message',
'Hello!',
@@ -59,20 +59,20 @@ namespace :translation do
write_email(contact_email, 'Contact email (to admin)', output_file)
- user_contact_email = ContactMailer.create_user_message(info_request.user,
+ user_contact_email = ContactMailer.user_message(info_request.user,
info_request.user,
'http://www.example.com/user',
'A test message',
'Hello!')
write_email(user_contact_email, 'Contact email (user to user)', output_file)
- admin_contact_email = ContactMailer.create_from_admin_message(info_request.user,
+ admin_contact_email = ContactMailer.from_admin_message(info_request.user,
'A test message',
'Hello!')
write_email(admin_contact_email, 'Contact email (admin to user)', output_file)
# request mailer
- fake_response_email = RequestMailer.create_fake_response(info_request,
+ fake_response_email = RequestMailer.fake_response(info_request,
info_request.user,
"test body",
"attachment.txt",
@@ -89,54 +89,54 @@ namespace :translation do
response_mail = MailHandler.mail_from_raw_email(content)
response_mail.from = "authority@example.com"
- stopped_responses_email = RequestMailer.create_stopped_responses(info_request,
+ stopped_responses_email = RequestMailer.stopped_responses(info_request,
response_mail,
content)
write_email(stopped_responses_email,
'Bounce if someone sends email to a request that has had responses stopped',
output_file)
- requires_admin_email = RequestMailer.create_requires_admin(info_request)
+ requires_admin_email = RequestMailer.requires_admin(info_request)
write_email(requires_admin_email, 'Drawing admin attention to a response', output_file)
- new_response_email = RequestMailer.create_new_response(info_request, incoming_message)
+ new_response_email = RequestMailer.new_response(info_request, incoming_message)
write_email(new_response_email,
'Telling the requester that a new response has arrived',
output_file)
- overdue_alert_email = RequestMailer.create_overdue_alert(info_request, info_request.user)
+ overdue_alert_email = RequestMailer.overdue_alert(info_request, info_request.user)
write_email(overdue_alert_email,
'Telling the requester that the public body is late in replying',
output_file)
- very_overdue_alert_email = RequestMailer.create_very_overdue_alert(info_request, info_request.user)
+ very_overdue_alert_email = RequestMailer.very_overdue_alert(info_request, info_request.user)
write_email(very_overdue_alert_email,
'Telling the requester that the public body is very late in replying',
output_file)
- response_reminder_alert_email = RequestMailer.create_new_response_reminder_alert(info_request,
+ response_reminder_alert_email = RequestMailer.new_response_reminder_alert(info_request,
incoming_message)
write_email(response_reminder_alert_email,
'Telling the requester that they need to say if the new response contains info or not',
output_file)
- old_unclassified_email = RequestMailer.create_old_unclassified_updated(info_request)
+ old_unclassified_email = RequestMailer.old_unclassified_updated(info_request)
write_email(old_unclassified_email,
'Telling the requester that someone updated their old unclassified request',
output_file)
- not_clarified_alert_email = RequestMailer.create_not_clarified_alert(info_request, incoming_message)
+ not_clarified_alert_email = RequestMailer.not_clarified_alert(info_request, incoming_message)
write_email(not_clarified_alert_email,
'Telling the requester that they need to clarify their request',
output_file)
- comment_on_alert_email = RequestMailer.create_comment_on_alert(info_request, comment)
+ comment_on_alert_email = RequestMailer.comment_on_alert(info_request, comment)
write_email(comment_on_alert_email,
'Telling requester that somebody added an annotation to their request',
output_file)
- comment_on_alert_plural_email = RequestMailer.create_comment_on_alert_plural(info_request, 2, comment)
+ comment_on_alert_plural_email = RequestMailer.comment_on_alert_plural(info_request, 2, comment)
write_email(comment_on_alert_plural_email,
'Telling requester that somebody added multiple annotations to their request',
output_file)
@@ -149,38 +149,38 @@ namespace :translation do
nil,
100,
1)
- event_digest_email = TrackMailer.create_event_digest(info_request.user,
+ event_digest_email = TrackMailer.event_digest(info_request.user,
[[track_thing,
xapian_object.results,
xapian_object]])
write_email(event_digest_email, 'Alerts on things the user is tracking', output_file)
# user mailer
- site_name = Configuration::site_name
+ site_name = AlaveteliConfiguration::site_name
reasons = {
:web => "",
:email => _("Then you can sign in to {{site_name}}", :site_name => site_name),
:email_subject => _("Confirm your account on {{site_name}}", :site_name => site_name)
}
- confirm_login_email = UserMailer.create_confirm_login(info_request.user,
+ confirm_login_email = UserMailer.confirm_login(info_request.user,
reasons,
'http://www.example.com')
write_email(confirm_login_email, 'Confirm a user login', output_file)
- already_registered_email = UserMailer.create_already_registered(info_request.user,
+ already_registered_email = UserMailer.already_registered(info_request.user,
reasons,
'http://www.example.com')
write_email(already_registered_email, 'Tell a user they are already registered', output_file)
new_email = 'new_email@example.com'
- changeemail_confirm_email = UserMailer.create_changeemail_confirm(info_request.user,
+ changeemail_confirm_email = UserMailer.changeemail_confirm(info_request.user,
new_email,
'http://www.example.com')
write_email(changeemail_confirm_email,
'Confirm that the user wants to change their email',
output_file)
- changeemail_already_used = UserMailer.create_changeemail_already_used('old_email@example.com',
+ changeemail_already_used = UserMailer.changeemail_already_used('old_email@example.com',
new_email)
write_email(changeemail_already_used,
'Tell a user that the email they want to change to is already used',
@@ -189,4 +189,4 @@ namespace :translation do
output_file.close
end
-end \ No newline at end of file
+end
diff --git a/lib/timezone_fixes.rb b/lib/timezone_fixes.rb
deleted file mode 100644
index 1bf326ccd..000000000
--- a/lib/timezone_fixes.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# Taken from
-# https://rails.lighthouseapp.com/projects/8994/tickets/2946
-# http://github.com/rails/rails/commit/6f97ad07ded847f29159baf71050c63f04282170
-
-# Otherwise times get stored wrong during British Summer Time
-
-# Hopefully fixed in later Rails. There is a test in spec/lib/timezone_fixes_spec.rb
-
-# This fix is applied in Rails 3.x. So, should be possible to remove this then!
-
-# Monkeypatch!
-module ActiveRecord
- module ConnectionAdapters # :nodoc:
- module Quoting
- def quoted_date(value)
- if value.acts_like?(:time)
- zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
- value.respond_to?(zone_conversion_method) ? value.send(zone_conversion_method) : value
- else
- value
- end.to_s(:db)
- end
- end
- end
-end
-
diff --git a/lib/willpaginate_extension.rb b/lib/willpaginate_extension.rb
index 3cdb0ae60..fa58bd9f0 100644
--- a/lib/willpaginate_extension.rb
+++ b/lib/willpaginate_extension.rb
@@ -1,6 +1,6 @@
# this extension is loaded in environment.rb
module WillPaginateExtension
- class LinkRenderer < WillPaginate::LinkRenderer
+ class LinkRenderer < WillPaginate::ActionView::LinkRenderer
def page_link(page, text, attributes = {})
# Hack for admin pages, when proxied via https on mySociety servers, they
# need a relative URL.
diff --git a/public/404.html b/public/404.html
index eff660b90..9a48320a5 100644
--- a/public/404.html
+++ b/public/404.html
@@ -1,23 +1,19 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-
+<!DOCTYPE html>
+<html>
<head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>The page you were looking for doesn't exist (404)</title>
- <style type="text/css">
- body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
- div.dialog {
- width: 25em;
- padding: 0 4em;
- margin: 4em auto 0 auto;
- border: 1px solid #ccc;
- border-right-color: #999;
- border-bottom-color: #999;
- }
- h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
- </style>
+ <style type="text/css">
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+ div.dialog {
+ width: 25em;
+ padding: 0 4em;
+ margin: 4em auto 0 auto;
+ border: 1px solid #ccc;
+ border-right-color: #999;
+ border-bottom-color: #999;
+ }
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+ </style>
</head>
<body>
@@ -27,4 +23,4 @@
<p>You may have mistyped the address or the page may have moved.</p>
</div>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/public/422.html b/public/422.html
new file mode 100644
index 000000000..83660ab18
--- /dev/null
+++ b/public/422.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The change you wanted was rejected (422)</title>
+ <style type="text/css">
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+ div.dialog {
+ width: 25em;
+ padding: 0 4em;
+ margin: 4em auto 0 auto;
+ border: 1px solid #ccc;
+ border-right-color: #999;
+ border-bottom-color: #999;
+ }
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+ </style>
+</head>
+
+<body>
+ <!-- This file lives in public/422.html -->
+ <div class="dialog">
+ <h1>The change you wanted was rejected.</h1>
+ <p>Maybe you tried to change something you didn't have access to.</p>
+ </div>
+</body>
+</html>
diff --git a/public/500.html b/public/500.html
index f0aee0e9f..b80307fc1 100644
--- a/public/500.html
+++ b/public/500.html
@@ -1,23 +1,19 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-
+<!DOCTYPE html>
+<html>
<head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
- <title>We're sorry, but something went wrong</title>
- <style type="text/css">
- body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
- div.dialog {
- width: 25em;
- padding: 0 4em;
- margin: 4em auto 0 auto;
- border: 1px solid #ccc;
- border-right-color: #999;
- border-bottom-color: #999;
- }
- h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
- </style>
+ <title>We're sorry, but something went wrong (500)</title>
+ <style type="text/css">
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
+ div.dialog {
+ width: 25em;
+ padding: 0 4em;
+ margin: 4em auto 0 auto;
+ border: 1px solid #ccc;
+ border-right-color: #999;
+ border-bottom-color: #999;
+ }
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
+ </style>
</head>
<body>
@@ -27,4 +23,4 @@
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
</div>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/public/dispatch.cgi b/public/dispatch.cgi
deleted file mode 100755
index 3848806db..000000000
--- a/public/dispatch.cgi
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/ruby1.8
-
-require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
-
-# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
-# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
-require "dispatcher"
-
-ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
-Dispatcher.dispatch \ No newline at end of file
diff --git a/public/dispatch.fcgi b/public/dispatch.fcgi
deleted file mode 100755
index ad34d90e4..000000000
--- a/public/dispatch.fcgi
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/ruby1.8
-#
-# You may specify the path to the FastCGI crash log (a log of unhandled
-# exceptions which forced the FastCGI instance to exit, great for debugging)
-# and the number of requests to process before running garbage collection.
-#
-# By default, the FastCGI crash log is Rails.root/log/fastcgi.crash.log
-# and the GC period is nil (turned off). A reasonable number of requests
-# could range from 10-100 depending on the memory footprint of your app.
-#
-# Example:
-# # Default log path, normal GC behavior.
-# RailsFCGIHandler.process!
-#
-# # Default log path, 50 requests between GC.
-# RailsFCGIHandler.process! nil, 50
-#
-# # Custom log path, normal GC behavior.
-# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
-#
-require File.dirname(__FILE__) + "/../config/environment"
-require 'fcgi_handler'
-
-RailsFCGIHandler.process!
diff --git a/public/dispatch.rb b/public/dispatch.rb
deleted file mode 100755
index 3848806db..000000000
--- a/public/dispatch.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/ruby1.8
-
-require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
-
-# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
-# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
-require "dispatcher"
-
-ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
-Dispatcher.dispatch \ No newline at end of file
diff --git a/public/javascripts/controls.js b/public/javascripts/controls.js
index 5aaf0bb2b..7392fb664 100644
--- a/public/javascripts/controls.js
+++ b/public/javascripts/controls.js
@@ -1,22 +1,24 @@
-// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
-// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
+// script.aculo.us controls.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
+
+// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005-2009 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+// (c) 2005-2009 Jon Tirsen (http://www.tirsen.com)
// Contributors:
// Richard Livsey
// Rahul Bhargava
// Rob Wills
-//
+//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/
-// Autocompleter.Base handles all the autocompletion functionality
+// Autocompleter.Base handles all the autocompletion functionality
// that's independent of the data source for autocompletion. This
// includes drawing the autocompletion menu, observing keyboard
// and mouse events, and similar.
//
-// Specific autocompleters need to provide, at the very least,
+// Specific autocompleters need to provide, at the very least,
// a getUpdatedChoices function that will be invoked every time
-// the text inside the monitored textbox changes. This method
+// the text inside the monitored textbox changes. This method
// should get the text for which to provide autocompletion by
// invoking this.getToken(), NOT by directly accessing
// this.element.value. This is to allow incremental tokenized
@@ -30,23 +32,23 @@
// will incrementally autocomplete with a comma as the token.
// Additionally, ',' in the above example can be replaced with
// a token array, e.g. { tokens: [',', '\n'] } which
-// enables autocompletion on multiple tokens. This is most
-// useful when one of the tokens is \n (a newline), as it
+// enables autocompletion on multiple tokens. This is most
+// useful when one of the tokens is \n (a newline), as it
// allows smart autocompletion after linebreaks.
if(typeof Effect == 'undefined')
throw("controls.js requires including script.aculo.us' effects.js library");
-var Autocompleter = { }
+var Autocompleter = { };
Autocompleter.Base = Class.create({
baseInitialize: function(element, update, options) {
- element = $(element)
- this.element = element;
- this.update = $(update);
- this.hasFocus = false;
- this.changed = false;
- this.active = false;
- this.index = 0;
+ element = $(element);
+ this.element = element;
+ this.update = $(update);
+ this.hasFocus = false;
+ this.changed = false;
+ this.active = false;
+ this.index = 0;
this.entryCount = 0;
this.oldElementValue = this.element.value;
@@ -59,28 +61,28 @@ Autocompleter.Base = Class.create({
this.options.tokens = this.options.tokens || [];
this.options.frequency = this.options.frequency || 0.4;
this.options.minChars = this.options.minChars || 1;
- this.options.onShow = this.options.onShow ||
- function(element, update){
+ this.options.onShow = this.options.onShow ||
+ function(element, update){
if(!update.style.position || update.style.position=='absolute') {
update.style.position = 'absolute';
Position.clone(element, update, {
- setHeight: false,
+ setHeight: false,
offsetTop: element.offsetHeight
});
}
Effect.Appear(update,{duration:0.15});
};
- this.options.onHide = this.options.onHide ||
+ this.options.onHide = this.options.onHide ||
function(element, update){ new Effect.Fade(update,{duration:0.15}) };
- if(typeof(this.options.tokens) == 'string')
+ if(typeof(this.options.tokens) == 'string')
this.options.tokens = new Array(this.options.tokens);
// Force carriage returns as token delimiters anyway
if (!this.options.tokens.include('\n'))
this.options.tokens.push('\n');
this.observer = null;
-
+
this.element.setAttribute('autocomplete','off');
Element.hide(this.update);
@@ -91,10 +93,10 @@ Autocompleter.Base = Class.create({
show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
- if(!this.iefix &&
+ if(!this.iefix &&
(Prototype.Browser.IE) &&
(Element.getStyle(this.update, 'position')=='absolute')) {
- new Insertion.After(this.update,
+ new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
@@ -102,7 +104,7 @@ Autocompleter.Base = Class.create({
}
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
},
-
+
fixIEOverlapping: function() {
Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
this.iefix.style.zIndex = 1;
@@ -150,15 +152,15 @@ Autocompleter.Base = Class.create({
Event.stop(event);
return;
}
- else
- if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
+ else
+ if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
(Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
this.changed = true;
this.hasFocus = true;
if(this.observer) clearTimeout(this.observer);
- this.observer =
+ this.observer =
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
},
@@ -170,35 +172,35 @@ Autocompleter.Base = Class.create({
onHover: function(event) {
var element = Event.findElement(event, 'LI');
- if(this.index != element.autocompleteIndex)
+ if(this.index != element.autocompleteIndex)
{
this.index = element.autocompleteIndex;
this.render();
}
Event.stop(event);
},
-
+
onClick: function(event) {
var element = Event.findElement(event, 'LI');
this.index = element.autocompleteIndex;
this.selectEntry();
this.hide();
},
-
+
onBlur: function(event) {
// needed to make click events working
setTimeout(this.hide.bind(this), 250);
this.hasFocus = false;
- this.active = false;
- },
-
+ this.active = false;
+ },
+
render: function() {
if(this.entryCount > 0) {
for (var i = 0; i < this.entryCount; i++)
- this.index==i ?
- Element.addClassName(this.getEntry(i),"selected") :
+ this.index==i ?
+ Element.addClassName(this.getEntry(i),"selected") :
Element.removeClassName(this.getEntry(i),"selected");
- if(this.hasFocus) {
+ if(this.hasFocus) {
this.show();
this.active = true;
}
@@ -207,27 +209,27 @@ Autocompleter.Base = Class.create({
this.hide();
}
},
-
+
markPrevious: function() {
- if(this.index > 0) this.index--
+ if(this.index > 0) this.index--;
else this.index = this.entryCount-1;
this.getEntry(this.index).scrollIntoView(true);
},
-
+
markNext: function() {
- if(this.index < this.entryCount-1) this.index++
+ if(this.index < this.entryCount-1) this.index++;
else this.index = 0;
this.getEntry(this.index).scrollIntoView(false);
},
-
+
getEntry: function(index) {
return this.update.firstChild.childNodes[index];
},
-
+
getCurrentEntry: function() {
return this.getEntry(this.index);
},
-
+
selectEntry: function() {
this.active = false;
this.updateElement(this.getCurrentEntry());
@@ -244,7 +246,7 @@ Autocompleter.Base = Class.create({
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
} else
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
-
+
var bounds = this.getTokenBounds();
if (bounds[0] != -1) {
var newValue = this.element.value.substr(0, bounds[0]);
@@ -257,7 +259,7 @@ Autocompleter.Base = Class.create({
}
this.oldElementValue = this.element.value;
this.element.focus();
-
+
if (this.options.afterUpdateElement)
this.options.afterUpdateElement(this.element, selectedElement);
},
@@ -269,20 +271,20 @@ Autocompleter.Base = Class.create({
Element.cleanWhitespace(this.update.down());
if(this.update.firstChild && this.update.down().childNodes) {
- this.entryCount =
+ this.entryCount =
this.update.down().childNodes.length;
for (var i = 0; i < this.entryCount; i++) {
var entry = this.getEntry(i);
entry.autocompleteIndex = i;
this.addObservers(entry);
}
- } else {
+ } else {
this.entryCount = 0;
}
this.stopIndicator();
this.index = 0;
-
+
if(this.entryCount==1 && this.options.autoSelect) {
this.selectEntry();
this.hide();
@@ -298,7 +300,7 @@ Autocompleter.Base = Class.create({
},
onObserverEvent: function() {
- this.changed = false;
+ this.changed = false;
this.tokenBounds = null;
if(this.getToken().length>=this.options.minChars) {
this.getUpdatedChoices();
@@ -351,16 +353,16 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
getUpdatedChoices: function() {
this.startIndicator();
-
- var entry = encodeURIComponent(this.options.paramName) + '=' +
+
+ var entry = encodeURIComponent(this.options.paramName) + '=' +
encodeURIComponent(this.getToken());
this.options.parameters = this.options.callback ?
this.options.callback(this.element, entry) : entry;
- if(this.options.defaultParams)
+ if(this.options.defaultParams)
this.options.parameters += '&' + this.options.defaultParams;
-
+
new Ajax.Request(this.url, this.options);
},
@@ -382,7 +384,7 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
// - choices - How many autocompletion choices to offer
//
// - partialSearch - If false, the autocompleter will match entered
-// text only at the beginning of strings in the
+// text only at the beginning of strings in the
// autocomplete array. Defaults to true, which will
// match text at the beginning of any *word* in the
// strings in the autocomplete array. If you want to
@@ -399,7 +401,7 @@ Ajax.Autocompleter = Class.create(Autocompleter.Base, {
// - ignoreCase - Whether to ignore case when autocompleting.
// Defaults to true.
//
-// It's possible to pass in a custom function as the 'selector'
+// It's possible to pass in a custom function as the 'selector'
// option, if you prefer to write your own autocompletion logic.
// In that case, the other options above will not apply unless
// you support them.
@@ -427,20 +429,20 @@ Autocompleter.Local = Class.create(Autocompleter.Base, {
var entry = instance.getToken();
var count = 0;
- for (var i = 0; i < instance.options.array.length &&
- ret.length < instance.options.choices ; i++) {
+ for (var i = 0; i < instance.options.array.length &&
+ ret.length < instance.options.choices ; i++) {
var elem = instance.options.array[i];
- var foundPos = instance.options.ignoreCase ?
- elem.toLowerCase().indexOf(entry.toLowerCase()) :
+ var foundPos = instance.options.ignoreCase ?
+ elem.toLowerCase().indexOf(entry.toLowerCase()) :
elem.indexOf(entry);
while (foundPos != -1) {
- if (foundPos == 0 && elem.length != entry.length) {
- ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
+ if (foundPos == 0 && elem.length != entry.length) {
+ ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
elem.substr(entry.length) + "</li>");
break;
- } else if (entry.length >= instance.options.partialChars &&
+ } else if (entry.length >= instance.options.partialChars &&
instance.options.partialSearch && foundPos != -1) {
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
@@ -450,14 +452,14 @@ Autocompleter.Local = Class.create(Autocompleter.Base, {
}
}
- foundPos = instance.options.ignoreCase ?
- elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
+ foundPos = instance.options.ignoreCase ?
+ elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
elem.indexOf(entry, foundPos + 1);
}
}
if (partial.length)
- ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
+ ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
return "<ul>" + ret.join('') + "</ul>";
}
}, options || { });
@@ -474,7 +476,7 @@ Field.scrollFreeActivate = function(field) {
setTimeout(function() {
Field.activate(field);
}, 1);
-}
+};
Ajax.InPlaceEditor = Class.create({
initialize: function(element, url, options) {
@@ -604,7 +606,7 @@ Ajax.InPlaceEditor = Class.create({
this.triggerCallback('onEnterHover');
},
getText: function() {
- return this.element.innerHTML;
+ return this.element.innerHTML.unescapeHTML();
},
handleAJAXFailure: function(transport) {
this.triggerCallback('onFailure', transport);
@@ -780,7 +782,7 @@ Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
onSuccess: function(transport) {
var js = transport.responseText.strip();
if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
- throw 'Server returned an invalid collection representation.';
+ throw('Server returned an invalid collection representation.');
this._collection = eval(js);
this.checkForExternalText();
}.bind(this),
@@ -937,7 +939,7 @@ Ajax.InPlaceCollectionEditor.DefaultOptions = {
loadingCollectionText: 'Loading options...'
};
-// Delayed observer, like Form.Element.Observer,
+// Delayed observer, like Form.Element.Observer,
// but waits for delay after last key input
// Ideal for live-search fields
@@ -947,7 +949,7 @@ Form.Element.DelayedObserver = Class.create({
this.element = $(element);
this.callback = callback;
this.timer = null;
- this.lastValue = $F(this.element);
+ this.lastValue = $F(this.element);
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
},
delayedListener: function(event) {
@@ -960,4 +962,4 @@ Form.Element.DelayedObserver = Class.create({
this.timer = null;
this.callback(this.element, $F(this.element));
}
-});
+}); \ No newline at end of file
diff --git a/public/javascripts/dragdrop.js b/public/javascripts/dragdrop.js
index bf5cfea66..15c6dbca6 100644
--- a/public/javascripts/dragdrop.js
+++ b/public/javascripts/dragdrop.js
@@ -1,6 +1,7 @@
-// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
-//
+// script.aculo.us dragdrop.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
+
+// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/
@@ -32,7 +33,7 @@ var Droppables = {
options._containers.push($(containment));
}
}
-
+
if(options.accept) options.accept = [options.accept].flatten();
Element.makePositioned(element); // fix IE
@@ -40,34 +41,34 @@ var Droppables = {
this.drops.push(options);
},
-
+
findDeepestChild: function(drops) {
deepest = drops[0];
-
+
for (i = 1; i < drops.length; ++i)
if (Element.isParent(drops[i].element, deepest.element))
deepest = drops[i];
-
+
return deepest;
},
isContained: function(element, drop) {
var containmentNode;
if(drop.tree) {
- containmentNode = element.treeNode;
+ containmentNode = element.treeNode;
} else {
containmentNode = element.parentNode;
}
return drop._containers.detect(function(c) { return containmentNode == c });
},
-
+
isAffected: function(point, element, drop) {
return (
(drop.element!=element) &&
((!drop._containers) ||
this.isContained(element, drop)) &&
((!drop.accept) ||
- (Element.classNames(element).detect(
+ (Element.classNames(element).detect(
function(v) { return drop.accept.include(v) } ) )) &&
Position.within(drop.element, point[0], point[1]) );
},
@@ -87,12 +88,12 @@ var Droppables = {
show: function(point, element) {
if(!this.drops.length) return;
var drop, affected = [];
-
+
this.drops.each( function(drop) {
if(Droppables.isAffected(point, element, drop))
affected.push(drop);
});
-
+
if(affected.length>0)
drop = Droppables.findDeepestChild(affected);
@@ -101,7 +102,7 @@ var Droppables = {
Position.within(drop.element, point[0], point[1]);
if(drop.onHover)
drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
-
+
if (drop != this.last_active) Droppables.activate(drop);
}
},
@@ -112,8 +113,8 @@ var Droppables = {
if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
if (this.last_active.onDrop) {
- this.last_active.onDrop(element, this.last_active.element, event);
- return true;
+ this.last_active.onDrop(element, this.last_active.element, event);
+ return true;
}
},
@@ -121,25 +122,25 @@ var Droppables = {
if(this.last_active)
this.deactivate(this.last_active);
}
-}
+};
var Draggables = {
drags: [],
observers: [],
-
+
register: function(draggable) {
if(this.drags.length == 0) {
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this);
-
+
Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress);
}
this.drags.push(draggable);
},
-
+
unregister: function(draggable) {
this.drags = this.drags.reject(function(d) { return d==draggable });
if(this.drags.length == 0) {
@@ -148,24 +149,24 @@ var Draggables = {
Event.stopObserving(document, "keypress", this.eventKeypress);
}
},
-
+
activate: function(draggable) {
- if(draggable.options.delay) {
- this._timeout = setTimeout(function() {
- Draggables._timeout = null;
- window.focus();
- Draggables.activeDraggable = draggable;
- }.bind(this), draggable.options.delay);
+ if(draggable.options.delay) {
+ this._timeout = setTimeout(function() {
+ Draggables._timeout = null;
+ window.focus();
+ Draggables.activeDraggable = draggable;
+ }.bind(this), draggable.options.delay);
} else {
window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
this.activeDraggable = draggable;
}
},
-
+
deactivate: function() {
this.activeDraggable = null;
},
-
+
updateDrag: function(event) {
if(!this.activeDraggable) return;
var pointer = [Event.pointerX(event), Event.pointerY(event)];
@@ -173,36 +174,36 @@ var Draggables = {
// the same coordinates, prevent needless redrawing (moz bug?)
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
this._lastPointer = pointer;
-
+
this.activeDraggable.updateDrag(event, pointer);
},
-
+
endDrag: function(event) {
- if(this._timeout) {
- clearTimeout(this._timeout);
- this._timeout = null;
+ if(this._timeout) {
+ clearTimeout(this._timeout);
+ this._timeout = null;
}
if(!this.activeDraggable) return;
this._lastPointer = null;
this.activeDraggable.endDrag(event);
this.activeDraggable = null;
},
-
+
keyPress: function(event) {
if(this.activeDraggable)
this.activeDraggable.keyPress(event);
},
-
+
addObserver: function(observer) {
this.observers.push(observer);
this._cacheObserverCallbacks();
},
-
+
removeObserver: function(element) { // element instead of observer fixes mem leaks
this.observers = this.observers.reject( function(o) { return o.element==element });
this._cacheObserverCallbacks();
},
-
+
notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
if(this[eventName+'Count'] > 0)
this.observers.each( function(o) {
@@ -210,7 +211,7 @@ var Draggables = {
});
if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
},
-
+
_cacheObserverCallbacks: function() {
['onStart','onEnd','onDrag'].each( function(eventName) {
Draggables[eventName+'Count'] = Draggables.observers.select(
@@ -218,7 +219,7 @@ var Draggables = {
).length;
});
}
-}
+};
/*--------------------------------------------------------------------------*/
@@ -234,12 +235,12 @@ var Draggable = Class.create({
},
endeffect: function(element) {
var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
- new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
+ new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
queue: {scope:'_draggable', position:'end'},
- afterFinish: function(){
- Draggable._dragging[element] = false
+ afterFinish: function(){
+ Draggable._dragging[element] = false
}
- });
+ });
},
zindex: 1000,
revert: false,
@@ -250,57 +251,57 @@ var Draggable = Class.create({
snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
delay: 0
};
-
+
if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
Object.extend(defaults, {
starteffect: function(element) {
element._opacity = Element.getOpacity(element);
Draggable._dragging[element] = true;
- new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
+ new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
}
});
-
+
var options = Object.extend(defaults, arguments[1] || { });
this.element = $(element);
-
+
if(options.handle && Object.isString(options.handle))
this.handle = this.element.down('.'+options.handle, 0);
-
+
if(!this.handle) this.handle = $(options.handle);
if(!this.handle) this.handle = this.element;
-
+
if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
options.scroll = $(options.scroll);
this._isScrollChild = Element.childOf(this.element, options.scroll);
}
- Element.makePositioned(this.element); // fix IE
+ Element.makePositioned(this.element); // fix IE
this.options = options;
- this.dragging = false;
+ this.dragging = false;
this.eventMouseDown = this.initDrag.bindAsEventListener(this);
Event.observe(this.handle, "mousedown", this.eventMouseDown);
-
+
Draggables.register(this);
},
-
+
destroy: function() {
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
Draggables.unregister(this);
},
-
+
currentDelta: function() {
return([
parseInt(Element.getStyle(this.element,'left') || '0'),
parseInt(Element.getStyle(this.element,'top') || '0')]);
},
-
+
initDrag: function(event) {
if(!Object.isUndefined(Draggable._dragging[this.element]) &&
Draggable._dragging[this.element]) return;
- if(Event.isLeftClick(event)) {
+ if(Event.isLeftClick(event)) {
// abort on form elements, fixes a Firefox issue
var src = Event.element(event);
if((tag_name = src.tagName.toUpperCase()) && (
@@ -309,34 +310,34 @@ var Draggable = Class.create({
tag_name=='OPTION' ||
tag_name=='BUTTON' ||
tag_name=='TEXTAREA')) return;
-
+
var pointer = [Event.pointerX(event), Event.pointerY(event)];
- var pos = Position.cumulativeOffset(this.element);
+ var pos = this.element.cumulativeOffset();
this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
-
+
Draggables.activate(this);
Event.stop(event);
}
},
-
+
startDrag: function(event) {
this.dragging = true;
if(!this.delta)
this.delta = this.currentDelta();
-
+
if(this.options.zindex) {
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
this.element.style.zIndex = this.options.zindex;
}
-
+
if(this.options.ghosting) {
this._clone = this.element.cloneNode(true);
- this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
- if (!this.element._originallyAbsolute)
+ this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
+ if (!this._originallyAbsolute)
Position.absolutize(this.element);
this.element.parentNode.insertBefore(this._clone, this.element);
}
-
+
if(this.options.scroll) {
if (this.options.scroll == window) {
var where = this._getWindowScroll(this.options.scroll);
@@ -347,28 +348,28 @@ var Draggable = Class.create({
this.originalScrollTop = this.options.scroll.scrollTop;
}
}
-
+
Draggables.notify('onStart', this, event);
-
+
if(this.options.starteffect) this.options.starteffect(this.element);
},
-
+
updateDrag: function(event, pointer) {
if(!this.dragging) this.startDrag(event);
-
+
if(!this.options.quiet){
Position.prepare();
Droppables.show(pointer, this.element);
}
-
+
Draggables.notify('onDrag', this, event);
-
+
this.draw(pointer);
if(this.options.change) this.options.change(this);
-
+
if(this.options.scroll) {
this.stopScrolling();
-
+
var p;
if (this.options.scroll == window) {
with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
@@ -386,16 +387,16 @@ var Draggable = Class.create({
if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
this.startScrolling(speed);
}
-
+
// fix AppleWebKit rendering
if(Prototype.Browser.WebKit) window.scrollBy(0,0);
-
+
Event.stop(event);
},
-
+
finishDrag: function(event, success) {
this.dragging = false;
-
+
if(this.options.quiet){
Position.prepare();
var pointer = [Event.pointerX(event), Event.pointerY(event)];
@@ -403,24 +404,24 @@ var Draggable = Class.create({
}
if(this.options.ghosting) {
- if (!this.element._originallyAbsolute)
+ if (!this._originallyAbsolute)
Position.relativize(this.element);
- delete this.element._originallyAbsolute;
+ delete this._originallyAbsolute;
Element.remove(this._clone);
this._clone = null;
}
- var dropped = false;
- if(success) {
- dropped = Droppables.fire(event, this.element);
- if (!dropped) dropped = false;
+ var dropped = false;
+ if(success) {
+ dropped = Droppables.fire(event, this.element);
+ if (!dropped) dropped = false;
}
if(dropped && this.options.onDropped) this.options.onDropped(this.element);
Draggables.notify('onEnd', this, event);
var revert = this.options.revert;
if(revert && Object.isFunction(revert)) revert = revert(this.element);
-
+
var d = this.currentDelta();
if(revert && this.options.reverteffect) {
if (dropped == 0 || revert != 'failure')
@@ -433,67 +434,67 @@ var Draggable = Class.create({
if(this.options.zindex)
this.element.style.zIndex = this.originalZ;
- if(this.options.endeffect)
+ if(this.options.endeffect)
this.options.endeffect(this.element);
-
+
Draggables.deactivate(this);
Droppables.reset();
},
-
+
keyPress: function(event) {
if(event.keyCode!=Event.KEY_ESC) return;
this.finishDrag(event, false);
Event.stop(event);
},
-
+
endDrag: function(event) {
if(!this.dragging) return;
this.stopScrolling();
this.finishDrag(event, true);
Event.stop(event);
},
-
+
draw: function(point) {
- var pos = Position.cumulativeOffset(this.element);
+ var pos = this.element.cumulativeOffset();
if(this.options.ghosting) {
var r = Position.realOffset(this.element);
pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
}
-
+
var d = this.currentDelta();
pos[0] -= d[0]; pos[1] -= d[1];
-
+
if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
}
-
- var p = [0,1].map(function(i){
- return (point[i]-pos[i]-this.offset[i])
+
+ var p = [0,1].map(function(i){
+ return (point[i]-pos[i]-this.offset[i])
}.bind(this));
-
+
if(this.options.snap) {
if(Object.isFunction(this.options.snap)) {
p = this.options.snap(p[0],p[1],this);
} else {
if(Object.isArray(this.options.snap)) {
p = p.map( function(v, i) {
- return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this))
+ return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
} else {
p = p.map( function(v) {
- return (v/this.options.snap).round()*this.options.snap }.bind(this))
+ return (v/this.options.snap).round()*this.options.snap }.bind(this));
}
}}
-
+
var style = this.element.style;
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
style.left = p[0] + "px";
if((!this.options.constraint) || (this.options.constraint=='vertical'))
style.top = p[1] + "px";
-
+
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
},
-
+
stopScrolling: function() {
if(this.scrollInterval) {
clearInterval(this.scrollInterval);
@@ -501,14 +502,14 @@ var Draggable = Class.create({
Draggables._lastScrollPointer = null;
}
},
-
+
startScrolling: function(speed) {
if(!(speed[0] || speed[1])) return;
this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
this.lastScrolled = new Date();
this.scrollInterval = setInterval(this.scroll.bind(this), 10);
},
-
+
scroll: function() {
var current = new Date();
var delta = current - this.lastScrolled;
@@ -524,7 +525,7 @@ var Draggable = Class.create({
this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
}
-
+
Position.prepare();
Droppables.show(Draggables._lastPointer, this.element);
Draggables.notify('onDrag', this);
@@ -538,10 +539,10 @@ var Draggable = Class.create({
Draggables._lastScrollPointer[1] = 0;
this.draw(Draggables._lastScrollPointer);
}
-
+
if(this.options.change) this.options.change(this);
},
-
+
_getWindowScroll: function(w) {
var T, L, W, H;
with (w.document) {
@@ -560,7 +561,7 @@ var Draggable = Class.create({
H = documentElement.clientHeight;
} else {
W = body.offsetWidth;
- H = body.offsetHeight
+ H = body.offsetHeight;
}
}
return { top: T, left: L, width: W, height: H };
@@ -577,11 +578,11 @@ var SortableObserver = Class.create({
this.observer = observer;
this.lastValue = Sortable.serialize(this.element);
},
-
+
onStart: function() {
this.lastValue = Sortable.serialize(this.element);
},
-
+
onEnd: function() {
Sortable.unmark();
if(this.lastValue != Sortable.serialize(this.element))
@@ -591,11 +592,11 @@ var SortableObserver = Class.create({
var Sortable = {
SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
-
+
sortables: { },
-
+
_findRootElement: function(element) {
- while (element.tagName.toUpperCase() != "BODY") {
+ while (element.tagName.toUpperCase() != "BODY") {
if(element.id && Sortable.sortables[element.id]) return element;
element = element.parentNode;
}
@@ -606,22 +607,23 @@ var Sortable = {
if(!element) return;
return Sortable.sortables[element.id];
},
-
+
destroy: function(element){
- var s = Sortable.options(element);
-
+ element = $(element);
+ var s = Sortable.sortables[element.id];
+
if(s) {
Draggables.removeObserver(s.element);
s.droppables.each(function(d){ Droppables.remove(d) });
s.draggables.invoke('destroy');
-
+
delete Sortable.sortables[s.element.id];
}
},
create: function(element) {
element = $(element);
- var options = Object.extend({
+ var options = Object.extend({
element: element,
tag: 'li', // assumes li children, override with tag: 'tagname'
dropOnEmpty: false,
@@ -635,17 +637,17 @@ var Sortable = {
delay: 0,
hoverclass: null,
ghosting: false,
- quiet: false,
+ quiet: false,
scroll: false,
scrollSensitivity: 20,
scrollSpeed: 15,
format: this.SERIALIZE_RULE,
-
- // these take arrays of elements or ids and can be
+
+ // these take arrays of elements or ids and can be
// used for better initialization performance
elements: false,
handles: false,
-
+
onChange: Prototype.emptyFunction,
onUpdate: Prototype.emptyFunction
}, arguments[1] || { });
@@ -682,24 +684,24 @@ var Sortable = {
if(options.zindex)
options_for_draggable.zindex = options.zindex;
- // build options for the droppables
+ // build options for the droppables
var options_for_droppable = {
overlap: options.overlap,
containment: options.containment,
tree: options.tree,
hoverclass: options.hoverclass,
onHover: Sortable.onHover
- }
-
+ };
+
var options_for_tree = {
onHover: Sortable.onEmptyHover,
overlap: options.overlap,
containment: options.containment,
hoverclass: options.hoverclass
- }
+ };
// fix for gecko engine
- Element.cleanWhitespace(element);
+ Element.cleanWhitespace(element);
options.draggables = [];
options.droppables = [];
@@ -712,14 +714,14 @@ var Sortable = {
(options.elements || this.findElements(element, options) || []).each( function(e,i) {
var handle = options.handles ? $(options.handles[i]) :
- (options.handle ? $(e).select('.' + options.handle)[0] : e);
+ (options.handle ? $(e).select('.' + options.handle)[0] : e);
options.draggables.push(
new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
Droppables.add(e, options_for_droppable);
if(options.tree) e.treeNode = element;
- options.droppables.push(e);
+ options.droppables.push(e);
});
-
+
if(options.tree) {
(Sortable.findTreeElements(element, options) || []).each( function(e) {
Droppables.add(e, options_for_tree);
@@ -729,7 +731,7 @@ var Sortable = {
}
// keep reference
- this.sortables[element.id] = options;
+ this.sortables[element.identify()] = options;
// for onupdate
Draggables.addObserver(new SortableObserver(element, options.onUpdate));
@@ -741,7 +743,7 @@ var Sortable = {
return Element.findChildren(
element, options.only, options.tree ? true : false, options.tag);
},
-
+
findTreeElements: function(element, options) {
return Element.findChildren(
element, options.only, options.tree ? true : false, options.treeTag);
@@ -758,7 +760,7 @@ var Sortable = {
var oldParentNode = element.parentNode;
element.style.visibility = "hidden"; // fix gecko rendering
dropon.parentNode.insertBefore(element, dropon);
- if(dropon.parentNode!=oldParentNode)
+ if(dropon.parentNode!=oldParentNode)
Sortable.options(oldParentNode).onChange(element);
Sortable.options(dropon.parentNode).onChange(element);
}
@@ -769,26 +771,26 @@ var Sortable = {
var oldParentNode = element.parentNode;
element.style.visibility = "hidden"; // fix gecko rendering
dropon.parentNode.insertBefore(element, nextElement);
- if(dropon.parentNode!=oldParentNode)
+ if(dropon.parentNode!=oldParentNode)
Sortable.options(oldParentNode).onChange(element);
Sortable.options(dropon.parentNode).onChange(element);
}
}
},
-
+
onEmptyHover: function(element, dropon, overlap) {
var oldParentNode = element.parentNode;
var droponOptions = Sortable.options(dropon);
-
+
if(!Element.isParent(dropon, element)) {
var index;
-
+
var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
var child = null;
-
+
if(children) {
var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
-
+
for (index = 0; index < children.length; index += 1) {
if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
offset -= Element.offsetSize (children[index], droponOptions.overlap);
@@ -801,9 +803,9 @@ var Sortable = {
}
}
}
-
+
dropon.insertBefore(element, child);
-
+
Sortable.options(oldParentNode).onChange(element);
droponOptions.onChange(element);
}
@@ -816,34 +818,34 @@ var Sortable = {
mark: function(dropon, position) {
// mark on ghosting only
var sortable = Sortable.options(dropon.parentNode);
- if(sortable && !sortable.ghosting) return;
+ if(sortable && !sortable.ghosting) return;
if(!Sortable._marker) {
- Sortable._marker =
+ Sortable._marker =
($('dropmarker') || Element.extend(document.createElement('DIV'))).
hide().addClassName('dropmarker').setStyle({position:'absolute'});
document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
- }
- var offsets = Position.cumulativeOffset(dropon);
+ }
+ var offsets = dropon.cumulativeOffset();
Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
-
+
if(position=='after')
- if(sortable.overlap == 'horizontal')
+ if(sortable.overlap == 'horizontal')
Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
else
Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
-
+
Sortable._marker.show();
},
-
+
_tree: function(element, options, parent) {
var children = Sortable.findElements(element, options) || [];
-
+
for (var i = 0; i < children.length; ++i) {
var match = children[i].id.match(options.format);
if (!match) continue;
-
+
var child = {
id: encodeURIComponent(match ? match[1] : null),
element: element,
@@ -851,16 +853,16 @@ var Sortable = {
children: [],
position: parent.children.length,
container: $(children[i]).down(options.treeTag)
- }
-
+ };
+
/* Get the element containing the children and recurse over it */
if (child.container)
- this._tree(child.container, options, child)
-
+ this._tree(child.container, options, child);
+
parent.children.push (child);
}
- return parent;
+ return parent;
},
tree: function(element) {
@@ -873,15 +875,15 @@ var Sortable = {
name: element.id,
format: sortableOptions.format
}, arguments[1] || { });
-
+
var root = {
id: null,
parent: null,
children: [],
container: element,
position: 0
- }
-
+ };
+
return Sortable._tree(element, options, root);
},
@@ -897,7 +899,7 @@ var Sortable = {
sequence: function(element) {
element = $(element);
var options = Object.extend(this.options(element), arguments[1] || { });
-
+
return $(this.findElements(element, options) || []).map( function(item) {
return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
});
@@ -906,14 +908,14 @@ var Sortable = {
setSequence: function(element, new_sequence) {
element = $(element);
var options = Object.extend(this.options(element), arguments[2] || { });
-
+
var nodeMap = { };
this.findElements(element, options).each( function(n) {
if (n.id.match(options.format))
nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
n.parentNode.removeChild(n);
});
-
+
new_sequence.each(function(ident) {
var n = nodeMap[ident];
if (n) {
@@ -922,16 +924,16 @@ var Sortable = {
}
});
},
-
+
serialize: function(element) {
element = $(element);
var options = Object.extend(Sortable.options(element), arguments[1] || { });
var name = encodeURIComponent(
(arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
-
+
if (options.tree) {
return Sortable.tree(element, arguments[1]).children.map( function (item) {
- return [name + Sortable._constructIndex(item) + "[id]=" +
+ return [name + Sortable._constructIndex(item) + "[id]=" +
encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
}).flatten().join('&');
} else {
@@ -940,16 +942,16 @@ var Sortable = {
}).join('&');
}
}
-}
+};
// Returns true if child is contained within element
Element.isParent = function(child, element) {
if (!child.parentNode || child == element) return false;
if (child.parentNode == element) return true;
return Element.isParent(child.parentNode, element);
-}
+};
-Element.findChildren = function(element, only, recursive, tagName) {
+Element.findChildren = function(element, only, recursive, tagName) {
if(!element.hasChildNodes()) return null;
tagName = tagName.toUpperCase();
if(only) only = [only].flatten();
@@ -965,8 +967,8 @@ Element.findChildren = function(element, only, recursive, tagName) {
});
return (elements.length>0 ? elements.flatten() : []);
-}
+};
Element.offsetSize = function (element, type) {
return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
-}
+}; \ No newline at end of file
diff --git a/public/javascripts/effects.js b/public/javascripts/effects.js
index f030b5dbe..c81e6c7d5 100644
--- a/public/javascripts/effects.js
+++ b/public/javascripts/effects.js
@@ -1,48 +1,50 @@
-// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// script.aculo.us effects.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
+
+// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
// Justin Palmer (http://encytemedia.com/)
// Mark Pilgrim (http://diveintomark.org/)
// Martin Bialasinki
-//
+//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
-// For details, see the script.aculo.us web site: http://script.aculo.us/
+// For details, see the script.aculo.us web site: http://script.aculo.us/
-// converts rgb() and #xxx to #xxxxxx format,
-// returns self (or first argument) if not convertable
-String.prototype.parseColor = function() {
+// converts rgb() and #xxx to #xxxxxx format,
+// returns self (or first argument) if not convertable
+String.prototype.parseColor = function() {
var color = '#';
- if (this.slice(0,4) == 'rgb(') {
- var cols = this.slice(4,this.length-1).split(',');
- var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
- } else {
- if (this.slice(0,1) == '#') {
- if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
- if (this.length==7) color = this.toLowerCase();
- }
- }
- return (color.length==7 ? color : (arguments[0] || this));
+ if (this.slice(0,4) == 'rgb(') {
+ var cols = this.slice(4,this.length-1).split(',');
+ var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
+ } else {
+ if (this.slice(0,1) == '#') {
+ if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
+ if (this.length==7) color = this.toLowerCase();
+ }
+ }
+ return (color.length==7 ? color : (arguments[0] || this));
};
/*--------------------------------------------------------------------------*/
-Element.collectTextNodes = function(element) {
+Element.collectTextNodes = function(element) {
return $A($(element).childNodes).collect( function(node) {
- return (node.nodeType==3 ? node.nodeValue :
+ return (node.nodeType==3 ? node.nodeValue :
(node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
}).flatten().join('');
};
-Element.collectTextNodesIgnoreClass = function(element, className) {
+Element.collectTextNodesIgnoreClass = function(element, className) {
return $A($(element).childNodes).collect( function(node) {
- return (node.nodeType==3 ? node.nodeValue :
- ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
+ return (node.nodeType==3 ? node.nodeValue :
+ ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
Element.collectTextNodesIgnoreClass(node, className) : ''));
}).flatten().join('');
};
Element.setContentZoom = function(element, percent) {
- element = $(element);
- element.setStyle({fontSize: (percent/100) + 'em'});
+ element = $(element);
+ element.setStyle({fontSize: (percent/100) + 'em'});
if (Prototype.Browser.WebKit) window.scrollBy(0,0);
return element;
};
@@ -70,28 +72,23 @@ var Effect = {
Transitions: {
linear: Prototype.K,
sinoidal: function(pos) {
- return (-Math.cos(pos*Math.PI)/2) + 0.5;
+ return (-Math.cos(pos*Math.PI)/2) + .5;
},
reverse: function(pos) {
return 1-pos;
},
flicker: function(pos) {
- var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+ var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
return pos > 1 ? 1 : pos;
},
wobble: function(pos) {
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+ return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
},
- pulse: function(pos, pulses) {
- pulses = pulses || 5;
- return (
- ((pos % (1/pulses)) * pulses).round() == 0 ?
- ((pos * pulses * 2) - (pos * pulses * 2).floor()) :
- 1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
- );
+ pulse: function(pos, pulses) {
+ return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
},
- spring: function(pos) {
- return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
+ spring: function(pos) {
+ return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
},
none: function(pos) {
return 0;
@@ -112,14 +109,14 @@ var Effect = {
tagifyText: function(element) {
var tagifyStyle = 'position:relative';
if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
-
+
element = $(element);
$A(element.childNodes).each( function(child) {
if (child.nodeType==3) {
child.nodeValue.toArray().each( function(character) {
element.insertBefore(
new Element('span', {style: tagifyStyle}).update(
- character == ' ' ? String.fromCharCode(160) : character),
+ character == ' ' ? String.fromCharCode(160) : character),
child);
});
Element.remove(child);
@@ -128,13 +125,13 @@ var Effect = {
},
multiple: function(element, effect) {
var elements;
- if (((typeof element == 'object') ||
- Object.isFunction(element)) &&
+ if (((typeof element == 'object') ||
+ Object.isFunction(element)) &&
(element.length))
elements = element;
else
elements = $(element).childNodes;
-
+
var options = Object.extend({
speed: 0.1,
delay: 0.0
@@ -150,14 +147,13 @@ var Effect = {
'blind': ['BlindDown','BlindUp'],
'appear': ['Appear','Fade']
},
- toggle: function(element, effect) {
+ toggle: function(element, effect, options) {
element = $(element);
- effect = (effect || 'appear').toLowerCase();
- var options = Object.extend({
+ effect = (effect || 'appear').toLowerCase();
+
+ return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({
queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
- }, arguments[2] || { });
- Effect[element.visible() ?
- Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+ }, options || {}));
}
};
@@ -168,20 +164,20 @@ Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
Effect.ScopedQueue = Class.create(Enumerable, {
initialize: function() {
this.effects = [];
- this.interval = null;
+ this.interval = null;
},
_each: function(iterator) {
this.effects._each(iterator);
},
add: function(effect) {
var timestamp = new Date().getTime();
-
- var position = Object.isString(effect.options.queue) ?
+
+ var position = Object.isString(effect.options.queue) ?
effect.options.queue : effect.options.queue.position;
-
+
switch(position) {
case 'front':
- // move unstarted effects after this effect
+ // move unstarted effects after this effect
this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
e.startOn += effect.finishOn;
e.finishOn += effect.finishOn;
@@ -195,13 +191,13 @@ Effect.ScopedQueue = Class.create(Enumerable, {
timestamp = this.effects.pluck('finishOn').max() || timestamp;
break;
}
-
+
effect.startOn += timestamp;
effect.finishOn += timestamp;
if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
this.effects.push(effect);
-
+
if (!this.interval)
this.interval = setInterval(this.loop.bind(this), 15);
},
@@ -214,7 +210,7 @@ Effect.ScopedQueue = Class.create(Enumerable, {
},
loop: function() {
var timePos = new Date().getTime();
- for(var i=0, len=this.effects.length;i<len;i++)
+ for(var i=0, len=this.effects.length;i<len;i++)
this.effects[i] && this.effects[i].loop(timePos);
}
});
@@ -223,7 +219,7 @@ Effect.Queues = {
instances: $H(),
get: function(queueName) {
if (!Object.isString(queueName)) return queueName;
-
+
return this.instances.get(queueName) ||
this.instances.set(queueName, new Effect.ScopedQueue());
}
@@ -233,12 +229,6 @@ Effect.Queue = Effect.Queues.get('global');
Effect.Base = Class.create({
position: null,
start: function(options) {
- function codeForEvent(options,eventName){
- return (
- (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
- (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
- );
- }
if (options && options.transition === false) options.transition = Effect.Transitions.linear;
this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
this.currentFrame = 0;
@@ -248,23 +238,35 @@ Effect.Base = Class.create({
this.fromToDelta = this.options.to-this.options.from;
this.totalTime = this.finishOn-this.startOn;
this.totalFrames = this.options.fps*this.options.duration;
-
- eval('this.render = function(pos){ '+
- 'if (this.state=="idle"){this.state="running";'+
- codeForEvent(this.options,'beforeSetup')+
- (this.setup ? 'this.setup();':'')+
- codeForEvent(this.options,'afterSetup')+
- '};if (this.state=="running"){'+
- 'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
- 'this.position=pos;'+
- codeForEvent(this.options,'beforeUpdate')+
- (this.update ? 'this.update(pos);':'')+
- codeForEvent(this.options,'afterUpdate')+
- '}}');
-
+
+ this.render = (function() {
+ function dispatch(effect, eventName) {
+ if (effect.options[eventName + 'Internal'])
+ effect.options[eventName + 'Internal'](effect);
+ if (effect.options[eventName])
+ effect.options[eventName](effect);
+ }
+
+ return function(pos) {
+ if (this.state === "idle") {
+ this.state = "running";
+ dispatch(this, 'beforeSetup');
+ if (this.setup) this.setup();
+ dispatch(this, 'afterSetup');
+ }
+ if (this.state === "running") {
+ pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
+ this.position = pos;
+ dispatch(this, 'beforeUpdate');
+ if (this.update) this.update(pos);
+ dispatch(this, 'afterUpdate');
+ }
+ };
+ })();
+
this.event('beforeStart');
if (!this.options.sync)
- Effect.Queues.get(Object.isString(this.options.queue) ?
+ Effect.Queues.get(Object.isString(this.options.queue) ?
'global' : this.options.queue.scope).add(this);
},
loop: function(timePos) {
@@ -273,9 +275,9 @@ Effect.Base = Class.create({
this.render(1.0);
this.cancel();
this.event('beforeFinish');
- if (this.finish) this.finish();
+ if (this.finish) this.finish();
this.event('afterFinish');
- return;
+ return;
}
var pos = (timePos - this.startOn) / this.totalTime,
frame = (pos * this.totalFrames).round();
@@ -287,7 +289,7 @@ Effect.Base = Class.create({
},
cancel: function() {
if (!this.options.sync)
- Effect.Queues.get(Object.isString(this.options.queue) ?
+ Effect.Queues.get(Object.isString(this.options.queue) ?
'global' : this.options.queue.scope).remove(this);
this.state = 'finished';
},
@@ -325,10 +327,10 @@ Effect.Parallel = Class.create(Effect.Base, {
Effect.Tween = Class.create(Effect.Base, {
initialize: function(object, from, to) {
object = Object.isString(object) ? $(object) : object;
- var args = $A(arguments), method = args.last(),
+ var args = $A(arguments), method = args.last(),
options = args.length == 5 ? args[3] : null;
this.method = Object.isFunction(method) ? method.bind(object) :
- Object.isFunction(object[method]) ? object[method].bind(object) :
+ Object.isFunction(object[method]) ? object[method].bind(object) :
function(value) { object[method] = value };
this.start(Object.extend({ from: from, to: to }, options || { }));
},
@@ -392,7 +394,7 @@ Effect.Move = Class.create(Effect.Base, {
// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
- return new Effect.Move(element,
+ return new Effect.Move(element,
Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
};
@@ -414,15 +416,15 @@ Effect.Scale = Class.create(Effect.Base, {
setup: function() {
this.restoreAfterFinish = this.options.restoreAfterFinish || false;
this.elementPositioning = this.element.getStyle('position');
-
+
this.originalStyle = { };
['top','left','width','height','fontSize'].each( function(k) {
this.originalStyle[k] = this.element.style[k];
}.bind(this));
-
+
this.originalTop = this.element.offsetTop;
this.originalLeft = this.element.offsetLeft;
-
+
var fontSize = this.element.getStyle('font-size') || '100%';
['em','px','%','pt'].each( function(fontSizeType) {
if (fontSize.indexOf(fontSizeType)>0) {
@@ -430,9 +432,9 @@ Effect.Scale = Class.create(Effect.Base, {
this.fontSizeType = fontSizeType;
}
}.bind(this));
-
+
this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
-
+
this.dims = null;
if (this.options.scaleMode=='box')
this.dims = [this.element.offsetHeight, this.element.offsetWidth];
@@ -507,17 +509,16 @@ Effect.Highlight = Class.create(Effect.Base, {
Effect.ScrollTo = function(element) {
var options = arguments[1] || { },
- scrollOffsets = document.viewport.getScrollOffsets(),
- elementOffsets = $(element).cumulativeOffset(),
- max = (window.height || document.body.scrollHeight) - document.viewport.getHeight();
+ scrollOffsets = document.viewport.getScrollOffsets(),
+ elementOffsets = $(element).cumulativeOffset();
if (options.offset) elementOffsets[1] += options.offset;
return new Effect.Tween(null,
scrollOffsets.top,
- elementOffsets[1] > max ? max : elementOffsets[1],
+ elementOffsets[1],
options,
- function(p){ scrollTo(scrollOffsets.left, p.round()) }
+ function(p){ scrollTo(scrollOffsets.left, p.round()); }
);
};
@@ -529,9 +530,9 @@ Effect.Fade = function(element) {
var options = Object.extend({
from: element.getOpacity() || 1.0,
to: 0.0,
- afterFinishInternal: function(effect) {
+ afterFinishInternal: function(effect) {
if (effect.options.to!=0) return;
- effect.element.hide().setStyle({opacity: oldOpacity});
+ effect.element.hide().setStyle({opacity: oldOpacity});
}
}, arguments[1] || { });
return new Effect.Opacity(element,options);
@@ -547,15 +548,15 @@ Effect.Appear = function(element) {
effect.element.forceRerendering();
},
beforeSetup: function(effect) {
- effect.element.setOpacity(effect.options.from).show();
+ effect.element.setOpacity(effect.options.from).show();
}}, arguments[1] || { });
return new Effect.Opacity(element,options);
};
Effect.Puff = function(element) {
element = $(element);
- var oldStyle = {
- opacity: element.getInlineOpacity(),
+ var oldStyle = {
+ opacity: element.getInlineOpacity(),
position: element.getStyle('position'),
top: element.style.top,
left: element.style.left,
@@ -563,12 +564,12 @@ Effect.Puff = function(element) {
height: element.style.height
};
return new Effect.Parallel(
- [ new Effect.Scale(element, 200,
- { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
- new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
- Object.extend({ duration: 1.0,
+ [ new Effect.Scale(element, 200,
+ { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
+ Object.extend({ duration: 1.0,
beforeSetupInternal: function(effect) {
- Position.absolutize(effect.effects[0].element)
+ Position.absolutize(effect.effects[0].element);
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().setStyle(oldStyle); }
@@ -580,12 +581,12 @@ Effect.BlindUp = function(element) {
element = $(element);
element.makeClipping();
return new Effect.Scale(element, 0,
- Object.extend({ scaleContent: false,
- scaleX: false,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
restoreAfterFinish: true,
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping();
- }
+ }
}, arguments[1] || { })
);
};
@@ -593,15 +594,15 @@ Effect.BlindUp = function(element) {
Effect.BlindDown = function(element) {
element = $(element);
var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100, Object.extend({
- scaleContent: false,
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
scaleX: false,
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
- effect.element.makeClipping().setStyle({height: '0px'}).show();
- },
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
afterFinishInternal: function(effect) {
effect.element.undoClipping();
}
@@ -616,16 +617,16 @@ Effect.SwitchOff = function(element) {
from: 0,
transition: Effect.Transitions.flicker,
afterFinishInternal: function(effect) {
- new Effect.Scale(effect.element, 1, {
+ new Effect.Scale(effect.element, 1, {
duration: 0.3, scaleFromCenter: true,
scaleX: false, scaleContent: false, restoreAfterFinish: true,
- beforeSetup: function(effect) {
+ beforeSetup: function(effect) {
effect.element.makePositioned().makeClipping();
},
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
}
- })
+ });
}
}, arguments[1] || { }));
};
@@ -637,16 +638,16 @@ Effect.DropOut = function(element) {
left: element.getStyle('left'),
opacity: element.getInlineOpacity() };
return new Effect.Parallel(
- [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
+ [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
Object.extend(
{ duration: 0.5,
beforeSetup: function(effect) {
- effect.effects[0].element.makePositioned();
+ effect.effects[0].element.makePositioned();
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
- }
+ }
}, arguments[1] || { }));
};
@@ -674,7 +675,7 @@ Effect.Shake = function(element) {
new Effect.Move(effect.element,
{ x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
effect.element.undoPositioned().setStyle(oldStyle);
- }}) }}) }}) }}) }}) }});
+ }}); }}); }}); }}); }}); }});
};
Effect.SlideDown = function(element) {
@@ -682,9 +683,9 @@ Effect.SlideDown = function(element) {
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
var oldInnerBottom = element.down().getStyle('bottom');
var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100, Object.extend({
- scaleContent: false,
- scaleX: false,
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
scaleFrom: window.opera ? 0 : 1,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
@@ -692,11 +693,11 @@ Effect.SlideDown = function(element) {
effect.element.makePositioned();
effect.element.down().makePositioned();
if (window.opera) effect.element.setStyle({top: ''});
- effect.element.makeClipping().setStyle({height: '0px'}).show();
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
},
afterUpdateInternal: function(effect) {
effect.element.down().setStyle({bottom:
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
},
afterFinishInternal: function(effect) {
effect.element.undoClipping().undoPositioned();
@@ -710,8 +711,8 @@ Effect.SlideUp = function(element) {
var oldInnerBottom = element.down().getStyle('bottom');
var elementDimensions = element.getDimensions();
return new Effect.Scale(element, window.opera ? 0 : 1,
- Object.extend({ scaleContent: false,
- scaleX: false,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
scaleMode: 'box',
scaleFrom: 100,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
@@ -721,7 +722,7 @@ Effect.SlideUp = function(element) {
effect.element.down().makePositioned();
if (window.opera) effect.element.setStyle({top: ''});
effect.element.makeClipping().show();
- },
+ },
afterUpdateInternal: function(effect) {
effect.element.down().setStyle({bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' });
@@ -734,15 +735,15 @@ Effect.SlideUp = function(element) {
);
};
-// Bug in opera makes the TD containing this element expand for a instance after finish
+// Bug in opera makes the TD containing this element expand for a instance after finish
Effect.Squish = function(element) {
- return new Effect.Scale(element, window.opera ? 1 : 0, {
+ return new Effect.Scale(element, window.opera ? 1 : 0, {
restoreAfterFinish: true,
beforeSetup: function(effect) {
- effect.element.makeClipping();
- },
+ effect.element.makeClipping();
+ },
afterFinishInternal: function(effect) {
- effect.element.hide().undoClipping();
+ effect.element.hide().undoClipping();
}
});
};
@@ -762,13 +763,13 @@ Effect.Grow = function(element) {
width: element.style.width,
opacity: element.getInlineOpacity() };
- var dims = element.getDimensions();
+ var dims = element.getDimensions();
var initialMoveX, initialMoveY;
var moveX, moveY;
-
+
switch (options.direction) {
case 'top-left':
- initialMoveX = initialMoveY = moveX = moveY = 0;
+ initialMoveX = initialMoveY = moveX = moveY = 0;
break;
case 'top-right':
initialMoveX = dims.width;
@@ -793,11 +794,11 @@ Effect.Grow = function(element) {
moveY = -dims.height / 2;
break;
}
-
+
return new Effect.Move(element, {
x: initialMoveX,
y: initialMoveY,
- duration: 0.01,
+ duration: 0.01,
beforeSetup: function(effect) {
effect.element.hide().makeClipping().makePositioned();
},
@@ -806,17 +807,17 @@ Effect.Grow = function(element) {
[ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
new Effect.Scale(effect.element, 100, {
- scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
+ scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
], Object.extend({
beforeSetup: function(effect) {
- effect.effects[0].element.setStyle({height: '0px'}).show();
+ effect.effects[0].element.setStyle({height: '0px'}).show();
},
afterFinishInternal: function(effect) {
- effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
+ effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
}
}, options)
- )
+ );
}
});
};
@@ -838,7 +839,7 @@ Effect.Shrink = function(element) {
var dims = element.getDimensions();
var moveX, moveY;
-
+
switch (options.direction) {
case 'top-left':
moveX = moveY = 0;
@@ -855,19 +856,19 @@ Effect.Shrink = function(element) {
moveX = dims.width;
moveY = dims.height;
break;
- case 'center':
+ case 'center':
moveX = dims.width / 2;
moveY = dims.height / 2;
break;
}
-
+
return new Effect.Parallel(
[ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
- ], Object.extend({
+ ], Object.extend({
beforeStartInternal: function(effect) {
- effect.effects[0].element.makePositioned().makeClipping();
+ effect.effects[0].element.makePositioned().makeClipping();
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
@@ -877,12 +878,14 @@ Effect.Shrink = function(element) {
Effect.Pulsate = function(element) {
element = $(element);
- var options = arguments[1] || { };
- var oldOpacity = element.getInlineOpacity();
- var transition = options.transition || Effect.Transitions.sinoidal;
- var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
- reverser.bind(transition);
- return new Effect.Opacity(element,
+ var options = arguments[1] || { },
+ oldOpacity = element.getInlineOpacity(),
+ transition = options.transition || Effect.Transitions.linear,
+ reverser = function(pos){
+ return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
+ };
+
+ return new Effect.Opacity(element,
Object.extend(Object.extend({ duration: 2.0, from: 0,
afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
}, options), {transition: reverser}));
@@ -896,12 +899,12 @@ Effect.Fold = function(element) {
width: element.style.width,
height: element.style.height };
element.makeClipping();
- return new Effect.Scale(element, 5, Object.extend({
+ return new Effect.Scale(element, 5, Object.extend({
scaleContent: false,
scaleX: false,
afterFinishInternal: function(effect) {
- new Effect.Scale(element, 1, {
- scaleContent: false,
+ new Effect.Scale(element, 1, {
+ scaleContent: false,
scaleY: false,
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().setStyle(oldStyle);
@@ -916,7 +919,7 @@ Effect.Morph = Class.create(Effect.Base, {
var options = Object.extend({
style: { }
}, arguments[1] || { });
-
+
if (!Object.isString(options.style)) this.style = $H(options.style);
else {
if (options.style.include(':'))
@@ -934,18 +937,18 @@ Effect.Morph = Class.create(Effect.Base, {
effect.transforms.each(function(transform) {
effect.element.style[transform.style] = '';
});
- }
+ };
}
}
this.start(options);
},
-
+
setup: function(){
function parseColor(color){
if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
color = color.parseColor();
return $R(0,2).map(function(i){
- return parseInt( color.slice(i*2+1,i*2+3), 16 )
+ return parseInt( color.slice(i*2+1,i*2+3), 16 );
});
}
this.transforms = this.style.map(function(pair){
@@ -965,9 +968,9 @@ Effect.Morph = Class.create(Effect.Base, {
}
var originalValue = this.element.getStyle(property);
- return {
- style: property.camelize(),
- originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
+ return {
+ style: property.camelize(),
+ originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
targetValue: unit=='color' ? parseColor(value) : value,
unit: unit
};
@@ -978,13 +981,13 @@ Effect.Morph = Class.create(Effect.Base, {
transform.unit != 'color' &&
(isNaN(transform.originalValue) || isNaN(transform.targetValue))
)
- )
+ );
});
},
update: function(position) {
var style = { }, transform, i = this.transforms.length;
while(i--)
- style[(transform = this.transforms[i]).style] =
+ style[(transform = this.transforms[i]).style] =
transform.unit=='color' ? '#'+
(Math.round(transform.originalValue[0]+
(transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
@@ -993,7 +996,7 @@ Effect.Morph = Class.create(Effect.Base, {
(Math.round(transform.originalValue[2]+
(transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
(transform.originalValue +
- (transform.targetValue - transform.originalValue) * position).toFixed(3) +
+ (transform.targetValue - transform.originalValue) * position).toFixed(3) +
(transform.unit === null ? '' : transform.unit);
this.element.setStyle(style, true);
}
@@ -1030,7 +1033,7 @@ Effect.Transform = Class.create({
});
Element.CSS_PROPERTIES = $w(
- 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
+ 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
@@ -1039,7 +1042,7 @@ Element.CSS_PROPERTIES = $w(
'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
'right textIndent top width wordSpacing zIndex');
-
+
Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
String.__parseStyleElement = document.createElement('div');
@@ -1051,11 +1054,11 @@ String.prototype.parseStyle = function(){
String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
style = String.__parseStyleElement.childNodes[0].style;
}
-
+
Element.CSS_PROPERTIES.each(function(property){
- if (style[property]) styleRules.set(property, style[property]);
+ if (style[property]) styleRules.set(property, style[property]);
});
-
+
if (Prototype.Browser.IE && this.include('opacity'))
styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
@@ -1074,14 +1077,14 @@ if (document.defaultView && document.defaultView.getComputedStyle) {
Element.getStyles = function(element) {
element = $(element);
var css = element.currentStyle, styles;
- styles = Element.CSS_PROPERTIES.inject({ }, function(hash, property) {
- hash.set(property, css[property]);
- return hash;
+ styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
+ results[property] = css[property];
+ return results;
});
- if (!styles.opacity) styles.set('opacity', element.getOpacity());
+ if (!styles.opacity) styles.opacity = element.getOpacity();
return styles;
};
-};
+}
Effect.Methods = {
morph: function(element, style) {
@@ -1090,7 +1093,7 @@ Effect.Methods = {
return element;
},
visualEffect: function(element, effect, options) {
- element = $(element)
+ element = $(element);
var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
new Effect[klass](element, options);
return element;
@@ -1104,17 +1107,17 @@ Effect.Methods = {
$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
'pulsate shake puff squish switchOff dropOut').each(
- function(effect) {
+ function(effect) {
Effect.Methods[effect] = function(element, options){
element = $(element);
Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
return element;
- }
+ };
}
);
-$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
+$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
function(f) { Effect.Methods[f] = Element[f]; }
);
-Element.addMethods(Effect.Methods);
+Element.addMethods(Effect.Methods); \ No newline at end of file
diff --git a/public/javascripts/prototype.js b/public/javascripts/prototype.js
index 546f9fe44..06249a6ae 100644
--- a/public/javascripts/prototype.js
+++ b/public/javascripts/prototype.js
@@ -1,5 +1,5 @@
-/* Prototype JavaScript framework, version 1.6.0.1
- * (c) 2005-2007 Sam Stephenson
+/* Prototype JavaScript framework, version 1.7_rc2
+ * (c) 2005-2010 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://www.prototypejs.org/
@@ -7,29 +7,53 @@
*--------------------------------------------------------------------------*/
var Prototype = {
- Version: '1.6.0.1',
- Browser: {
- IE: !!(window.attachEvent && !window.opera),
- Opera: !!window.opera,
- WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
- Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
- MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
- },
+ Version: '1.7_rc2',
+
+ Browser: (function(){
+ var ua = navigator.userAgent;
+ var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
+ return {
+ IE: !!window.attachEvent && !isOpera,
+ Opera: isOpera,
+ WebKit: ua.indexOf('AppleWebKit/') > -1,
+ Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
+ MobileSafari: /Apple.*Mobile/.test(ua)
+ }
+ })(),
BrowserFeatures: {
XPath: !!document.evaluate,
- ElementExtensions: !!window.HTMLElement,
- SpecificElementExtensions:
- document.createElement('div').__proto__ &&
- document.createElement('div').__proto__ !==
- document.createElement('form').__proto__
+
+ SelectorsAPI: !!document.querySelector,
+
+ ElementExtensions: (function() {
+ var constructor = window.Element || window.HTMLElement;
+ return !!(constructor && constructor.prototype);
+ })(),
+ SpecificElementExtensions: (function() {
+ if (typeof window.HTMLDivElement !== 'undefined')
+ return true;
+
+ var div = document.createElement('div'),
+ form = document.createElement('form'),
+ isSupported = false;
+
+ if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
+ isSupported = true;
+ }
+
+ div = form = null;
+
+ return isSupported;
+ })()
},
ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
emptyFunction: function() { },
+
K: function(x) { return x }
};
@@ -37,9 +61,38 @@ if (Prototype.Browser.MobileSafari)
Prototype.BrowserFeatures.SpecificElementExtensions = false;
+var Abstract = { };
+
+
+var Try = {
+ these: function() {
+ var returnValue;
+
+ for (var i = 0, length = arguments.length; i < length; i++) {
+ var lambda = arguments[i];
+ try {
+ returnValue = lambda();
+ break;
+ } catch (e) { }
+ }
+
+ return returnValue;
+ }
+};
+
/* Based on Alex Arnell's inheritance implementation. */
-var Class = {
- create: function() {
+
+var Class = (function() {
+
+ var IS_DONTENUM_BUGGY = (function(){
+ for (var p in { toString: 1 }) {
+ if (p === 'toString') return false;
+ }
+ return true;
+ })();
+
+ function subclass() {};
+ function create() {
var parent = null, properties = $A(arguments);
if (Object.isFunction(properties[0]))
parent = properties.shift();
@@ -53,235 +106,374 @@ var Class = {
klass.subclasses = [];
if (parent) {
- var subclass = function() { };
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
parent.subclasses.push(klass);
}
- for (var i = 0; i < properties.length; i++)
+ for (var i = 0, length = properties.length; i < length; i++)
klass.addMethods(properties[i]);
if (!klass.prototype.initialize)
klass.prototype.initialize = Prototype.emptyFunction;
klass.prototype.constructor = klass;
-
return klass;
}
-};
-Class.Methods = {
- addMethods: function(source) {
- var ancestor = this.superclass && this.superclass.prototype;
- var properties = Object.keys(source);
+ function addMethods(source) {
+ var ancestor = this.superclass && this.superclass.prototype,
+ properties = Object.keys(source);
- if (!Object.keys({ toString: true }).length)
- properties.push("toString", "valueOf");
+ if (IS_DONTENUM_BUGGY) {
+ if (source.toString != Object.prototype.toString)
+ properties.push("toString");
+ if (source.valueOf != Object.prototype.valueOf)
+ properties.push("valueOf");
+ }
for (var i = 0, length = properties.length; i < length; i++) {
var property = properties[i], value = source[property];
if (ancestor && Object.isFunction(value) &&
- value.argumentNames().first() == "$super") {
- var method = value, value = Object.extend((function(m) {
- return function() { return ancestor[m].apply(this, arguments) };
- })(property).wrap(method), {
- valueOf: function() { return method },
- toString: function() { return method.toString() }
- });
+ value.argumentNames()[0] == "$super") {
+ var method = value;
+ value = (function(m) {
+ return function() { return ancestor[m].apply(this, arguments); };
+ })(property).wrap(method);
+
+ value.valueOf = method.valueOf.bind(method);
+ value.toString = method.toString.bind(method);
}
this.prototype[property] = value;
}
return this;
}
-};
-var Abstract = { };
+ return {
+ create: create,
+ Methods: {
+ addMethods: addMethods
+ }
+ };
+})();
+(function() {
-Object.extend = function(destination, source) {
- for (var property in source)
- destination[property] = source[property];
- return destination;
-};
+ var _toString = Object.prototype.toString,
+ NULL_TYPE = 'Null',
+ UNDEFINED_TYPE = 'Undefined',
+ BOOLEAN_TYPE = 'Boolean',
+ NUMBER_TYPE = 'Number',
+ STRING_TYPE = 'String',
+ OBJECT_TYPE = 'Object',
+ BOOLEAN_CLASS = '[object Boolean]',
+ NUMBER_CLASS = '[object Number]',
+ STRING_CLASS = '[object String]',
+ ARRAY_CLASS = '[object Array]',
+ NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
+ typeof JSON.stringify === 'function' &&
+ JSON.stringify(0) === '0' &&
+ typeof JSON.stringify(Prototype.K) === 'undefined';
+
+ function Type(o) {
+ switch(o) {
+ case null: return NULL_TYPE;
+ case (void 0): return UNDEFINED_TYPE;
+ }
+ var type = typeof o;
+ switch(type) {
+ case 'boolean': return BOOLEAN_TYPE;
+ case 'number': return NUMBER_TYPE;
+ case 'string': return STRING_TYPE;
+ }
+ return OBJECT_TYPE;
+ }
-Object.extend(Object, {
- inspect: function(object) {
+ function extend(destination, source) {
+ for (var property in source)
+ destination[property] = source[property];
+ return destination;
+ }
+
+ function inspect(object) {
try {
- if (Object.isUndefined(object)) return 'undefined';
+ if (isUndefined(object)) return 'undefined';
if (object === null) return 'null';
- return object.inspect ? object.inspect() : object.toString();
+ return object.inspect ? object.inspect() : String(object);
} catch (e) {
if (e instanceof RangeError) return '...';
throw e;
}
- },
+ }
- toJSON: function(object) {
- var type = typeof object;
- switch (type) {
- case 'undefined':
- case 'function':
- case 'unknown': return;
- case 'boolean': return object.toString();
+ function toJSON(value) {
+ return Str('', { '': value }, []);
+ }
+
+ function Str(key, holder, stack) {
+ var value = holder[key],
+ type = typeof value;
+
+ if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
}
- if (object === null) return 'null';
- if (object.toJSON) return object.toJSON();
- if (Object.isElement(object)) return;
+ var _class = _toString.call(value);
- var results = [];
- for (var property in object) {
- var value = Object.toJSON(object[property]);
- if (!Object.isUndefined(value))
- results.push(property.toJSON() + ': ' + value);
+ switch (_class) {
+ case NUMBER_CLASS:
+ case BOOLEAN_CLASS:
+ case STRING_CLASS:
+ value = value.valueOf();
}
- return '{' + results.join(', ') + '}';
- },
+ switch (value) {
+ case null: return 'null';
+ case true: return 'true';
+ case false: return 'false';
+ }
+
+ type = typeof value;
+ switch (type) {
+ case 'string':
+ return value.inspect(true);
+ case 'number':
+ return isFinite(value) ? String(value) : 'null';
+ case 'object':
+
+ for (var i = 0, length = stack.length; i < length; i++) {
+ if (stack[i] === value) { throw new TypeError(); }
+ }
+ stack.push(value);
- toQueryString: function(object) {
+ var partial = [];
+ if (_class === ARRAY_CLASS) {
+ for (var i = 0, length = value.length; i < length; i++) {
+ var str = Str(i, value, stack);
+ partial.push(typeof str === 'undefined' ? 'null' : str);
+ }
+ partial = '[' + partial.join(',') + ']';
+ } else {
+ var keys = Object.keys(value);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ var key = keys[i], str = Str(key, value, stack);
+ if (typeof str !== "undefined") {
+ partial.push(key.inspect(true)+ ':' + str);
+ }
+ }
+ partial = '{' + partial.join(',') + '}';
+ }
+ stack.pop();
+ return partial;
+ }
+ }
+
+ function stringify(object) {
+ return JSON.stringify(object);
+ }
+
+ function toQueryString(object) {
return $H(object).toQueryString();
- },
+ }
- toHTML: function(object) {
+ function toHTML(object) {
return object && object.toHTML ? object.toHTML() : String.interpret(object);
- },
+ }
- keys: function(object) {
- var keys = [];
- for (var property in object)
- keys.push(property);
- return keys;
- },
+ function keys(object) {
+ if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
+ var results = [];
+ for (var property in object) {
+ if (object.hasOwnProperty(property)) {
+ results.push(property);
+ }
+ }
+ return results;
+ }
- values: function(object) {
- var values = [];
+ function values(object) {
+ var results = [];
for (var property in object)
- values.push(object[property]);
- return values;
- },
+ results.push(object[property]);
+ return results;
+ }
- clone: function(object) {
- return Object.extend({ }, object);
- },
+ function clone(object) {
+ return extend({ }, object);
+ }
- isElement: function(object) {
- return object && object.nodeType == 1;
- },
+ function isElement(object) {
+ return !!(object && object.nodeType == 1);
+ }
- isArray: function(object) {
- return object && object.constructor === Array;
- },
+ function isArray(object) {
+ return _toString.call(object) === ARRAY_CLASS;
+ }
+
+ var hasNativeIsArray = (typeof Array.isArray == 'function')
+ && Array.isArray([]) && !Array.isArray({});
- isHash: function(object) {
+ if (hasNativeIsArray) {
+ isArray = Array.isArray;
+ }
+
+ function isHash(object) {
return object instanceof Hash;
- },
+ }
- isFunction: function(object) {
- return typeof object == "function";
- },
+ function isFunction(object) {
+ return typeof object === "function";
+ }
- isString: function(object) {
- return typeof object == "string";
- },
+ function isString(object) {
+ return _toString.call(object) === STRING_CLASS;
+ }
- isNumber: function(object) {
- return typeof object == "number";
- },
+ function isNumber(object) {
+ return _toString.call(object) === NUMBER_CLASS;
+ }
- isUndefined: function(object) {
- return typeof object == "undefined";
+ function isUndefined(object) {
+ return typeof object === "undefined";
}
-});
-Object.extend(Function.prototype, {
- argumentNames: function() {
- var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
+ extend(Object, {
+ extend: extend,
+ inspect: inspect,
+ toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
+ toQueryString: toQueryString,
+ toHTML: toHTML,
+ keys: Object.keys || keys,
+ values: values,
+ clone: clone,
+ isElement: isElement,
+ isArray: isArray,
+ isHash: isHash,
+ isFunction: isFunction,
+ isString: isString,
+ isNumber: isNumber,
+ isUndefined: isUndefined
+ });
+})();
+Object.extend(Function.prototype, (function() {
+ var slice = Array.prototype.slice;
+
+ function update(array, args) {
+ var arrayLength = array.length, length = args.length;
+ while (length--) array[arrayLength + length] = args[length];
+ return array;
+ }
+
+ function merge(array, args) {
+ array = slice.call(array, 0);
+ return update(array, args);
+ }
+
+ function argumentNames() {
+ var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
+ .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
+ .replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names;
- },
+ }
- bind: function() {
+ function bind(context) {
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
- var __method = this, args = $A(arguments), object = args.shift();
+ var __method = this, args = slice.call(arguments, 1);
return function() {
- return __method.apply(object, args.concat($A(arguments)));
+ var a = merge(args, arguments);
+ return __method.apply(context, a);
}
- },
+ }
- bindAsEventListener: function() {
- var __method = this, args = $A(arguments), object = args.shift();
+ function bindAsEventListener(context) {
+ var __method = this, args = slice.call(arguments, 1);
return function(event) {
- return __method.apply(object, [event || window.event].concat(args));
+ var a = update([event || window.event], args);
+ return __method.apply(context, a);
}
- },
+ }
- curry: function() {
+ function curry() {
if (!arguments.length) return this;
- var __method = this, args = $A(arguments);
+ var __method = this, args = slice.call(arguments, 0);
return function() {
- return __method.apply(this, args.concat($A(arguments)));
+ var a = merge(args, arguments);
+ return __method.apply(this, a);
}
- },
+ }
- delay: function() {
- var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+ function delay(timeout) {
+ var __method = this, args = slice.call(arguments, 1);
+ timeout = timeout * 1000;
return window.setTimeout(function() {
return __method.apply(__method, args);
}, timeout);
- },
+ }
+
+ function defer() {
+ var args = update([0.01], arguments);
+ return this.delay.apply(this, args);
+ }
- wrap: function(wrapper) {
+ function wrap(wrapper) {
var __method = this;
return function() {
- return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+ var a = update([__method.bind(this)], arguments);
+ return wrapper.apply(this, a);
}
- },
+ }
- methodize: function() {
+ function methodize() {
if (this._methodized) return this._methodized;
var __method = this;
return this._methodized = function() {
- return __method.apply(null, [this].concat($A(arguments)));
+ var a = update([this], arguments);
+ return __method.apply(null, a);
};
}
-});
-Function.prototype.defer = Function.prototype.delay.curry(0.01);
+ return {
+ argumentNames: argumentNames,
+ bind: bind,
+ bindAsEventListener: bindAsEventListener,
+ curry: curry,
+ delay: delay,
+ defer: defer,
+ wrap: wrap,
+ methodize: methodize
+ }
+})());
-Date.prototype.toJSON = function() {
- return '"' + this.getUTCFullYear() + '-' +
- (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
- this.getUTCDate().toPaddedString(2) + 'T' +
- this.getUTCHours().toPaddedString(2) + ':' +
- this.getUTCMinutes().toPaddedString(2) + ':' +
- this.getUTCSeconds().toPaddedString(2) + 'Z"';
-};
-var Try = {
- these: function() {
- var returnValue;
- for (var i = 0, length = arguments.length; i < length; i++) {
- var lambda = arguments[i];
- try {
- returnValue = lambda();
- break;
- } catch (e) { }
- }
+(function(proto) {
- return returnValue;
+
+ function toISOString() {
+ return this.getUTCFullYear() + '-' +
+ (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
+ this.getUTCDate().toPaddedString(2) + 'T' +
+ this.getUTCHours().toPaddedString(2) + ':' +
+ this.getUTCMinutes().toPaddedString(2) + ':' +
+ this.getUTCSeconds().toPaddedString(2) + 'Z';
}
-};
+
+
+ function toJSON() {
+ return this.toISOString();
+ }
+
+ if (!proto.toISOString) proto.toISOString = toISOString;
+ if (!proto.toJSON) proto.toJSON = toJSON;
+
+})(Date.prototype);
+
RegExp.prototype.match = RegExp.prototype.test;
RegExp.escape = function(str) {
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};
-
-/*--------------------------------------------------------------------------*/
-
var PeriodicalExecuter = Class.create({
initialize: function(callback, frequency) {
this.callback = callback;
@@ -310,8 +502,10 @@ var PeriodicalExecuter = Class.create({
try {
this.currentlyExecuting = true;
this.execute();
- } finally {
this.currentlyExecuting = false;
+ } catch(e) {
+ this.currentlyExecuting = false;
+ throw e;
}
}
}
@@ -330,10 +524,28 @@ Object.extend(String, {
}
});
-Object.extend(String.prototype, {
- gsub: function(pattern, replacement) {
+Object.extend(String.prototype, (function() {
+ var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
+ typeof JSON.parse === 'function' &&
+ JSON.parse('{"test": true}').test;
+
+ function prepareReplacement(replacement) {
+ if (Object.isFunction(replacement)) return replacement;
+ var template = new Template(replacement);
+ return function(match) { return template.evaluate(match) };
+ }
+
+ function gsub(pattern, replacement) {
var result = '', source = this, match;
- replacement = arguments.callee.prepareReplacement(replacement);
+ replacement = prepareReplacement(replacement);
+
+ if (Object.isString(pattern))
+ pattern = RegExp.escape(pattern);
+
+ if (!(pattern.length || pattern.source)) {
+ replacement = replacement('');
+ return replacement + source.split('').join(replacement) + replacement;
+ }
while (source.length > 0) {
if (match = source.match(pattern)) {
@@ -345,76 +557,72 @@ Object.extend(String.prototype, {
}
}
return result;
- },
+ }
- sub: function(pattern, replacement, count) {
- replacement = this.gsub.prepareReplacement(replacement);
+ function sub(pattern, replacement, count) {
+ replacement = prepareReplacement(replacement);
count = Object.isUndefined(count) ? 1 : count;
return this.gsub(pattern, function(match) {
if (--count < 0) return match[0];
return replacement(match);
});
- },
+ }
- scan: function(pattern, iterator) {
+ function scan(pattern, iterator) {
this.gsub(pattern, iterator);
return String(this);
- },
+ }
- truncate: function(length, truncation) {
+ function truncate(length, truncation) {
length = length || 30;
truncation = Object.isUndefined(truncation) ? '...' : truncation;
return this.length > length ?
this.slice(0, length - truncation.length) + truncation : String(this);
- },
+ }
- strip: function() {
+ function strip() {
return this.replace(/^\s+/, '').replace(/\s+$/, '');
- },
+ }
- stripTags: function() {
- return this.replace(/<\/?[^>]+>/gi, '');
- },
+ function stripTags() {
+ return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
+ }
- stripScripts: function() {
+ function stripScripts() {
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
- },
+ }
- extractScripts: function() {
- var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
- var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+ function extractScripts() {
+ var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
+ matchOne = new RegExp(Prototype.ScriptFragment, 'im');
return (this.match(matchAll) || []).map(function(scriptTag) {
return (scriptTag.match(matchOne) || ['', ''])[1];
});
- },
+ }
- evalScripts: function() {
+ function evalScripts() {
return this.extractScripts().map(function(script) { return eval(script) });
- },
+ }
- escapeHTML: function() {
- var self = arguments.callee;
- self.text.data = this;
- return self.div.innerHTML;
- },
+ function escapeHTML() {
+ return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
+ }
+
+ function unescapeHTML() {
+ return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
+ }
- unescapeHTML: function() {
- var div = new Element('div');
- div.innerHTML = this.stripTags();
- return div.childNodes[0] ? (div.childNodes.length > 1 ?
- $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
- div.childNodes[0].nodeValue) : '';
- },
- toQueryParams: function(separator) {
+ function toQueryParams(separator) {
var match = this.strip().match(/([^?#]*)(#.*)?$/);
if (!match) return { };
return match[1].split(separator || '&').inject({ }, function(hash, pair) {
if ((pair = pair.split('='))[0]) {
- var key = decodeURIComponent(pair.shift());
- var value = pair.length > 1 ? pair.join('=') : pair[0];
+ var key = decodeURIComponent(pair.shift()),
+ value = pair.length > 1 ? pair.join('=') : pair[0];
+
if (value != undefined) value = decodeURIComponent(value);
if (key in hash) {
@@ -425,128 +633,144 @@ Object.extend(String.prototype, {
}
return hash;
});
- },
+ }
- toArray: function() {
+ function toArray() {
return this.split('');
- },
+ }
- succ: function() {
+ function succ() {
return this.slice(0, this.length - 1) +
String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
- },
+ }
- times: function(count) {
+ function times(count) {
return count < 1 ? '' : new Array(count + 1).join(this);
- },
-
- camelize: function() {
- var parts = this.split('-'), len = parts.length;
- if (len == 1) return parts[0];
-
- var camelized = this.charAt(0) == '-'
- ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
- : parts[0];
-
- for (var i = 1; i < len; i++)
- camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+ }
- return camelized;
- },
+ function camelize() {
+ return this.replace(/-+(.)?/g, function(match, chr) {
+ return chr ? chr.toUpperCase() : '';
+ });
+ }
- capitalize: function() {
+ function capitalize() {
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
- },
+ }
- underscore: function() {
- return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
- },
+ function underscore() {
+ return this.replace(/::/g, '/')
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
+ .replace(/([a-z\d])([A-Z])/g, '$1_$2')
+ .replace(/-/g, '_')
+ .toLowerCase();
+ }
- dasherize: function() {
- return this.gsub(/_/,'-');
- },
+ function dasherize() {
+ return this.replace(/_/g, '-');
+ }
- inspect: function(useDoubleQuotes) {
- var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
- var character = String.specialChar[match[0]];
- return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
+ function inspect(useDoubleQuotes) {
+ var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
+ if (character in String.specialChar) {
+ return String.specialChar[character];
+ }
+ return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
});
if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
return "'" + escapedString.replace(/'/g, '\\\'') + "'";
- },
-
- toJSON: function() {
- return this.inspect(true);
- },
+ }
- unfilterJSON: function(filter) {
- return this.sub(filter || Prototype.JSONFilter, '#{1}');
- },
+ function unfilterJSON(filter) {
+ return this.replace(filter || Prototype.JSONFilter, '$1');
+ }
- isJSON: function() {
+ function isJSON() {
var str = this;
if (str.blank()) return false;
- str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
- return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
- },
+ str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
+ str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
+ str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
+ return (/^[\],:{}\s]*$/).test(str);
+ }
- evalJSON: function(sanitize) {
- var json = this.unfilterJSON();
+ function evalJSON(sanitize) {
+ var json = this.unfilterJSON(),
+ cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+ if (cx.test(json)) {
+ json = json.replace(cx, function (a) {
+ return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ });
+ }
try {
if (!sanitize || json.isJSON()) return eval('(' + json + ')');
} catch (e) { }
throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
- },
+ }
- include: function(pattern) {
+ function parseJSON() {
+ var json = this.unfilterJSON();
+ return JSON.parse(json);
+ }
+
+ function include(pattern) {
return this.indexOf(pattern) > -1;
- },
+ }
- startsWith: function(pattern) {
- return this.indexOf(pattern) === 0;
- },
+ function startsWith(pattern) {
+ return this.lastIndexOf(pattern, 0) === 0;
+ }
- endsWith: function(pattern) {
+ function endsWith(pattern) {
var d = this.length - pattern.length;
- return d >= 0 && this.lastIndexOf(pattern) === d;
- },
+ return d >= 0 && this.indexOf(pattern, d) === d;
+ }
- empty: function() {
+ function empty() {
return this == '';
- },
+ }
- blank: function() {
+ function blank() {
return /^\s*$/.test(this);
- },
-
- interpolate: function(object, pattern) {
- return new Template(this, pattern).evaluate(object);
}
-});
-if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
- escapeHTML: function() {
- return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
- },
- unescapeHTML: function() {
- return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
+ function interpolate(object, pattern) {
+ return new Template(this, pattern).evaluate(object);
}
-});
-
-String.prototype.gsub.prepareReplacement = function(replacement) {
- if (Object.isFunction(replacement)) return replacement;
- var template = new Template(replacement);
- return function(match) { return template.evaluate(match) };
-};
-String.prototype.parseQuery = String.prototype.toQueryParams;
-
-Object.extend(String.prototype.escapeHTML, {
- div: document.createElement('div'),
- text: document.createTextNode('')
-});
-
-with (String.prototype.escapeHTML) div.appendChild(text);
+ return {
+ gsub: gsub,
+ sub: sub,
+ scan: scan,
+ truncate: truncate,
+ strip: String.prototype.trim || strip,
+ stripTags: stripTags,
+ stripScripts: stripScripts,
+ extractScripts: extractScripts,
+ evalScripts: evalScripts,
+ escapeHTML: escapeHTML,
+ unescapeHTML: unescapeHTML,
+ toQueryParams: toQueryParams,
+ parseQuery: toQueryParams,
+ toArray: toArray,
+ succ: succ,
+ times: times,
+ camelize: camelize,
+ capitalize: capitalize,
+ underscore: underscore,
+ dasherize: dasherize,
+ inspect: inspect,
+ unfilterJSON: unfilterJSON,
+ isJSON: isJSON,
+ evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
+ include: include,
+ startsWith: startsWith,
+ endsWith: endsWith,
+ empty: empty,
+ blank: blank,
+ interpolate: interpolate
+ };
+})());
var Template = Class.create({
initialize: function(template, pattern) {
@@ -555,22 +779,23 @@ var Template = Class.create({
},
evaluate: function(object) {
- if (Object.isFunction(object.toTemplateReplacements))
+ if (object && Object.isFunction(object.toTemplateReplacements))
object = object.toTemplateReplacements();
return this.template.gsub(this.pattern, function(match) {
- if (object == null) return '';
+ if (object == null) return (match[1] + '');
var before = match[1] || '';
if (before == '\\') return match[2];
- var ctx = object, expr = match[3];
- var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
+ var ctx = object, expr = match[3],
+ pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
+
match = pattern.exec(expr);
if (match == null) return before;
while (match != null) {
- var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
+ var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
ctx = ctx[comp];
if (null == ctx || '' == match[3]) break;
expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
@@ -578,101 +803,98 @@ var Template = Class.create({
}
return before + String.interpret(ctx);
- }.bind(this));
+ });
}
});
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
var $break = { };
-var Enumerable = {
- each: function(iterator, context) {
+var Enumerable = (function() {
+ function each(iterator, context) {
var index = 0;
- iterator = iterator.bind(context);
try {
this._each(function(value) {
- iterator(value, index++);
+ iterator.call(context, value, index++);
});
} catch (e) {
if (e != $break) throw e;
}
return this;
- },
+ }
- eachSlice: function(number, iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function eachSlice(number, iterator, context) {
var index = -number, slices = [], array = this.toArray();
+ if (number < 1) return array;
while ((index += number) < array.length)
slices.push(array.slice(index, index+number));
return slices.collect(iterator, context);
- },
+ }
- all: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function all(iterator, context) {
+ iterator = iterator || Prototype.K;
var result = true;
this.each(function(value, index) {
- result = result && !!iterator(value, index);
+ result = result && !!iterator.call(context, value, index);
if (!result) throw $break;
});
return result;
- },
+ }
- any: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function any(iterator, context) {
+ iterator = iterator || Prototype.K;
var result = false;
this.each(function(value, index) {
- if (result = !!iterator(value, index))
+ if (result = !!iterator.call(context, value, index))
throw $break;
});
return result;
- },
+ }
- collect: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function collect(iterator, context) {
+ iterator = iterator || Prototype.K;
var results = [];
this.each(function(value, index) {
- results.push(iterator(value, index));
+ results.push(iterator.call(context, value, index));
});
return results;
- },
+ }
- detect: function(iterator, context) {
- iterator = iterator.bind(context);
+ function detect(iterator, context) {
var result;
this.each(function(value, index) {
- if (iterator(value, index)) {
+ if (iterator.call(context, value, index)) {
result = value;
throw $break;
}
});
return result;
- },
+ }
- findAll: function(iterator, context) {
- iterator = iterator.bind(context);
+ function findAll(iterator, context) {
var results = [];
this.each(function(value, index) {
- if (iterator(value, index))
+ if (iterator.call(context, value, index))
results.push(value);
});
return results;
- },
+ }
- grep: function(filter, iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function grep(filter, iterator, context) {
+ iterator = iterator || Prototype.K;
var results = [];
if (Object.isString(filter))
- filter = new RegExp(filter);
+ filter = new RegExp(RegExp.escape(filter));
this.each(function(value, index) {
if (filter.match(value))
- results.push(iterator(value, index));
+ results.push(iterator.call(context, value, index));
});
return results;
- },
+ }
- include: function(object) {
+ function include(object) {
if (Object.isFunction(this.indexOf))
if (this.indexOf(object) != -1) return true;
@@ -684,96 +906,96 @@ var Enumerable = {
}
});
return found;
- },
+ }
- inGroupsOf: function(number, fillWith) {
+ function inGroupsOf(number, fillWith) {
fillWith = Object.isUndefined(fillWith) ? null : fillWith;
return this.eachSlice(number, function(slice) {
while(slice.length < number) slice.push(fillWith);
return slice;
});
- },
+ }
- inject: function(memo, iterator, context) {
- iterator = iterator.bind(context);
+ function inject(memo, iterator, context) {
this.each(function(value, index) {
- memo = iterator(memo, value, index);
+ memo = iterator.call(context, memo, value, index);
});
return memo;
- },
+ }
- invoke: function(method) {
+ function invoke(method) {
var args = $A(arguments).slice(1);
return this.map(function(value) {
return value[method].apply(value, args);
});
- },
+ }
- max: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function max(iterator, context) {
+ iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
- value = iterator(value, index);
+ value = iterator.call(context, value, index);
if (result == null || value >= result)
result = value;
});
return result;
- },
+ }
- min: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function min(iterator, context) {
+ iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
- value = iterator(value, index);
+ value = iterator.call(context, value, index);
if (result == null || value < result)
result = value;
});
return result;
- },
+ }
- partition: function(iterator, context) {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
+ function partition(iterator, context) {
+ iterator = iterator || Prototype.K;
var trues = [], falses = [];
this.each(function(value, index) {
- (iterator(value, index) ?
+ (iterator.call(context, value, index) ?
trues : falses).push(value);
});
return [trues, falses];
- },
+ }
- pluck: function(property) {
+ function pluck(property) {
var results = [];
this.each(function(value) {
results.push(value[property]);
});
return results;
- },
+ }
- reject: function(iterator, context) {
- iterator = iterator.bind(context);
+ function reject(iterator, context) {
var results = [];
this.each(function(value, index) {
- if (!iterator(value, index))
+ if (!iterator.call(context, value, index))
results.push(value);
});
return results;
- },
+ }
- sortBy: function(iterator, context) {
- iterator = iterator.bind(context);
+ function sortBy(iterator, context) {
return this.map(function(value, index) {
- return {value: value, criteria: iterator(value, index)};
+ return {
+ value: value,
+ criteria: iterator.call(context, value, index)
+ };
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
}).pluck('value');
- },
+ }
- toArray: function() {
+ function toArray() {
return this.map();
- },
+ }
- zip: function() {
+ function zip() {
var iterator = Prototype.K, args = $A(arguments);
if (Object.isFunction(args.last()))
iterator = args.pop();
@@ -782,330 +1004,409 @@ var Enumerable = {
return this.map(function(value, index) {
return iterator(collections.pluck(index));
});
- },
+ }
- size: function() {
+ function size() {
return this.toArray().length;
- },
+ }
- inspect: function() {
+ function inspect() {
return '#<Enumerable:' + this.toArray().inspect() + '>';
}
-};
-Object.extend(Enumerable, {
- map: Enumerable.collect,
- find: Enumerable.detect,
- select: Enumerable.findAll,
- filter: Enumerable.findAll,
- member: Enumerable.include,
- entries: Enumerable.toArray,
- every: Enumerable.all,
- some: Enumerable.any
-});
+
+
+
+
+
+
+
+
+ return {
+ each: each,
+ eachSlice: eachSlice,
+ all: all,
+ every: all,
+ any: any,
+ some: any,
+ collect: collect,
+ map: collect,
+ detect: detect,
+ findAll: findAll,
+ select: findAll,
+ filter: findAll,
+ grep: grep,
+ include: include,
+ member: include,
+ inGroupsOf: inGroupsOf,
+ inject: inject,
+ invoke: invoke,
+ max: max,
+ min: min,
+ partition: partition,
+ pluck: pluck,
+ reject: reject,
+ sortBy: sortBy,
+ toArray: toArray,
+ entries: toArray,
+ zip: zip,
+ size: size,
+ inspect: inspect,
+ find: detect
+ };
+})();
+
function $A(iterable) {
if (!iterable) return [];
- if (iterable.toArray) return iterable.toArray();
- var length = iterable.length, results = new Array(length);
+ if ('toArray' in Object(iterable)) return iterable.toArray();
+ var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}
-if (Prototype.Browser.WebKit) {
- function $A(iterable) {
- if (!iterable) return [];
- if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
- iterable.toArray) return iterable.toArray();
- var length = iterable.length, results = new Array(length);
- while (length--) results[length] = iterable[length];
- return results;
- }
+
+function $w(string) {
+ if (!Object.isString(string)) return [];
+ string = string.strip();
+ return string ? string.split(/\s+/) : [];
}
Array.from = $A;
-Object.extend(Array.prototype, Enumerable);
-if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
+(function() {
+ var arrayProto = Array.prototype,
+ slice = arrayProto.slice,
+ _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
-Object.extend(Array.prototype, {
- _each: function(iterator) {
+ function each(iterator) {
for (var i = 0, length = this.length; i < length; i++)
iterator(this[i]);
- },
+ }
+ if (!_each) _each = each;
- clear: function() {
+ function clear() {
this.length = 0;
return this;
- },
+ }
- first: function() {
+ function first() {
return this[0];
- },
+ }
- last: function() {
+ function last() {
return this[this.length - 1];
- },
+ }
- compact: function() {
+ function compact() {
return this.select(function(value) {
return value != null;
});
- },
+ }
- flatten: function() {
+ function flatten() {
return this.inject([], function(array, value) {
- return array.concat(Object.isArray(value) ?
- value.flatten() : [value]);
+ if (Object.isArray(value))
+ return array.concat(value.flatten());
+ array.push(value);
+ return array;
});
- },
+ }
- without: function() {
- var values = $A(arguments);
+ function without() {
+ var values = slice.call(arguments, 0);
return this.select(function(value) {
return !values.include(value);
});
- },
-
- reverse: function(inline) {
- return (inline !== false ? this : this.toArray())._reverse();
- },
+ }
- reduce: function() {
- return this.length > 1 ? this : this[0];
- },
+ function reverse(inline) {
+ return (inline === false ? this.toArray() : this)._reverse();
+ }
- uniq: function(sorted) {
+ function uniq(sorted) {
return this.inject([], function(array, value, index) {
if (0 == index || (sorted ? array.last() != value : !array.include(value)))
array.push(value);
return array;
});
- },
+ }
- intersect: function(array) {
+ function intersect(array) {
return this.uniq().findAll(function(item) {
return array.detect(function(value) { return item === value });
});
- },
+ }
- clone: function() {
- return [].concat(this);
- },
- size: function() {
+ function clone() {
+ return slice.call(this, 0);
+ }
+
+ function size() {
return this.length;
- },
+ }
- inspect: function() {
+ function inspect() {
return '[' + this.map(Object.inspect).join(', ') + ']';
- },
-
- toJSON: function() {
- var results = [];
- this.each(function(object) {
- var value = Object.toJSON(object);
- if (!Object.isUndefined(value)) results.push(value);
- });
- return '[' + results.join(', ') + ']';
}
-});
-
-// use native browser JS 1.6 implementation if available
-if (Object.isFunction(Array.prototype.forEach))
- Array.prototype._each = Array.prototype.forEach;
-
-if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
- i || (i = 0);
- var length = this.length;
- if (i < 0) i = length + i;
- for (; i < length; i++)
- if (this[i] === item) return i;
- return -1;
-};
-
-if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
- i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
- var n = this.slice(0, i).reverse().indexOf(item);
- return (n < 0) ? n : i - n - 1;
-};
-Array.prototype.toArray = Array.prototype.clone;
+ function indexOf(item, i) {
+ i || (i = 0);
+ var length = this.length;
+ if (i < 0) i = length + i;
+ for (; i < length; i++)
+ if (this[i] === item) return i;
+ return -1;
+ }
-function $w(string) {
- if (!Object.isString(string)) return [];
- string = string.strip();
- return string ? string.split(/\s+/) : [];
-}
+ function lastIndexOf(item, i) {
+ i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
+ var n = this.slice(0, i).reverse().indexOf(item);
+ return (n < 0) ? n : i - n - 1;
+ }
-if (Prototype.Browser.Opera){
- Array.prototype.concat = function() {
- var array = [];
- for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+ function concat() {
+ var array = slice.call(this, 0), item;
for (var i = 0, length = arguments.length; i < length; i++) {
- if (Object.isArray(arguments[i])) {
- for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
- array.push(arguments[i][j]);
+ item = arguments[i];
+ if (Object.isArray(item) && !('callee' in item)) {
+ for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
+ array.push(item[j]);
} else {
- array.push(arguments[i]);
+ array.push(item);
}
}
return array;
- };
-}
-Object.extend(Number.prototype, {
- toColorPart: function() {
- return this.toPaddedString(2, 16);
- },
-
- succ: function() {
- return this + 1;
- },
+ }
- times: function(iterator) {
- $R(0, this, true).each(iterator);
- return this;
- },
+ Object.extend(arrayProto, Enumerable);
+
+ if (!arrayProto._reverse)
+ arrayProto._reverse = arrayProto.reverse;
+
+ Object.extend(arrayProto, {
+ _each: _each,
+ clear: clear,
+ first: first,
+ last: last,
+ compact: compact,
+ flatten: flatten,
+ without: without,
+ reverse: reverse,
+ uniq: uniq,
+ intersect: intersect,
+ clone: clone,
+ toArray: clone,
+ size: size,
+ inspect: inspect
+ });
- toPaddedString: function(length, radix) {
- var string = this.toString(radix || 10);
- return '0'.times(length - string.length) + string;
- },
+ var CONCAT_ARGUMENTS_BUGGY = (function() {
+ return [].concat(arguments)[0][0] !== 1;
+ })(1,2)
- toJSON: function() {
- return isFinite(this) ? this.toString() : 'null';
- }
-});
+ if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
-$w('abs round ceil floor').each(function(method){
- Number.prototype[method] = Math[method].methodize();
-});
+ if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
+ if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
+})();
function $H(object) {
return new Hash(object);
};
var Hash = Class.create(Enumerable, (function() {
-
- function toQueryPair(key, value) {
- if (Object.isUndefined(value)) return key;
- return key + '=' + encodeURIComponent(String.interpret(value));
+ function initialize(object) {
+ this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
}
- return {
- initialize: function(object) {
- this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
- },
- _each: function(iterator) {
- for (var key in this._object) {
- var value = this._object[key], pair = [key, value];
- pair.key = key;
- pair.value = value;
- iterator(pair);
- }
- },
+ function _each(iterator) {
+ for (var key in this._object) {
+ var value = this._object[key], pair = [key, value];
+ pair.key = key;
+ pair.value = value;
+ iterator(pair);
+ }
+ }
- set: function(key, value) {
- return this._object[key] = value;
- },
+ function set(key, value) {
+ return this._object[key] = value;
+ }
- get: function(key) {
+ function get(key) {
+ if (this._object[key] !== Object.prototype[key])
return this._object[key];
- },
+ }
- unset: function(key) {
- var value = this._object[key];
- delete this._object[key];
- return value;
- },
+ function unset(key) {
+ var value = this._object[key];
+ delete this._object[key];
+ return value;
+ }
- toObject: function() {
- return Object.clone(this._object);
- },
+ function toObject() {
+ return Object.clone(this._object);
+ }
- keys: function() {
- return this.pluck('key');
- },
- values: function() {
- return this.pluck('value');
- },
- index: function(value) {
- var match = this.detect(function(pair) {
- return pair.value === value;
- });
- return match && match.key;
- },
+ function keys() {
+ return this.pluck('key');
+ }
- merge: function(object) {
- return this.clone().update(object);
- },
+ function values() {
+ return this.pluck('value');
+ }
- update: function(object) {
- return new Hash(object).inject(this, function(result, pair) {
- result.set(pair.key, pair.value);
- return result;
- });
- },
+ function index(value) {
+ var match = this.detect(function(pair) {
+ return pair.value === value;
+ });
+ return match && match.key;
+ }
- toQueryString: function() {
- return this.map(function(pair) {
- var key = encodeURIComponent(pair.key), values = pair.value;
+ function merge(object) {
+ return this.clone().update(object);
+ }
- if (values && typeof values == 'object') {
- if (Object.isArray(values))
- return values.map(toQueryPair.curry(key)).join('&');
- }
- return toQueryPair(key, values);
- }).join('&');
- },
+ function update(object) {
+ return new Hash(object).inject(this, function(result, pair) {
+ result.set(pair.key, pair.value);
+ return result;
+ });
+ }
- inspect: function() {
- return '#<Hash:{' + this.map(function(pair) {
- return pair.map(Object.inspect).join(': ');
- }).join(', ') + '}>';
- },
+ function toQueryPair(key, value) {
+ if (Object.isUndefined(value)) return key;
+ return key + '=' + encodeURIComponent(String.interpret(value));
+ }
- toJSON: function() {
- return Object.toJSON(this.toObject());
- },
+ function toQueryString() {
+ return this.inject([], function(results, pair) {
+ var key = encodeURIComponent(pair.key), values = pair.value;
- clone: function() {
- return new Hash(this);
- }
+ if (values && typeof values == 'object') {
+ if (Object.isArray(values))
+ return results.concat(values.map(toQueryPair.curry(key)));
+ } else results.push(toQueryPair(key, values));
+ return results;
+ }).join('&');
+ }
+
+ function inspect() {
+ return '#<Hash:{' + this.map(function(pair) {
+ return pair.map(Object.inspect).join(': ');
+ }).join(', ') + '}>';
+ }
+
+ function clone() {
+ return new Hash(this);
}
+
+ return {
+ initialize: initialize,
+ _each: _each,
+ set: set,
+ get: get,
+ unset: unset,
+ toObject: toObject,
+ toTemplateReplacements: toObject,
+ keys: keys,
+ values: values,
+ index: index,
+ merge: merge,
+ update: update,
+ toQueryString: toQueryString,
+ inspect: inspect,
+ toJSON: toObject,
+ clone: clone
+ };
})());
-Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
Hash.from = $H;
-var ObjectRange = Class.create(Enumerable, {
- initialize: function(start, end, exclusive) {
+Object.extend(Number.prototype, (function() {
+ function toColorPart() {
+ return this.toPaddedString(2, 16);
+ }
+
+ function succ() {
+ return this + 1;
+ }
+
+ function times(iterator, context) {
+ $R(0, this, true).each(iterator, context);
+ return this;
+ }
+
+ function toPaddedString(length, radix) {
+ var string = this.toString(radix || 10);
+ return '0'.times(length - string.length) + string;
+ }
+
+ function abs() {
+ return Math.abs(this);
+ }
+
+ function round() {
+ return Math.round(this);
+ }
+
+ function ceil() {
+ return Math.ceil(this);
+ }
+
+ function floor() {
+ return Math.floor(this);
+ }
+
+ return {
+ toColorPart: toColorPart,
+ succ: succ,
+ times: times,
+ toPaddedString: toPaddedString,
+ abs: abs,
+ round: round,
+ ceil: ceil,
+ floor: floor
+ };
+})());
+
+function $R(start, end, exclusive) {
+ return new ObjectRange(start, end, exclusive);
+}
+
+var ObjectRange = Class.create(Enumerable, (function() {
+ function initialize(start, end, exclusive) {
this.start = start;
this.end = end;
this.exclusive = exclusive;
- },
+ }
- _each: function(iterator) {
+ function _each(iterator) {
var value = this.start;
while (this.include(value)) {
iterator(value);
value = value.succ();
}
- },
+ }
- include: function(value) {
+ function include(value) {
if (value < this.start)
return false;
if (this.exclusive)
return value < this.end;
return value <= this.end;
}
-});
-var $R = function(start, end, exclusive) {
- return new ObjectRange(start, end, exclusive);
-};
+ return {
+ initialize: initialize,
+ _each: _each,
+ include: include
+ };
+})());
+
+
var Ajax = {
getTransport: function() {
@@ -1152,7 +1453,6 @@ Ajax.Responders.register({
onCreate: function() { Ajax.activeRequestCount++ },
onComplete: function() { Ajax.activeRequestCount-- }
});
-
Ajax.Base = Class.create({
initialize: function(options) {
this.options = {
@@ -1174,7 +1474,6 @@ Ajax.Base = Class.create({
this.options.parameters = this.options.parameters.toObject();
}
});
-
Ajax.Request = Class.create(Ajax.Base, {
_complete: false,
@@ -1190,7 +1489,6 @@ Ajax.Request = Class.create(Ajax.Base, {
var params = Object.clone(this.options.parameters);
if (!['get', 'post'].include(this.method)) {
- // simulate other verbs over post
params['_method'] = this.method;
this.method = 'post';
}
@@ -1198,7 +1496,6 @@ Ajax.Request = Class.create(Ajax.Base, {
this.parameters = params;
if (params = Object.toQueryString(params)) {
- // when GET, append parameters to URL
if (this.method == 'get')
this.url += (this.url.include('?') ? '&' : '?') + params;
else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
@@ -1257,7 +1554,6 @@ Ajax.Request = Class.create(Ajax.Base, {
headers['Connection'] = 'close';
}
- // user-defined headers
if (typeof this.options.requestHeaders == 'object') {
var extras = this.options.requestHeaders;
@@ -1298,7 +1594,7 @@ Ajax.Request = Class.create(Ajax.Base, {
var contentType = response.getHeader('Content-type');
if (this.options.evalJS == 'force'
- || (this.options.evalJS && contentType
+ || (this.options.evalJS && this.isSameOrigin() && contentType
&& contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
this.evalResponse();
}
@@ -1311,15 +1607,23 @@ Ajax.Request = Class.create(Ajax.Base, {
}
if (state == 'Complete') {
- // avoid memory leak in MSIE: clean up
this.transport.onreadystatechange = Prototype.emptyFunction;
}
},
+ isSameOrigin: function() {
+ var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
+ return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
+ protocol: location.protocol,
+ domain: document.domain,
+ port: location.port ? ':' + location.port : ''
+ }));
+ },
+
getHeader: function(name) {
try {
- return this.transport.getResponseHeader(name);
- } catch (e) { return null }
+ return this.transport.getResponseHeader(name) || null;
+ } catch (e) { return null; }
},
evalResponse: function() {
@@ -1339,20 +1643,27 @@ Ajax.Request = Class.create(Ajax.Base, {
Ajax.Request.Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+
+
+
+
+
+
Ajax.Response = Class.create({
initialize: function(request){
this.request = request;
var transport = this.transport = request.transport,
readyState = this.readyState = transport.readyState;
- if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
+ if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
this.status = this.getStatus();
this.statusText = this.getStatusText();
this.responseText = String.interpret(transport.responseText);
this.headerJSON = this._getHeaderJSON();
}
- if(readyState == 4) {
+ if (readyState == 4) {
var xml = transport.responseXML;
this.responseXML = Object.isUndefined(xml) ? null : xml;
this.responseJSON = this._getResponseJSON();
@@ -1360,6 +1671,7 @@ Ajax.Response = Class.create({
},
status: 0,
+
statusText: '',
getStatus: Ajax.Request.prototype.getStatus,
@@ -1391,7 +1703,8 @@ Ajax.Response = Class.create({
if (!json) return null;
json = decodeURIComponent(escape(json));
try {
- return json.evalJSON(this.request.options.sanitizeJSON);
+ return json.evalJSON(this.request.options.sanitizeJSON ||
+ !this.request.isSameOrigin());
} catch (e) {
this.request.dispatchException(e);
}
@@ -1404,7 +1717,8 @@ Ajax.Response = Class.create({
this.responseText.blank())
return null;
try {
- return this.responseText.evalJSON(options.sanitizeJSON);
+ return this.responseText.evalJSON(options.sanitizeJSON ||
+ !this.request.isSameOrigin());
} catch (e) {
this.request.dispatchException(e);
}
@@ -1487,6 +1801,8 @@ Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
+
+
function $(element) {
if (arguments.length > 1) {
for (var i = 0, elements = [], length = arguments.length; i < length; i++)
@@ -1511,10 +1827,9 @@ if (Prototype.BrowserFeatures.XPath) {
/*--------------------------------------------------------------------------*/
-if (!window.Node) var Node = { };
+if (!Node) var Node = { };
if (!Node.ELEMENT_NODE) {
- // DOM level 2 ECMAScript Language Binding
Object.extend(Node, {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
@@ -1531,13 +1846,27 @@ if (!Node.ELEMENT_NODE) {
});
}
-(function() {
- var element = this.Element;
- this.Element = function(tagName, attributes) {
+
+
+(function(global) {
+
+ var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
+ try {
+ var el = document.createElement('<input name="x">');
+ return el.tagName.toLowerCase() === 'input' && el.name === 'x';
+ }
+ catch(err) {
+ return false;
+ }
+ })();
+
+ var element = global.Element;
+
+ global.Element = function(tagName, attributes) {
attributes = attributes || { };
tagName = tagName.toLowerCase();
var cache = Element.cache;
- if (Prototype.Browser.IE && attributes.name) {
+ if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
tagName = '<' + tagName + ' name="' + attributes.name + '">';
delete attributes.name;
return Element.writeAttribute(document.createElement(tagName), attributes);
@@ -1545,11 +1874,24 @@ if (!Node.ELEMENT_NODE) {
if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
};
- Object.extend(this.Element, element || { });
-}).call(window);
+ Object.extend(global.Element, element || { });
+ if (element) global.Element.prototype = element.prototype;
+
+})(this);
+
+Element.idCounter = 1;
Element.cache = { };
+function purgeElement(element) {
+ var uid = element._prototypeUID;
+ if (uid) {
+ Element.stopObserving(element);
+ element._prototypeUID = void 0;
+ delete Element.Storage[uid];
+ }
+}
+
Element.Methods = {
visible: function(element) {
return $(element).style.display != 'none';
@@ -1562,12 +1904,14 @@ Element.Methods = {
},
hide: function(element) {
- $(element).style.display = 'none';
+ element = $(element);
+ element.style.display = 'none';
return element;
},
show: function(element) {
- $(element).style.display = '';
+ element = $(element);
+ element.style.display = '';
return element;
},
@@ -1577,15 +1921,93 @@ Element.Methods = {
return element;
},
- update: function(element, content) {
- element = $(element);
- if (content && content.toElement) content = content.toElement();
- if (Object.isElement(content)) return element.update().insert(content);
- content = Object.toHTML(content);
- element.innerHTML = content.stripScripts();
- content.evalScripts.bind(content).defer();
- return element;
- },
+ update: (function(){
+
+ var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
+ var el = document.createElement("select"),
+ isBuggy = true;
+ el.innerHTML = "<option value=\"test\">test</option>";
+ if (el.options && el.options[0]) {
+ isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
+ }
+ el = null;
+ return isBuggy;
+ })();
+
+ var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
+ try {
+ var el = document.createElement("table");
+ if (el && el.tBodies) {
+ el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
+ var isBuggy = typeof el.tBodies[0] == "undefined";
+ el = null;
+ return isBuggy;
+ }
+ } catch (e) {
+ return true;
+ }
+ })();
+
+ var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
+ var s = document.createElement("script"),
+ isBuggy = false;
+ try {
+ s.appendChild(document.createTextNode(""));
+ isBuggy = !s.firstChild ||
+ s.firstChild && s.firstChild.nodeType !== 3;
+ } catch (e) {
+ isBuggy = true;
+ }
+ s = null;
+ return isBuggy;
+ })();
+
+ function update(element, content) {
+ element = $(element);
+
+ var descendants = element.getElementsByTagName('*'),
+ i = descendants.length;
+ while (i--) purgeElement(descendants[i]);
+
+ if (content && content.toElement)
+ content = content.toElement();
+
+ if (Object.isElement(content))
+ return element.update().insert(content);
+
+ content = Object.toHTML(content);
+
+ var tagName = element.tagName.toUpperCase();
+
+ if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
+ element.text = content;
+ return element;
+ }
+
+ if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) {
+ if (tagName in Element._insertionTranslations.tags) {
+ while (element.firstChild) {
+ element.removeChild(element.firstChild);
+ }
+ Element._getContentFromAnonymousElement(tagName, content.stripScripts())
+ .each(function(node) {
+ element.appendChild(node)
+ });
+ }
+ else {
+ element.innerHTML = content.stripScripts();
+ }
+ }
+ else {
+ element.innerHTML = content.stripScripts();
+ }
+
+ content.evalScripts.bind(content).defer();
+ return element;
+ }
+
+ return update;
+ })(),
replace: function(element, content) {
element = $(element);
@@ -1608,24 +2030,28 @@ Element.Methods = {
Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
insertions = {bottom:insertions};
- var content, t, range;
+ var content, insert, tagName, childNodes;
- for (position in insertions) {
+ for (var position in insertions) {
content = insertions[position];
position = position.toLowerCase();
- t = Element._insertionTranslations[position];
+ insert = Element._insertionTranslations[position];
if (content && content.toElement) content = content.toElement();
if (Object.isElement(content)) {
- t.insert(element, content);
+ insert(element, content);
continue;
}
content = Object.toHTML(content);
- range = element.ownerDocument.createRange();
- t.initializeRange(element, range);
- t.insert(element, range.createContextualFragment(content.stripScripts()));
+ tagName = ((position == 'before' || position == 'after')
+ ? element.parentNode : element).tagName.toUpperCase();
+
+ childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+
+ if (position == 'top' || position == 'after') childNodes.reverse();
+ childNodes.each(insert.curry(element));
content.evalScripts.bind(content).defer();
}
@@ -1649,28 +2075,35 @@ Element.Methods = {
element = $(element);
var result = '<' + element.tagName.toLowerCase();
$H({'id': 'id', 'className': 'class'}).each(function(pair) {
- var property = pair.first(), attribute = pair.last();
- var value = (element[property] || '').toString();
+ var property = pair.first(),
+ attribute = pair.last(),
+ value = (element[property] || '').toString();
if (value) result += ' ' + attribute + '=' + value.inspect(true);
});
return result + '>';
},
- recursivelyCollect: function(element, property) {
+ recursivelyCollect: function(element, property, maximumLength) {
element = $(element);
+ maximumLength = maximumLength || -1;
var elements = [];
- while (element = element[property])
+
+ while (element = element[property]) {
if (element.nodeType == 1)
elements.push(Element.extend(element));
+ if (elements.length == maximumLength)
+ break;
+ }
+
return elements;
},
ancestors: function(element) {
- return $(element).recursivelyCollect('parentNode');
+ return Element.recursivelyCollect(element, 'parentNode');
},
descendants: function(element) {
- return $(element).getElementsBySelector("*");
+ return Element.select(element, "*");
},
firstDescendant: function(element) {
@@ -1680,79 +2113,96 @@ Element.Methods = {
},
immediateDescendants: function(element) {
- if (!(element = $(element).firstChild)) return [];
- while (element && element.nodeType != 1) element = element.nextSibling;
- if (element) return [element].concat($(element).nextSiblings());
- return [];
+ var results = [], child = $(element).firstChild;
+ while (child) {
+ if (child.nodeType === 1) {
+ results.push(Element.extend(child));
+ }
+ child = child.nextSibling;
+ }
+ return results;
},
- previousSiblings: function(element) {
- return $(element).recursivelyCollect('previousSibling');
+ previousSiblings: function(element, maximumLength) {
+ return Element.recursivelyCollect(element, 'previousSibling');
},
nextSiblings: function(element) {
- return $(element).recursivelyCollect('nextSibling');
+ return Element.recursivelyCollect(element, 'nextSibling');
},
siblings: function(element) {
element = $(element);
- return element.previousSiblings().reverse().concat(element.nextSiblings());
+ return Element.previousSiblings(element).reverse()
+ .concat(Element.nextSiblings(element));
},
match: function(element, selector) {
+ element = $(element);
if (Object.isString(selector))
- selector = new Selector(selector);
- return selector.match($(element));
+ return Prototype.Selector.match(element, selector);
+ return selector.match(element);
},
up: function(element, expression, index) {
element = $(element);
if (arguments.length == 1) return $(element.parentNode);
- var ancestors = element.ancestors();
- return expression ? Selector.findElement(ancestors, expression, index) :
- ancestors[index || 0];
+ var ancestors = Element.ancestors(element);
+ return Object.isNumber(expression) ? ancestors[expression] :
+ Prototype.Selector.find(ancestors, expression, index);
},
down: function(element, expression, index) {
element = $(element);
- if (arguments.length == 1) return element.firstDescendant();
- var descendants = element.descendants();
- return expression ? Selector.findElement(descendants, expression, index) :
- descendants[index || 0];
+ if (arguments.length == 1) return Element.firstDescendant(element);
+ return Object.isNumber(expression) ? Element.descendants(element)[expression] :
+ Element.select(element, expression)[index || 0];
},
previous: function(element, expression, index) {
element = $(element);
- if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
- var previousSiblings = element.previousSiblings();
- return expression ? Selector.findElement(previousSiblings, expression, index) :
- previousSiblings[index || 0];
+ if (Object.isNumber(expression)) index = expression, expression = false;
+ if (!Object.isNumber(index)) index = 0;
+
+ if (expression) {
+ return Prototype.Selector.find(element.previousSiblings(), expression, index);
+ } else {
+ return element.recursivelyCollect("previousSibling", index + 1)[index];
+ }
},
next: function(element, expression, index) {
element = $(element);
- if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
- var nextSiblings = element.nextSiblings();
- return expression ? Selector.findElement(nextSiblings, expression, index) :
- nextSiblings[index || 0];
+ if (Object.isNumber(expression)) index = expression, expression = false;
+ if (!Object.isNumber(index)) index = 0;
+
+ if (expression) {
+ return Prototype.Selector.find(element.nextSiblings(), expression, index);
+ } else {
+ var maximumLength = Object.isNumber(index) ? index + 1 : 1;
+ return element.recursivelyCollect("nextSibling", index + 1)[index];
+ }
},
- select: function() {
- var args = $A(arguments), element = $(args.shift());
- return Selector.findChildElements(element, args);
+
+ select: function(element) {
+ element = $(element);
+ var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
+ return Prototype.Selector.select(expressions, element);
},
- adjacent: function() {
- var args = $A(arguments), element = $(args.shift());
- return Selector.findChildElements(element.parentNode, args).without(element);
+ adjacent: function(element) {
+ element = $(element);
+ var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
+ return Prototype.Selector.select(expressions, element.parentNode).without(element);
},
identify: function(element) {
element = $(element);
- var id = element.readAttribute('id'), self = arguments.callee;
+ var id = Element.readAttribute(element, 'id');
if (id) return id;
- do { id = 'anonymous_element_' + self.counter++ } while ($(id));
- element.writeAttribute('id', id);
+ do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
+ Element.writeAttribute(element, 'id', id);
return id;
},
@@ -1791,11 +2241,11 @@ Element.Methods = {
},
getHeight: function(element) {
- return $(element).getDimensions().height;
+ return Element.getDimensions(element).height;
},
getWidth: function(element) {
- return $(element).getDimensions().width;
+ return Element.getDimensions(element).width;
},
classNames: function(element) {
@@ -1811,7 +2261,7 @@ Element.Methods = {
addClassName: function(element, className) {
if (!(element = $(element))) return;
- if (!element.hasClassName(className))
+ if (!Element.hasClassName(element, className))
element.className += (element.className ? ' ' : '') + className;
return element;
},
@@ -1825,11 +2275,10 @@ Element.Methods = {
toggleClassName: function(element, className) {
if (!(element = $(element))) return;
- return element[element.hasClassName(className) ?
- 'removeClassName' : 'addClassName'](className);
+ return Element[Element.hasClassName(element, className) ?
+ 'removeClassName' : 'addClassName'](element, className);
},
- // removes whitespace-only text node children
cleanWhitespace: function(element) {
element = $(element);
var node = element.firstChild;
@@ -1848,29 +2297,22 @@ Element.Methods = {
descendantOf: function(element, ancestor) {
element = $(element), ancestor = $(ancestor);
- var originalAncestor = ancestor;
if (element.compareDocumentPosition)
return (element.compareDocumentPosition(ancestor) & 8) === 8;
- if (element.sourceIndex && !Prototype.Browser.Opera) {
- var e = element.sourceIndex, a = ancestor.sourceIndex,
- nextAncestor = ancestor.nextSibling;
- if (!nextAncestor) {
- do { ancestor = ancestor.parentNode; }
- while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
- }
- if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex);
- }
+ if (ancestor.contains)
+ return ancestor.contains(element) && ancestor !== element;
while (element = element.parentNode)
- if (element == originalAncestor) return true;
+ if (element == ancestor) return true;
+
return false;
},
scrollTo: function(element) {
element = $(element);
- var pos = element.cumulativeOffset();
+ var pos = Element.cumulativeOffset(element);
window.scrollTo(pos[0], pos[1]);
return element;
},
@@ -1879,7 +2321,7 @@ Element.Methods = {
element = $(element);
style = style == 'float' ? 'cssFloat' : style.camelize();
var value = element.style[style];
- if (!value) {
+ if (!value || value == 'auto') {
var css = document.defaultView.getComputedStyle(element, null);
value = css ? css[style] : null;
}
@@ -1916,38 +2358,13 @@ Element.Methods = {
return element;
},
- getDimensions: function(element) {
- element = $(element);
- var display = $(element).getStyle('display');
- if (display != 'none' && display != null) // Safari bug
- return {width: element.offsetWidth, height: element.offsetHeight};
-
- // All *Width and *Height properties give 0 on elements with display none,
- // so enable the element temporarily
- var els = element.style;
- var originalVisibility = els.visibility;
- var originalPosition = els.position;
- var originalDisplay = els.display;
- els.visibility = 'hidden';
- els.position = 'absolute';
- els.display = 'block';
- var originalWidth = element.clientWidth;
- var originalHeight = element.clientHeight;
- els.display = originalDisplay;
- els.position = originalPosition;
- els.visibility = originalVisibility;
- return {width: originalWidth, height: originalHeight};
- },
-
makePositioned: function(element) {
element = $(element);
var pos = Element.getStyle(element, 'position');
if (pos == 'static' || !pos) {
element._madePositioned = true;
element.style.position = 'relative';
- // Opera returns the offset relative to the positioning context, when an
- // element is position relative but top and left have not been defined
- if (window.opera) {
+ if (Prototype.Browser.Opera) {
element.style.top = 0;
element.style.left = 0;
}
@@ -1987,11 +2404,13 @@ Element.Methods = {
cumulativeOffset: function(element) {
var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
+ if (element.parentNode) {
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+ }
return Element._returnOffset(valueL, valueT);
},
@@ -2002,9 +2421,9 @@ Element.Methods = {
valueL += element.offsetLeft || 0;
element = element.offsetParent;
if (element) {
- if (element.tagName == 'BODY') break;
+ if (element.tagName.toUpperCase() == 'BODY') break;
var p = Element.getStyle(element, 'position');
- if (p == 'relative' || p == 'absolute') break;
+ if (p !== 'static') break;
}
} while (element);
return Element._returnOffset(valueL, valueT);
@@ -2012,14 +2431,13 @@ Element.Methods = {
absolutize: function(element) {
element = $(element);
- if (element.getStyle('position') == 'absolute') return;
- // Position.prepare(); // To be done manually by Scripty when it needs it.
+ if (Element.getStyle(element, 'position') == 'absolute') return element;
- var offsets = element.positionedOffset();
- var top = offsets[1];
- var left = offsets[0];
- var width = element.clientWidth;
- var height = element.clientHeight;
+ var offsets = Element.positionedOffset(element),
+ top = offsets[1],
+ left = offsets[0],
+ width = element.clientWidth,
+ height = element.clientHeight;
element._originalLeft = left - parseFloat(element.style.left || 0);
element._originalTop = top - parseFloat(element.style.top || 0);
@@ -2036,12 +2454,11 @@ Element.Methods = {
relativize: function(element) {
element = $(element);
- if (element.getStyle('position') == 'relative') return;
- // Position.prepare(); // To be done manually by Scripty when it needs it.
+ if (Element.getStyle(element, 'position') == 'relative') return element;
element.style.position = 'relative';
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+ var top = parseFloat(element.style.top || 0) - (element._originalTop || 0),
+ left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
element.style.top = top + 'px';
element.style.left = left + 'px';
@@ -2072,14 +2489,14 @@ Element.Methods = {
},
viewportOffset: function(forElement) {
- var valueT = 0, valueL = 0;
+ var valueT = 0,
+ valueL = 0,
+ element = forElement;
- var element = forElement;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
- // Safari fix
if (element.offsetParent == document.body &&
Element.getStyle(element, 'position') == 'absolute') break;
@@ -2087,7 +2504,7 @@ Element.Methods = {
element = forElement;
do {
- if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
+ if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
valueT -= element.scrollTop || 0;
valueL -= element.scrollLeft || 0;
}
@@ -2106,28 +2523,21 @@ Element.Methods = {
offsetLeft: 0
}, arguments[2] || { });
- // find page position of source
source = $(source);
- var p = source.viewportOffset();
+ var p = Element.viewportOffset(source), delta = [0, 0], parent = null;
- // find coordinate system to use
element = $(element);
- var delta = [0, 0];
- var parent = null;
- // delta [0,0] will do fine with position: fixed elements,
- // position:absolute needs offsetParent deltas
+
if (Element.getStyle(element, 'position') == 'absolute') {
- parent = element.getOffsetParent();
- delta = parent.viewportOffset();
+ parent = Element.getOffsetParent(element);
+ delta = Element.viewportOffset(parent);
}
- // correct by body offsets (fixes Safari)
if (parent == document.body) {
delta[0] -= document.body.offsetLeft;
delta[1] -= document.body.offsetTop;
}
- // set position
if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
if (options.setWidth) element.style.width = source.offsetWidth + 'px';
@@ -2136,10 +2546,9 @@ Element.Methods = {
}
};
-Element.Methods.identify.counter = 1;
-
Object.extend(Element.Methods, {
getElementsBySelector: Element.Methods.select,
+
childElements: Element.Methods.immediateDescendants
});
@@ -2153,46 +2562,6 @@ Element._attributeTranslations = {
}
};
-
-if (!document.createRange || Prototype.Browser.Opera) {
- Element.Methods.insert = function(element, insertions) {
- element = $(element);
-
- if (Object.isString(insertions) || Object.isNumber(insertions) ||
- Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
- insertions = { bottom: insertions };
-
- var t = Element._insertionTranslations, content, position, pos, tagName;
-
- for (position in insertions) {
- content = insertions[position];
- position = position.toLowerCase();
- pos = t[position];
-
- if (content && content.toElement) content = content.toElement();
- if (Object.isElement(content)) {
- pos.insert(element, content);
- continue;
- }
-
- content = Object.toHTML(content);
- tagName = ((position == 'before' || position == 'after')
- ? element.parentNode : element).tagName.toUpperCase();
-
- if (t.tags[tagName]) {
- var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
- if (position == 'top' || position == 'after') fragments.reverse();
- fragments.each(pos.insert.curry(element));
- }
- else element.insertAdjacentHTML(pos.adjacency, content.stripScripts());
-
- content.evalScripts.bind(content).defer();
- }
-
- return element;
- };
-}
-
if (Prototype.Browser.Opera) {
Element.Methods.getStyle = Element.Methods.getStyle.wrap(
function(proceed, element, style) {
@@ -2200,11 +2569,8 @@ if (Prototype.Browser.Opera) {
case 'left': case 'top': case 'right': case 'bottom':
if (proceed(element, 'position') === 'static') return null;
case 'height': case 'width':
- // returns '0px' for hidden elements; we want it to return null
if (!Element.visible(element)) return null;
- // returns the border-box dimensions rather than the content-box
- // dimensions, so we subtract padding and borders from the value
var dim = parseInt(proceed(element, style), 10);
if (dim !== element['offset' + style.capitalize()])
@@ -2237,12 +2603,29 @@ if (Prototype.Browser.Opera) {
}
else if (Prototype.Browser.IE) {
- $w('positionedOffset getOffsetParent viewportOffset').each(function(method) {
+ Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
+ function(proceed, element) {
+ element = $(element);
+ if (!element.parentNode) return $(document.body);
+ var position = element.getStyle('position');
+ if (position !== 'static') return proceed(element);
+ element.setStyle({ position: 'relative' });
+ var value = proceed(element);
+ element.setStyle({ position: position });
+ return value;
+ }
+ );
+
+ $w('positionedOffset viewportOffset').each(function(method) {
Element.Methods[method] = Element.Methods[method].wrap(
function(proceed, element) {
element = $(element);
+ if (!element.parentNode) return Element._returnOffset(0, 0);
var position = element.getStyle('position');
- if (position != 'static') return proceed(element);
+ if (position !== 'static') return proceed(element);
+ var offsetParent = element.getOffsetParent();
+ if (offsetParent && offsetParent.getStyle('position') === 'fixed')
+ offsetParent.setStyle({ zoom: 1 });
element.setStyle({ position: 'relative' });
var value = proceed(element);
element.setStyle({ position: position });
@@ -2292,39 +2675,96 @@ else if (Prototype.Browser.IE) {
return element;
};
- Element._attributeTranslations = {
- read: {
- names: {
- 'class': 'className',
- 'for': 'htmlFor'
- },
- values: {
- _getAttr: function(element, attribute) {
- return element.getAttribute(attribute, 2);
- },
- _getAttrNode: function(element, attribute) {
- var node = element.getAttributeNode(attribute);
- return node ? node.value : "";
- },
- _getEv: function(element, attribute) {
- attribute = element.getAttribute(attribute);
- return attribute ? attribute.toString().slice(23, -2) : null;
- },
- _flag: function(element, attribute) {
- return $(element).hasAttribute(attribute) ? attribute : null;
- },
- style: function(element) {
- return element.style.cssText.toLowerCase();
+ Element._attributeTranslations = (function(){
+
+ var classProp = 'className',
+ forProp = 'for',
+ el = document.createElement('div');
+
+ el.setAttribute(classProp, 'x');
+
+ if (el.className !== 'x') {
+ el.setAttribute('class', 'x');
+ if (el.className === 'x') {
+ classProp = 'class';
+ }
+ }
+ el = null;
+
+ el = document.createElement('label');
+ el.setAttribute(forProp, 'x');
+ if (el.htmlFor !== 'x') {
+ el.setAttribute('htmlFor', 'x');
+ if (el.htmlFor === 'x') {
+ forProp = 'htmlFor';
+ }
+ }
+ el = null;
+
+ return {
+ read: {
+ names: {
+ 'class': classProp,
+ 'className': classProp,
+ 'for': forProp,
+ 'htmlFor': forProp
},
- title: function(element) {
- return element.title;
+ values: {
+ _getAttr: function(element, attribute) {
+ return element.getAttribute(attribute);
+ },
+ _getAttr2: function(element, attribute) {
+ return element.getAttribute(attribute, 2);
+ },
+ _getAttrNode: function(element, attribute) {
+ var node = element.getAttributeNode(attribute);
+ return node ? node.value : "";
+ },
+ _getEv: (function(){
+
+ var el = document.createElement('div'), f;
+ el.onclick = Prototype.emptyFunction;
+ var value = el.getAttribute('onclick');
+
+ if (String(value).indexOf('{') > -1) {
+ f = function(element, attribute) {
+ attribute = element.getAttribute(attribute);
+ if (!attribute) return null;
+ attribute = attribute.toString();
+ attribute = attribute.split('{')[1];
+ attribute = attribute.split('}')[0];
+ return attribute.strip();
+ };
+ }
+ else if (value === '') {
+ f = function(element, attribute) {
+ attribute = element.getAttribute(attribute);
+ if (!attribute) return null;
+ return attribute.strip();
+ };
+ }
+ el = null;
+ return f;
+ })(),
+ _flag: function(element, attribute) {
+ return $(element).hasAttribute(attribute) ? attribute : null;
+ },
+ style: function(element) {
+ return element.style.cssText.toLowerCase();
+ },
+ title: function(element) {
+ return element.title;
+ }
}
}
}
- };
+ })();
Element._attributeTranslations.write = {
- names: Object.clone(Element._attributeTranslations.read.names),
+ names: Object.extend({
+ cellpadding: 'cellPadding',
+ cellspacing: 'cellSpacing'
+ }, Element._attributeTranslations.read.names),
values: {
checked: function(element, value) {
element.checked = !!value;
@@ -2339,15 +2779,15 @@ else if (Prototype.Browser.IE) {
Element._attributeTranslations.has = {};
$w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
- 'encType maxLength readOnly longDesc').each(function(attr) {
+ 'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
Element._attributeTranslations.has[attr.toLowerCase()] = attr;
});
(function(v) {
Object.extend(v, {
- href: v._getAttr,
- src: v._getAttr,
+ href: v._getAttr2,
+ src: v._getAttr2,
type: v._getAttr,
action: v._getAttrNode,
disabled: v._flag,
@@ -2374,6 +2814,26 @@ else if (Prototype.Browser.IE) {
onchange: v._getEv
});
})(Element._attributeTranslations.read.values);
+
+ if (Prototype.BrowserFeatures.ElementExtensions) {
+ (function() {
+ function _descendants(element) {
+ var nodes = element.getElementsByTagName('*'), results = [];
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node.tagName !== "!") // Filter out comment nodes.
+ results.push(node);
+ return results;
+ }
+
+ Element.Methods.down = function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return element.firstDescendant();
+ return Object.isNumber(expression) ? _descendants(element)[expression] :
+ Element.select(element, expression)[index || 0];
+ }
+ })();
+ }
+
}
else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
@@ -2392,7 +2852,7 @@ else if (Prototype.Browser.WebKit) {
(value < 0.00001) ? 0 : value;
if (value == 1)
- if(element.tagName == 'IMG' && element.width) {
+ if (element.tagName.toUpperCase() == 'IMG' && element.width) {
element.width++; element.width--;
} else try {
var n = document.createTextNode(' ');
@@ -2403,9 +2863,6 @@ else if (Prototype.Browser.WebKit) {
return element;
};
- // Safari returns margins on body which is incorrect if the child is absolutely
- // positioned. For performance reasons, redefine Element#cumulativeOffset for
- // KHTML/WebKit only.
Element.Methods.cumulativeOffset = function(element) {
var valueT = 0, valueL = 0;
do {
@@ -2421,30 +2878,7 @@ else if (Prototype.Browser.WebKit) {
};
}
-if (Prototype.Browser.IE || Prototype.Browser.Opera) {
- // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
- Element.Methods.update = function(element, content) {
- element = $(element);
-
- if (content && content.toElement) content = content.toElement();
- if (Object.isElement(content)) return element.update().insert(content);
-
- content = Object.toHTML(content);
- var tagName = element.tagName.toUpperCase();
-
- if (tagName in Element._insertionTranslations.tags) {
- $A(element.childNodes).each(function(node) { element.removeChild(node) });
- Element._getContentFromAnonymousElement(tagName, content.stripScripts())
- .each(function(node) { element.appendChild(node) });
- }
- else element.innerHTML = content.stripScripts();
-
- content.evalScripts.bind(content).defer();
- return element;
- };
-}
-
-if (document.createElement('div').outerHTML) {
+if ('outerHTML' in document.documentElement) {
Element.Methods.replace = function(element, content) {
element = $(element);
@@ -2458,8 +2892,8 @@ if (document.createElement('div').outerHTML) {
var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
if (Element._insertionTranslations.tags[tagName]) {
- var nextSibling = element.next();
- var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+ var nextSibling = element.next(),
+ fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
parent.removeChild(element);
if (nextSibling)
fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
@@ -2481,46 +2915,32 @@ Element._returnOffset = function(l, t) {
};
Element._getContentFromAnonymousElement = function(tagName, html) {
- var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
- div.innerHTML = t[0] + html + t[1];
- t[2].times(function() { div = div.firstChild });
+ var div = new Element('div'),
+ t = Element._insertionTranslations.tags[tagName];
+ if (t) {
+ div.innerHTML = t[0] + html + t[1];
+ for (var i = t[2]; i--; ) {
+ div = div.firstChild;
+ }
+ }
+ else {
+ div.innerHTML = html;
+ }
return $A(div.childNodes);
};
Element._insertionTranslations = {
- before: {
- adjacency: 'beforeBegin',
- insert: function(element, node) {
- element.parentNode.insertBefore(node, element);
- },
- initializeRange: function(element, range) {
- range.setStartBefore(element);
- }
+ before: function(element, node) {
+ element.parentNode.insertBefore(node, element);
},
- top: {
- adjacency: 'afterBegin',
- insert: function(element, node) {
- element.insertBefore(node, element.firstChild);
- },
- initializeRange: function(element, range) {
- range.selectNodeContents(element);
- range.collapse(true);
- }
+ top: function(element, node) {
+ element.insertBefore(node, element.firstChild);
},
- bottom: {
- adjacency: 'beforeEnd',
- insert: function(element, node) {
- element.appendChild(node);
- }
+ bottom: function(element, node) {
+ element.appendChild(node);
},
- after: {
- adjacency: 'afterEnd',
- insert: function(element, node) {
- element.parentNode.insertBefore(node, element.nextSibling);
- },
- initializeRange: function(element, range) {
- range.setStartAfter(element);
- }
+ after: function(element, node) {
+ element.parentNode.insertBefore(node, element.nextSibling);
},
tags: {
TABLE: ['<table>', '</table>', 1],
@@ -2532,19 +2952,19 @@ Element._insertionTranslations = {
};
(function() {
- this.bottom.initializeRange = this.top.initializeRange;
- Object.extend(this.tags, {
- THEAD: this.tags.TBODY,
- TFOOT: this.tags.TBODY,
- TH: this.tags.TD
+ var tags = Element._insertionTranslations.tags;
+ Object.extend(tags, {
+ THEAD: tags.TBODY,
+ TFOOT: tags.TBODY,
+ TH: tags.TD
});
-}).call(Element._insertionTranslations);
+})();
Element.Methods.Simulated = {
hasAttribute: function(element, attribute) {
attribute = Element._attributeTranslations.has[attribute] || attribute;
var node = $(element).getAttributeNode(attribute);
- return node && node.specified;
+ return !!(node && node.specified);
}
};
@@ -2552,41 +2972,81 @@ Element.Methods.ByTag = { };
Object.extend(Element, Element.Methods);
-if (!Prototype.BrowserFeatures.ElementExtensions &&
- document.createElement('div').__proto__) {
- window.HTMLElement = { };
- window.HTMLElement.prototype = document.createElement('div').__proto__;
- Prototype.BrowserFeatures.ElementExtensions = true;
-}
+(function(div) {
+
+ if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
+ window.HTMLElement = { };
+ window.HTMLElement.prototype = div['__proto__'];
+ Prototype.BrowserFeatures.ElementExtensions = true;
+ }
+
+ div = null;
+
+})(document.createElement('div'));
Element.extend = (function() {
- if (Prototype.BrowserFeatures.SpecificElementExtensions)
+
+ function checkDeficiency(tagName) {
+ if (typeof window.Element != 'undefined') {
+ var proto = window.Element.prototype;
+ if (proto) {
+ var id = '_' + (Math.random()+'').slice(2),
+ el = document.createElement(tagName);
+ proto[id] = 'x';
+ var isBuggy = (el[id] !== 'x');
+ delete proto[id];
+ el = null;
+ return isBuggy;
+ }
+ }
+ return false;
+ }
+
+ function extendElementWith(element, methods) {
+ for (var property in methods) {
+ var value = methods[property];
+ if (Object.isFunction(value) && !(property in element))
+ element[property] = value.methodize();
+ }
+ }
+
+ var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
+
+ if (Prototype.BrowserFeatures.SpecificElementExtensions) {
+ if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
+ return function(element) {
+ if (element && typeof element._extendedByPrototype == 'undefined') {
+ var t = element.tagName;
+ if (t && (/^(?:object|applet|embed)$/i.test(t))) {
+ extendElementWith(element, Element.Methods);
+ extendElementWith(element, Element.Methods.Simulated);
+ extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
+ }
+ }
+ return element;
+ }
+ }
return Prototype.K;
+ }
var Methods = { }, ByTag = Element.Methods.ByTag;
var extend = Object.extend(function(element) {
- if (!element || element._extendedByPrototype ||
+ if (!element || typeof element._extendedByPrototype != 'undefined' ||
element.nodeType != 1 || element == window) return element;
var methods = Object.clone(Methods),
- tagName = element.tagName, property, value;
+ tagName = element.tagName.toUpperCase();
- // extend methods for specific tags
if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
- for (property in methods) {
- value = methods[property];
- if (Object.isFunction(value) && !(property in element))
- element[property] = value.methodize();
- }
+ extendElementWith(element, methods);
element._extendedByPrototype = Prototype.emptyFunction;
return element;
}, {
refresh: function() {
- // extend methods for all tags (Safari doesn't need this)
if (!Prototype.BrowserFeatures.ElementExtensions) {
Object.extend(Methods, Element.Methods);
Object.extend(Methods, Element.Methods.Simulated);
@@ -2598,10 +3058,14 @@ Element.extend = (function() {
return extend;
})();
-Element.hasAttribute = function(element, attribute) {
- if (element.hasAttribute) return element.hasAttribute(attribute);
- return Element.Methods.Simulated.hasAttribute(element, attribute);
-};
+if (document.documentElement.hasAttribute) {
+ Element.hasAttribute = function(element, attribute) {
+ return element.hasAttribute(attribute);
+ };
+}
+else {
+ Element.hasAttribute = Element.Methods.Simulated.hasAttribute;
+}
Element.addMethods = function(methods) {
var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
@@ -2665,14 +3129,19 @@ Element.addMethods = function(methods) {
klass = 'HTML' + tagName.capitalize() + 'Element';
if (window[klass]) return window[klass];
- window[klass] = { };
- window[klass].prototype = document.createElement(tagName).__proto__;
- return window[klass];
+ var element = document.createElement(tagName),
+ proto = element['__proto__'] || element.constructor.prototype;
+
+ element = null;
+ return proto;
}
+ var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
+ Element.prototype;
+
if (F.ElementExtensions) {
- copy(Element.Methods, HTMLElement.prototype);
- copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+ copy(Element.Methods, elementPrototype);
+ copy(Element.Methods.Simulated, elementPrototype, true);
}
if (F.SpecificElementExtensions) {
@@ -2690,697 +3159,1803 @@ Element.addMethods = function(methods) {
Element.cache = { };
};
-document.viewport = {
- getDimensions: function() {
- var dimensions = { };
- var B = Prototype.Browser;
- $w('width height').each(function(d) {
- var D = d.capitalize();
- dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
- (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
- });
- return dimensions;
- },
- getWidth: function() {
- return this.getDimensions().width;
- },
+document.viewport = {
- getHeight: function() {
- return this.getDimensions().height;
+ getDimensions: function() {
+ return { width: this.getWidth(), height: this.getHeight() };
},
getScrollOffsets: function() {
return Element._returnOffset(
window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
- window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
+ window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
}
};
-/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
- * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
- * license. Please see http://www.yui-ext.com/ for more information. */
-var Selector = Class.create({
- initialize: function(expression) {
- this.expression = expression.strip();
- this.compileMatcher();
- },
+(function(viewport) {
+ var B = Prototype.Browser, doc = document, element, property = {};
- shouldUseXPath: function() {
- if (!Prototype.BrowserFeatures.XPath) return false;
+ function getRootElement() {
+ if (B.WebKit && !doc.evaluate)
+ return document;
- var e = this.expression;
+ if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
+ return document.body;
- // Safari 3 chokes on :*-of-type and :empty
- if (Prototype.Browser.WebKit &&
- (e.include("-of-type") || e.include(":empty")))
- return false;
+ return document.documentElement;
+ }
- // XPath can't do namespaced attributes, nor can it read
- // the "checked" property from DOM nodes
- if ((/(\[[\w-]*?:|:checked)/).test(this.expression))
- return false;
+ function define(D) {
+ if (!element) element = getRootElement();
- return true;
- },
+ property[D] = 'client' + D;
- compileMatcher: function() {
- if (this.shouldUseXPath())
- return this.compileXPathMatcher();
+ viewport['get' + D] = function() { return element[property[D]] };
+ return viewport['get' + D]();
+ }
- var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
- c = Selector.criteria, le, p, m;
+ viewport.getWidth = define.curry('Width');
- if (Selector._cache[e]) {
- this.matcher = Selector._cache[e];
- return;
- }
+ viewport.getHeight = define.curry('Height');
+})(document.viewport);
- this.matcher = ["this.matcher = function(root) {",
- "var r = root, h = Selector.handlers, c = false, n;"];
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in ps) {
- p = ps[i];
- if (m = e.match(p)) {
- this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
- new Template(c[i]).evaluate(m));
- e = e.replace(m[0], '');
- break;
- }
- }
+Element.Storage = {
+ UID: 1
+};
+
+Element.addMethods({
+ getStorage: function(element) {
+ if (!(element = $(element))) return;
+
+ var uid;
+ if (element === window) {
+ uid = 0;
+ } else {
+ if (typeof element._prototypeUID === "undefined")
+ element._prototypeUID = Element.Storage.UID++;
+ uid = element._prototypeUID;
}
- this.matcher.push("return h.unique(n);\n}");
- eval(this.matcher.join('\n'));
- Selector._cache[this.expression] = this.matcher;
+ if (!Element.Storage[uid])
+ Element.Storage[uid] = $H();
+
+ return Element.Storage[uid];
},
- compileXPathMatcher: function() {
- var e = this.expression, ps = Selector.patterns,
- x = Selector.xpath, le, m;
+ store: function(element, key, value) {
+ if (!(element = $(element))) return;
- if (Selector._cache[e]) {
- this.xpath = Selector._cache[e]; return;
+ if (arguments.length === 2) {
+ Element.getStorage(element).update(key);
+ } else {
+ Element.getStorage(element).set(key, value);
}
- this.matcher = ['.//*'];
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in ps) {
- if (m = e.match(ps[i])) {
- this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
- new Template(x[i]).evaluate(m));
- e = e.replace(m[0], '');
- break;
- }
- }
+ return element;
+ },
+
+ retrieve: function(element, key, defaultValue) {
+ if (!(element = $(element))) return;
+ var hash = Element.getStorage(element), value = hash.get(key);
+
+ if (Object.isUndefined(value)) {
+ hash.set(key, defaultValue);
+ value = defaultValue;
}
- this.xpath = this.matcher.join('');
- Selector._cache[this.expression] = this.xpath;
+ return value;
},
- findElements: function(root) {
- root = root || document;
- if (this.xpath) return document._getElementsByXPath(this.xpath, root);
- return this.matcher(root);
+ clone: function(element, deep) {
+ if (!(element = $(element))) return;
+ var clone = element.cloneNode(deep);
+ clone._prototypeUID = void 0;
+ if (deep) {
+ var descendants = Element.select(clone, '*'),
+ i = descendants.length;
+ while (i--) {
+ descendants[i]._prototypeUID = void 0;
+ }
+ }
+ return Element.extend(clone);
},
- match: function(element) {
- this.tokens = [];
+ purge: function(element) {
+ if (!(element = $(element))) return;
+ purgeElement(element);
- var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
- var le, p, m;
+ var descendants = element.getElementsByTagName('*'),
+ i = descendants.length;
- while (e && le !== e && (/\S/).test(e)) {
- le = e;
- for (var i in ps) {
- p = ps[i];
- if (m = e.match(p)) {
- // use the Selector.assertions methods unless the selector
- // is too complex.
- if (as[i]) {
- this.tokens.push([i, Object.clone(m)]);
- e = e.replace(m[0], '');
- } else {
- // reluctantly do a document-wide search
- // and look for a match in the array
- return this.findElements(document).include(element);
- }
- }
- }
+ while (i--) purgeElement(descendants[i]);
+
+ return null;
+ }
+});
+
+(function() {
+
+ function toDecimal(pctString) {
+ var match = pctString.match(/^(\d+)%?$/i);
+ if (!match) return null;
+ return (Number(match[1]) / 100);
+ }
+
+ function getPixelValue(value, property) {
+ if (Object.isElement(value)) {
+ element = value;
+ value = element.getStyle(property);
+ }
+ if (value === null) {
+ return null;
+ }
+
+ if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
+ return window.parseFloat(value);
}
- var match = true, name, matches;
- for (var i = 0, token; token = this.tokens[i]; i++) {
- name = token[0], matches = token[1];
- if (!Selector.assertions[name](element, matches)) {
- match = false; break;
+ if (/\d/.test(value) && element.runtimeStyle) {
+ var style = element.style.left, rStyle = element.runtimeStyle.left;
+ element.runtimeStyle.left = element.currentStyle.left;
+ element.style.left = value || 0;
+ value = element.style.pixelLeft;
+ element.style.left = style;
+ element.runtimeStyle.left = rStyle;
+
+ return value;
+ }
+
+ if (value.include('%')) {
+ var decimal = toDecimal(value);
+ var whole;
+ if (property.include('left') || property.include('right') ||
+ property.include('width')) {
+ whole = $(element.parentNode).measure('width');
+ } else if (property.include('top') || property.include('bottom') ||
+ property.include('height')) {
+ whole = $(element.parentNode).measure('height');
}
+
+ return whole * decimal;
}
- return match;
- },
+ return 0;
+ }
- toString: function() {
- return this.expression;
- },
+ function toCSSPixels(number) {
+ if (Object.isString(number) && number.endsWith('px')) {
+ return number;
+ }
+ return number + 'px';
+ }
- inspect: function() {
- return "#<Selector:" + this.expression.inspect() + ">";
+ function isDisplayed(element) {
+ var originalElement = element;
+ while (element && element.parentNode) {
+ var display = element.getStyle('display');
+ if (display === 'none') {
+ return false;
+ }
+ element = $(element.parentNode);
+ }
+ return true;
}
-});
-Object.extend(Selector, {
- _cache: { },
-
- xpath: {
- descendant: "//*",
- child: "/*",
- adjacent: "/following-sibling::*[1]",
- laterSibling: '/following-sibling::*',
- tagName: function(m) {
- if (m[1] == '*') return '';
- return "[local-name()='" + m[1].toLowerCase() +
- "' or local-name()='" + m[1].toUpperCase() + "']";
+ var hasLayout = Prototype.K;
+ if ('currentStyle' in document.documentElement) {
+ hasLayout = function(element) {
+ if (!element.currentStyle.hasLayout) {
+ element.style.zoom = 1;
+ }
+ return element;
+ };
+ }
+
+ function cssNameFor(key) {
+ if (key.include('border')) key = key + '-width';
+ return key.camelize();
+ }
+
+ Element.Layout = Class.create(Hash, {
+ initialize: function($super, element, preCompute) {
+ $super();
+ this.element = $(element);
+
+ Element.Layout.PROPERTIES.each( function(property) {
+ this._set(property, null);
+ }, this);
+
+ if (preCompute) {
+ this._preComputing = true;
+ this._begin();
+ Element.Layout.PROPERTIES.each( this._compute, this );
+ this._end();
+ this._preComputing = false;
+ }
+ },
+
+ _set: function(property, value) {
+ return Hash.prototype.set.call(this, property, value);
+ },
+
+ set: function(property, value) {
+ throw "Properties of Element.Layout are read-only.";
+ },
+
+ get: function($super, property) {
+ var value = $super(property);
+ return value === null ? this._compute(property) : value;
+ },
+
+ _begin: function() {
+ if (this._prepared) return;
+
+ var element = this.element;
+ if (isDisplayed(element)) {
+ this._prepared = true;
+ return;
+ }
+
+ var originalStyles = {
+ position: element.style.position || '',
+ width: element.style.width || '',
+ visibility: element.style.visibility || '',
+ display: element.style.display || ''
+ };
+
+ element.store('prototype_original_styles', originalStyles);
+
+ var position = element.getStyle('position'),
+ width = element.getStyle('width');
+
+ element.setStyle({
+ position: 'absolute',
+ visibility: 'hidden',
+ display: 'block'
+ });
+
+ var positionedWidth = element.getStyle('width');
+
+ var newWidth;
+ if (width && (positionedWidth === width)) {
+ newWidth = getPixelValue(width);
+ } else if (width && (position === 'absolute' || position === 'fixed')) {
+ newWidth = getPixelValue(width);
+ } else {
+ var parent = element.parentNode, pLayout = $(parent).getLayout();
+
+ newWidth = pLayout.get('width') -
+ this.get('margin-left') -
+ this.get('border-left') -
+ this.get('padding-left') -
+ this.get('padding-right') -
+ this.get('border-right') -
+ this.get('margin-right');
+ }
+
+ element.setStyle({ width: newWidth + 'px' });
+
+ this._prepared = true;
},
- className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
- id: "[@id='#{1}']",
- attrPresence: function(m) {
- m[1] = m[1].toLowerCase();
- return new Template("[@#{1}]").evaluate(m);
+
+ _end: function() {
+ var element = this.element;
+ var originalStyles = element.retrieve('prototype_original_styles');
+ element.store('prototype_original_styles', null);
+ element.setStyle(originalStyles);
+ this._prepared = false;
},
- attr: function(m) {
- m[1] = m[1].toLowerCase();
- m[3] = m[5] || m[6];
- return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
+
+ _compute: function(property) {
+ var COMPUTATIONS = Element.Layout.COMPUTATIONS;
+ if (!(property in COMPUTATIONS)) {
+ throw "Property not found.";
+ }
+ return this._set(property, COMPUTATIONS[property].call(this, this.element));
},
- pseudo: function(m) {
- var h = Selector.xpath.pseudos[m[1]];
- if (!h) return '';
- if (Object.isFunction(h)) return h(m);
- return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
+
+ toObject: function() {
+ var args = $A(arguments);
+ var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
+ args.join(' ').split(' ');
+ var obj = {};
+ keys.each( function(key) {
+ if (!Element.Layout.PROPERTIES.include(key)) return;
+ var value = this.get(key);
+ if (value != null) obj[key] = value;
+ }, this);
+ return obj;
},
- operators: {
- '=': "[@#{1}='#{3}']",
- '!=': "[@#{1}!='#{3}']",
- '^=': "[starts-with(@#{1}, '#{3}')]",
- '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
- '*=': "[contains(@#{1}, '#{3}')]",
- '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
- '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
+
+ toHash: function() {
+ var obj = this.toObject.apply(this, arguments);
+ return new Hash(obj);
},
- pseudos: {
- 'first-child': '[not(preceding-sibling::*)]',
- 'last-child': '[not(following-sibling::*)]',
- 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
- 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
- 'checked': "[@checked]",
- 'disabled': "[@disabled]",
- 'enabled': "[not(@disabled)]",
- 'not': function(m) {
- var e = m[6], p = Selector.patterns,
- x = Selector.xpath, le, v;
-
- var exclusion = [];
- while (e && le != e && (/\S/).test(e)) {
- le = e;
- for (var i in p) {
- if (m = e.match(p[i])) {
- v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
- exclusion.push("(" + v.substring(1, v.length - 1) + ")");
- e = e.replace(m[0], '');
- break;
- }
- }
- }
- return "[not(" + exclusion.join(" and ") + ")]";
+
+ toCSS: function() {
+ var args = $A(arguments);
+ var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
+ args.join(' ').split(' ');
+ var css = {};
+
+ keys.each( function(key) {
+ if (!Element.Layout.PROPERTIES.include(key)) return;
+ if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
+
+ var value = this.get(key);
+ if (value != null) css[cssNameFor(key)] = value + 'px';
+ }, this);
+ return css;
+ },
+
+ inspect: function() {
+ return "#<Element.Layout>";
+ }
+ });
+
+ Object.extend(Element.Layout, {
+ PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
+
+ COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
+
+ COMPUTATIONS: {
+ 'height': function(element) {
+ if (!this._preComputing) this._begin();
+
+ var bHeight = this.get('border-box-height');
+ if (bHeight <= 0) return 0;
+
+ var bTop = this.get('border-top'),
+ bBottom = this.get('border-bottom');
+
+ var pTop = this.get('padding-top'),
+ pBottom = this.get('padding-bottom');
+
+ if (!this._preComputing) this._end();
+
+ return bHeight - bTop - bBottom - pTop - pBottom;
},
- 'nth-child': function(m) {
- return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
+
+ 'width': function(element) {
+ if (!this._preComputing) this._begin();
+
+ var bWidth = this.get('border-box-width');
+ if (bWidth <= 0) return 0;
+
+ var bLeft = this.get('border-left'),
+ bRight = this.get('border-right');
+
+ var pLeft = this.get('padding-left'),
+ pRight = this.get('padding-right');
+
+ if (!this._preComputing) this._end();
+
+ return bWidth - bLeft - bRight - pLeft - pRight;
},
- 'nth-last-child': function(m) {
- return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
+
+ 'padding-box-height': function(element) {
+ var height = this.get('height'),
+ pTop = this.get('padding-top'),
+ pBottom = this.get('padding-bottom');
+
+ return height + pTop + pBottom;
},
- 'nth-of-type': function(m) {
- return Selector.xpath.pseudos.nth("position() ", m);
+
+ 'padding-box-width': function(element) {
+ var width = this.get('width'),
+ pLeft = this.get('padding-left'),
+ pRight = this.get('padding-right');
+
+ return width + pLeft + pRight;
},
- 'nth-last-of-type': function(m) {
- return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
+
+ 'border-box-height': function(element) {
+ return element.offsetHeight;
},
- 'first-of-type': function(m) {
- m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
+
+ 'border-box-width': function(element) {
+ return element.offsetWidth;
},
- 'last-of-type': function(m) {
- m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
+
+ 'margin-box-height': function(element) {
+ var bHeight = this.get('border-box-height'),
+ mTop = this.get('margin-top'),
+ mBottom = this.get('margin-bottom');
+
+ if (bHeight <= 0) return 0;
+
+ return bHeight + mTop + mBottom;
},
- 'only-of-type': function(m) {
- var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
+
+ 'margin-box-width': function(element) {
+ var bWidth = this.get('border-box-width'),
+ mLeft = this.get('margin-left'),
+ mRight = this.get('margin-right');
+
+ if (bWidth <= 0) return 0;
+
+ return bWidth + mLeft + mRight;
},
- nth: function(fragment, m) {
- var mm, formula = m[6], predicate;
- if (formula == 'even') formula = '2n+0';
- if (formula == 'odd') formula = '2n+1';
- if (mm = formula.match(/^(\d+)$/)) // digit only
- return '[' + fragment + "= " + mm[1] + ']';
- if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
- if (mm[1] == "-") mm[1] = -1;
- var a = mm[1] ? Number(mm[1]) : 1;
- var b = mm[2] ? Number(mm[2]) : 0;
- predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
- "((#{fragment} - #{b}) div #{a} >= 0)]";
- return new Template(predicate).evaluate({
- fragment: fragment, a: a, b: b });
- }
+
+ 'top': function(element) {
+ var offset = element.positionedOffset();
+ return offset.top;
+ },
+
+ 'bottom': function(element) {
+ var offset = element.positionedOffset(),
+ parent = element.getOffsetParent(),
+ pHeight = parent.measure('height');
+
+ var mHeight = this.get('border-box-height');
+
+ return pHeight - mHeight - offset.top;
+ },
+
+ 'left': function(element) {
+ var offset = element.positionedOffset();
+ return offset.left;
+ },
+
+ 'right': function(element) {
+ var offset = element.positionedOffset(),
+ parent = element.getOffsetParent(),
+ pWidth = parent.measure('width');
+
+ var mWidth = this.get('border-box-width');
+
+ return pWidth - mWidth - offset.left;
+ },
+
+ 'padding-top': function(element) {
+ return getPixelValue(element, 'paddingTop');
+ },
+
+ 'padding-bottom': function(element) {
+ return getPixelValue(element, 'paddingBottom');
+ },
+
+ 'padding-left': function(element) {
+ return getPixelValue(element, 'paddingLeft');
+ },
+
+ 'padding-right': function(element) {
+ return getPixelValue(element, 'paddingRight');
+ },
+
+ 'border-top': function(element) {
+ return Object.isNumber(element.clientTop) ? element.clientTop :
+ getPixelValue(element, 'borderTopWidth');
+ },
+
+ 'border-bottom': function(element) {
+ return Object.isNumber(element.clientBottom) ? element.clientBottom :
+ getPixelValue(element, 'borderBottomWidth');
+ },
+
+ 'border-left': function(element) {
+ return Object.isNumber(element.clientLeft) ? element.clientLeft :
+ getPixelValue(element, 'borderLeftWidth');
+ },
+
+ 'border-right': function(element) {
+ return Object.isNumber(element.clientRight) ? element.clientRight :
+ getPixelValue(element, 'borderRightWidth');
+ },
+
+ 'margin-top': function(element) {
+ return getPixelValue(element, 'marginTop');
+ },
+
+ 'margin-bottom': function(element) {
+ return getPixelValue(element, 'marginBottom');
+ },
+
+ 'margin-left': function(element) {
+ return getPixelValue(element, 'marginLeft');
+ },
+
+ 'margin-right': function(element) {
+ return getPixelValue(element, 'marginRight');
}
}
- },
+ });
- criteria: {
- tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
- className: 'n = h.className(n, r, "#{1}", c); c = false;',
- id: 'n = h.id(n, r, "#{1}", c); c = false;',
- attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
- attr: function(m) {
- m[3] = (m[5] || m[6]);
- return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
- },
- pseudo: function(m) {
- if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
- return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
- },
- descendant: 'c = "descendant";',
- child: 'c = "child";',
- adjacent: 'c = "adjacent";',
- laterSibling: 'c = "laterSibling";'
- },
-
- patterns: {
- // combinators must be listed first
- // (and descendant needs to be last combinator)
- laterSibling: /^\s*~\s*/,
- child: /^\s*>\s*/,
- adjacent: /^\s*\+\s*/,
- descendant: /^\s/,
-
- // selectors follow
- tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
- id: /^#([\w\-\*]+)(\b|$)/,
- className: /^\.([\w\-\*]+)(\b|$)/,
- pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/,
- attrPresence: /^\[([\w]+)\]/,
- attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
- },
-
- // for Selector.match and Element#match
- assertions: {
- tagName: function(element, matches) {
- return matches[1].toUpperCase() == element.tagName.toUpperCase();
+ if ('getBoundingClientRect' in document.documentElement) {
+ Object.extend(Element.Layout.COMPUTATIONS, {
+ 'right': function(element) {
+ var parent = hasLayout(element.getOffsetParent());
+ var rect = element.getBoundingClientRect(),
+ pRect = parent.getBoundingClientRect();
+
+ return (pRect.right - rect.right).round();
+ },
+
+ 'bottom': function(element) {
+ var parent = hasLayout(element.getOffsetParent());
+ var rect = element.getBoundingClientRect(),
+ pRect = parent.getBoundingClientRect();
+
+ return (pRect.bottom - rect.bottom).round();
+ }
+ });
+ }
+
+ Element.Offset = Class.create({
+ initialize: function(left, top) {
+ this.left = left.round();
+ this.top = top.round();
+
+ this[0] = this.left;
+ this[1] = this.top;
},
- className: function(element, matches) {
- return Element.hasClassName(element, matches[1]);
+ relativeTo: function(offset) {
+ return new Element.Offset(
+ this.left - offset.left,
+ this.top - offset.top
+ );
},
- id: function(element, matches) {
- return element.id === matches[1];
+ inspect: function() {
+ return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
},
- attrPresence: function(element, matches) {
- return Element.hasAttribute(element, matches[1]);
+ toString: function() {
+ return "[#{left}, #{top}]".interpolate(this);
},
- attr: function(element, matches) {
- var nodeValue = Element.readAttribute(element, matches[1]);
- return Selector.operators[matches[2]](nodeValue, matches[3]);
+ toArray: function() {
+ return [this.left, this.top];
}
- },
+ });
- handlers: {
- // UTILITY FUNCTIONS
- // joins two collections
- concat: function(a, b) {
- for (var i = 0, node; node = b[i]; i++)
- a.push(node);
- return a;
- },
+ function getLayout(element, preCompute) {
+ return new Element.Layout(element, preCompute);
+ }
- // marks an array of nodes for counting
- mark: function(nodes) {
- for (var i = 0, node; node = nodes[i]; i++)
- node._counted = true;
- return nodes;
- },
+ function measure(element, property) {
+ return $(element).getLayout().get(property);
+ }
- unmark: function(nodes) {
- for (var i = 0, node; node = nodes[i]; i++)
- node._counted = undefined;
- return nodes;
- },
+ function getDimensions(element) {
+ var layout = $(element).getLayout();
+ return {
+ width: layout.get('width'),
+ height: layout.get('height')
+ };
+ }
- // mark each child node with its position (for nth calls)
- // "ofType" flag indicates whether we're indexing for nth-of-type
- // rather than nth-child
- index: function(parentNode, reverse, ofType) {
- parentNode._counted = true;
- if (reverse) {
- for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
- var node = nodes[i];
- if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
- }
- } else {
- for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
- if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+ function getOffsetParent(element) {
+ if (isDetached(element)) return $(document.body);
+
+ var isInline = (Element.getStyle(element, 'display') === 'inline');
+ if (!isInline && element.offsetParent) return $(element.offsetParent);
+ if (element === document.body) return $(element);
+
+ while ((element = element.parentNode) && element !== document.body) {
+ if (Element.getStyle(element, 'position') !== 'static') {
+ return (element.nodeName === 'HTML') ? $(document.body) : $(element);
}
- },
+ }
- // filters out duplicates and extends all nodes
- unique: function(nodes) {
- if (nodes.length == 0) return nodes;
- var results = [], n;
- for (var i = 0, l = nodes.length; i < l; i++)
- if (!(n = nodes[i])._counted) {
- n._counted = true;
- results.push(Element.extend(n));
- }
- return Selector.handlers.unmark(results);
- },
+ return $(document.body);
+ }
- // COMBINATOR FUNCTIONS
- descendant: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- h.concat(results, node.getElementsByTagName('*'));
- return results;
- },
- child: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- for (var j = 0, child; child = node.childNodes[j]; j++)
- if (child.nodeType == 1 && child.tagName != '!') results.push(child);
- }
- return results;
- },
+ function cumulativeOffset(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+ return new Element.Offset(valueL, valueT);
+ }
+
+ function positionedOffset(element) {
+ var layout = element.getLayout();
- adjacent: function(nodes) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- var next = this.nextElementSibling(node);
- if (next) results.push(next);
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ if (element) {
+ if (isBody(element)) break;
+ var p = Element.getStyle(element, 'position');
+ if (p !== 'static') break;
}
- return results;
- },
+ } while (element);
- laterSibling: function(nodes) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- h.concat(results, Element.nextSiblings(node));
- return results;
- },
+ valueL -= layout.get('margin-top');
+ valueT -= layout.get('margin-left');
- nextElementSibling: function(node) {
- while (node = node.nextSibling)
- if (node.nodeType == 1) return node;
- return null;
- },
+ return new Element.Offset(valueL, valueT);
+ }
- previousElementSibling: function(node) {
- while (node = node.previousSibling)
- if (node.nodeType == 1) return node;
- return null;
- },
+ function cumulativeScrollOffset(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.scrollTop || 0;
+ valueL += element.scrollLeft || 0;
+ element = element.parentNode;
+ } while (element);
+ return new Element.Offset(valueL, valueT);
+ }
- // TOKEN FUNCTIONS
- tagName: function(nodes, root, tagName, combinator) {
- tagName = tagName.toUpperCase();
- var results = [], h = Selector.handlers;
- if (nodes) {
- if (combinator) {
- // fastlane for ordinary descendant combinators
- if (combinator == "descendant") {
- for (var i = 0, node; node = nodes[i]; i++)
- h.concat(results, node.getElementsByTagName(tagName));
- return results;
- } else nodes = this[combinator](nodes);
- if (tagName == "*") return nodes;
- }
- for (var i = 0, node; node = nodes[i]; i++)
- if (node.tagName.toUpperCase() == tagName) results.push(node);
- return results;
- } else return root.getElementsByTagName(tagName);
- },
+ function viewportOffset(forElement) {
+ var valueT = 0, valueL = 0, docBody = document.body;
- id: function(nodes, root, id, combinator) {
- var targetNode = $(id), h = Selector.handlers;
- if (!targetNode) return [];
- if (!nodes && root == document) return [targetNode];
- if (nodes) {
- if (combinator) {
- if (combinator == 'child') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (targetNode.parentNode == node) return [targetNode];
- } else if (combinator == 'descendant') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (Element.descendantOf(targetNode, node)) return [targetNode];
- } else if (combinator == 'adjacent') {
- for (var i = 0, node; node = nodes[i]; i++)
- if (Selector.handlers.previousElementSibling(targetNode) == node)
- return [targetNode];
- } else nodes = h[combinator](nodes);
- }
- for (var i = 0, node; node = nodes[i]; i++)
- if (node == targetNode) return [targetNode];
- return [];
+ var element = forElement;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ if (element.offsetParent == docBody &&
+ Element.getStyle(element, 'position') == 'absolute') break;
+ } while (element = element.offsetParent);
+
+ element = forElement;
+ do {
+ if (element != docBody) {
+ valueT -= element.scrollTop || 0;
+ valueL -= element.scrollLeft || 0;
}
- return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
- },
+ } while (element = element.parentNode);
+ return new Element.Offset(valueL, valueT);
+ }
- className: function(nodes, root, className, combinator) {
- if (nodes && combinator) nodes = this[combinator](nodes);
- return Selector.handlers.byClassName(nodes, root, className);
- },
+ function absolutize(element) {
+ element = $(element);
- byClassName: function(nodes, root, className) {
- if (!nodes) nodes = Selector.handlers.descendant([root]);
- var needle = ' ' + className + ' ';
- for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
- nodeClassName = node.className;
- if (nodeClassName.length == 0) continue;
- if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
- results.push(node);
- }
- return results;
- },
+ if (Element.getStyle(element, 'position') === 'absolute') {
+ return element;
+ }
- attrPresence: function(nodes, root, attr) {
- if (!nodes) nodes = root.getElementsByTagName("*");
- var results = [];
- for (var i = 0, node; node = nodes[i]; i++)
- if (Element.hasAttribute(node, attr)) results.push(node);
- return results;
- },
+ var offsetParent = getOffsetParent(element);
+ var eOffset = element.viewportOffset(),
+ pOffset = offsetParent.viewportOffset();
- attr: function(nodes, root, attr, value, operator) {
- if (!nodes) nodes = root.getElementsByTagName("*");
- var handler = Selector.operators[operator], results = [];
- for (var i = 0, node; node = nodes[i]; i++) {
- var nodeValue = Element.readAttribute(node, attr);
- if (nodeValue === null) continue;
- if (handler(nodeValue, value)) results.push(node);
- }
- return results;
- },
+ var offset = eOffset.relativeTo(pOffset);
+ var layout = element.getLayout();
- pseudo: function(nodes, name, value, root, combinator) {
- if (nodes && combinator) nodes = this[combinator](nodes);
- if (!nodes) nodes = root.getElementsByTagName("*");
- return Selector.pseudos[name](nodes, value, root);
+ element.store('prototype_absolutize_original_styles', {
+ left: element.getStyle('left'),
+ top: element.getStyle('top'),
+ width: element.getStyle('width'),
+ height: element.getStyle('height')
+ });
+
+ element.setStyle({
+ position: 'absolute',
+ top: offset.top + 'px',
+ left: offset.left + 'px',
+ width: layout.get('width') + 'px',
+ height: layout.get('height') + 'px'
+ });
+
+ return element;
+ }
+
+ function relativize(element) {
+ element = $(element);
+ if (Element.getStyle(element, 'position') === 'relative') {
+ return element;
}
- },
- pseudos: {
- 'first-child': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- if (Selector.handlers.previousElementSibling(node)) continue;
- results.push(node);
- }
- return results;
- },
- 'last-child': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- if (Selector.handlers.nextElementSibling(node)) continue;
- results.push(node);
- }
- return results;
- },
- 'only-child': function(nodes, value, root) {
- var h = Selector.handlers;
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
- results.push(node);
- return results;
- },
- 'nth-child': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root);
- },
- 'nth-last-child': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, true);
- },
- 'nth-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, false, true);
- },
- 'nth-last-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, formula, root, true, true);
- },
- 'first-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, "1", root, false, true);
- },
- 'last-of-type': function(nodes, formula, root) {
- return Selector.pseudos.nth(nodes, "1", root, true, true);
- },
- 'only-of-type': function(nodes, formula, root) {
- var p = Selector.pseudos;
- return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
- },
+ var originalStyles =
+ element.retrieve('prototype_absolutize_original_styles');
- // handles the an+b logic
- getIndices: function(a, b, total) {
- if (a == 0) return b > 0 ? [b] : [];
- return $R(1, total).inject([], function(memo, i) {
- if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
- return memo;
- });
- },
+ if (originalStyles) element.setStyle(originalStyles);
+ return element;
+ }
- // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
- nth: function(nodes, formula, root, reverse, ofType) {
- if (nodes.length == 0) return [];
- if (formula == 'even') formula = '2n+0';
- if (formula == 'odd') formula = '2n+1';
- var h = Selector.handlers, results = [], indexed = [], m;
- h.mark(nodes);
- for (var i = 0, node; node = nodes[i]; i++) {
- if (!node.parentNode._counted) {
- h.index(node.parentNode, reverse, ofType);
- indexed.push(node.parentNode);
- }
- }
- if (formula.match(/^\d+$/)) { // just a number
- formula = Number(formula);
- for (var i = 0, node; node = nodes[i]; i++)
- if (node.nodeIndex == formula) results.push(node);
- } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
- if (m[1] == "-") m[1] = -1;
- var a = m[1] ? Number(m[1]) : 1;
- var b = m[2] ? Number(m[2]) : 0;
- var indices = Selector.pseudos.getIndices(a, b, nodes.length);
- for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
- for (var j = 0; j < l; j++)
- if (node.nodeIndex == indices[j]) results.push(node);
+ Element.addMethods({
+ getLayout: getLayout,
+ measure: measure,
+ getDimensions: getDimensions,
+ getOffsetParent: getOffsetParent,
+ cumulativeOffset: cumulativeOffset,
+ positionedOffset: positionedOffset,
+ cumulativeScrollOffset: cumulativeScrollOffset,
+ viewportOffset: viewportOffset,
+ absolutize: absolutize,
+ relativize: relativize
+ });
+
+ function isBody(element) {
+ return element.nodeName.toUpperCase() === 'BODY';
+ }
+
+ function isDetached(element) {
+ return element !== document.body &&
+ !Element.descendantOf(element, document.body);
+ }
+
+ if ('getBoundingClientRect' in document.documentElement) {
+ Element.addMethods({
+ viewportOffset: function(element) {
+ element = $(element);
+ if (isDetached(element)) return new Element.Offset(0, 0);
+
+ var rect = element.getBoundingClientRect(),
+ docEl = document.documentElement;
+ return new Element.Offset(rect.left - docEl.clientLeft,
+ rect.top - docEl.clientTop);
+ },
+
+ positionedOffset: function(element) {
+ element = $(element);
+ var parent = element.getOffsetParent();
+ if (isDetached(element)) return new Element.Offset(0, 0);
+
+ if (element.offsetParent &&
+ element.offsetParent.nodeName.toUpperCase() === 'HTML') {
+ return positionedOffset(element);
}
- }
- h.unmark(nodes);
- h.unmark(indexed);
- return results;
- },
- 'empty': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
- // IE treats comments as element nodes
- if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
- results.push(node);
- }
- return results;
- },
+ var eOffset = element.viewportOffset(),
+ pOffset = isBody(parent) ? viewportOffset(parent) :
+ parent.viewportOffset();
+ var retOffset = eOffset.relativeTo(pOffset);
- 'not': function(nodes, selector, root) {
- var h = Selector.handlers, selectorType, m;
- var exclusions = new Selector(selector).findElements(root);
- h.mark(exclusions);
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!node._counted) results.push(node);
- h.unmark(exclusions);
- return results;
- },
+ var layout = element.getLayout();
+ var top = retOffset.top - layout.get('margin-top');
+ var left = retOffset.left - layout.get('margin-left');
- 'enabled': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (!node.disabled) results.push(node);
- return results;
- },
+ return new Element.Offset(left, top);
+ }
+ });
+ }
+})();
+window.$$ = function() {
+ var expression = $A(arguments).join(', ');
+ return Prototype.Selector.select(expression, document);
+};
- 'disabled': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (node.disabled) results.push(node);
- return results;
- },
+Prototype.Selector = (function() {
- 'checked': function(nodes, value, root) {
- for (var i = 0, results = [], node; node = nodes[i]; i++)
- if (node.checked) results.push(node);
- return results;
- }
- },
+ function select() {
+ throw new Error('Method "Prototype.Selector.select" must be defined.');
+ }
- operators: {
- '=': function(nv, v) { return nv == v; },
- '!=': function(nv, v) { return nv != v; },
- '^=': function(nv, v) { return nv.startsWith(v); },
- '$=': function(nv, v) { return nv.endsWith(v); },
- '*=': function(nv, v) { return nv.include(v); },
- '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
- '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
- },
+ function match() {
+ throw new Error('Method "Prototype.Selector.match" must be defined.');
+ }
- matchElements: function(elements, expression) {
- var matches = new Selector(expression).findElements(), h = Selector.handlers;
- h.mark(matches);
- for (var i = 0, results = [], element; element = elements[i]; i++)
- if (element._counted) results.push(element);
- h.unmark(matches);
- return results;
- },
+ function find(elements, expression, index) {
+ index = index || 0;
+ var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
- findElement: function(elements, expression, index) {
- if (Object.isNumber(expression)) {
- index = expression; expression = false;
+ for (i = 0; i < length; i++) {
+ if (match(elements[i], expression) && index == matchIndex++) {
+ return Element.extend(elements[i]);
+ }
}
- return Selector.matchElements(elements, expression || '*')[index || 0];
- },
+ }
- findChildElements: function(element, expressions) {
- var exprs = expressions.join(',');
- expressions = [];
- exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
- expressions.push(m[1].strip());
- });
- var results = [], h = Selector.handlers;
- for (var i = 0, l = expressions.length, selector; i < l; i++) {
- selector = new Selector(expressions[i].strip());
- h.concat(results, selector.findElements(element));
+ function extendElements(elements) {
+ for (var i = 0, length = elements.length; i < length; i++) {
+ Element.extend(elements[i]);
}
- return (l > 1) ? h.unique(results) : results;
+ return elements;
}
-});
-if (Prototype.Browser.IE) {
- // IE returns comment nodes on getElementsByTagName("*").
- // Filter them out.
- Selector.handlers.concat = function(a, b) {
- for (var i = 0, node; node = b[i]; i++)
- if (node.tagName !== "!") a.push(node);
- return a;
+
+ var K = Prototype.K;
+
+ return {
+ select: select,
+ match: match,
+ find: find,
+ extendElements: (Element.extend === K) ? K : extendElements,
+ extendElement: Element.extend
};
+})();
+Prototype._original_property = window.Sizzle;
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true;
+
+[0, 0].sort(function(){
+ baseHasDuplicate = false;
+ return 0;
+});
+
+var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ var origContext = context = context || document;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
+ soFar = selector;
+
+ while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] )
+ selector += parts.shift();
+
+ set = posProcess( selector, set );
+ }
+ }
+ } else {
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+ var ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+ }
+
+ if ( context ) {
+ var ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+ set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray(set);
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ var cur = parts.pop(), pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ throw "Syntax error, unrecognized expression: " + (cur || selector);
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context && context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+};
+
+Sizzle.uniqueSort = function(results){
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort(sortOrder);
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[i-1] ) {
+ results.splice(i--, 1);
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function(expr, set){
+ return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+ var set, match;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var type = Expr.order[i], match;
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ var left = match[1];
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName("*");
+ }
+
+ return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+ var old = expr, result = [], curLoop = set, match, anyFound,
+ isXMLFilter = set && set[0] && isXML(set[0]);
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.match[ type ].exec( expr )) != null ) {
+ var filter = Expr.filter[ type ], found, item;
+ anyFound = false;
+
+ if ( curLoop == result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+ } else {
+ curLoop[i] = false;
+ }
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ if ( expr == old ) {
+ if ( anyFound == null ) {
+ throw "Syntax error, unrecognized expression: " + expr;
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
+ },
+ leftMatch: {},
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+ attrHandle: {
+ href: function(elem){
+ return elem.getAttribute("href");
+ }
+ },
+ relative: {
+ "+": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !/\W/.test(part),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag && !isXML ) {
+ part = part.toUpperCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+ ">": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string";
+
+ if ( isPartStr && !/\W/.test(part) ) {
+ part = isXML ? part : part.toUpperCase();
+
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName === part ? parent : false;
+ }
+ }
+ } else {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+ "": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( !/\W/.test(part) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+ },
+ "~": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+ }
+ },
+ find: {
+ ID: function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? [m] : [];
+ }
+ },
+ NAME: function(match, context, isXML){
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [], results = context.getElementsByName(match[1]);
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+ TAG: function(match, context){
+ return context.getElementsByTagName(match[1]);
+ }
+ },
+ preFilter: {
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
+ if ( !inplace )
+ result.push( elem );
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+ ID: function(match){
+ return match[1].replace(/\\/g, "");
+ },
+ TAG: function(match, curLoop){
+ for ( var i = 0; curLoop[i] === false; i++ ){}
+ return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
+ },
+ CHILD: function(match){
+ if ( match[1] == "nth" ) {
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ match[0] = done++;
+
+ return match;
+ },
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
+ var name = match[1].replace(/\\/g, "");
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+ PSEUDO: function(match, curLoop, inplace, result, not){
+ if ( match[1] === "not" ) {
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+ return false;
+ }
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+ POS: function(match){
+ match.unshift( true );
+ return match;
+ }
+ },
+ filters: {
+ enabled: function(elem){
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+ disabled: function(elem){
+ return elem.disabled === true;
+ },
+ checked: function(elem){
+ return elem.checked === true;
+ },
+ selected: function(elem){
+ elem.parentNode.selectedIndex;
+ return elem.selected === true;
+ },
+ parent: function(elem){
+ return !!elem.firstChild;
+ },
+ empty: function(elem){
+ return !elem.firstChild;
+ },
+ has: function(elem, i, match){
+ return !!Sizzle( match[3], elem ).length;
+ },
+ header: function(elem){
+ return /h\d/i.test( elem.nodeName );
+ },
+ text: function(elem){
+ return "text" === elem.type;
+ },
+ radio: function(elem){
+ return "radio" === elem.type;
+ },
+ checkbox: function(elem){
+ return "checkbox" === elem.type;
+ },
+ file: function(elem){
+ return "file" === elem.type;
+ },
+ password: function(elem){
+ return "password" === elem.type;
+ },
+ submit: function(elem){
+ return "submit" === elem.type;
+ },
+ image: function(elem){
+ return "image" === elem.type;
+ },
+ reset: function(elem){
+ return "reset" === elem.type;
+ },
+ button: function(elem){
+ return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
+ },
+ input: function(elem){
+ return /input|select|textarea|button/i.test(elem.nodeName);
+ }
+ },
+ setFilters: {
+ first: function(elem, i){
+ return i === 0;
+ },
+ last: function(elem, i, match, array){
+ return i === array.length - 1;
+ },
+ even: function(elem, i){
+ return i % 2 === 0;
+ },
+ odd: function(elem, i){
+ return i % 2 === 1;
+ },
+ lt: function(elem, i, match){
+ return i < match[3] - 0;
+ },
+ gt: function(elem, i, match){
+ return i > match[3] - 0;
+ },
+ nth: function(elem, i, match){
+ return match[3] - 0 == i;
+ },
+ eq: function(elem, i, match){
+ return match[3] - 0 == i;
+ }
+ },
+ filter: {
+ PSEUDO: function(elem, match, i, array){
+ var name = match[1], filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var i = 0, l = not.length; i < l; i++ ) {
+ if ( not[i] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ },
+ CHILD: function(elem, match){
+ var type = match[1], node = elem;
+ switch (type) {
+ case 'only':
+ case 'first':
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ if ( type == 'first') return true;
+ node = elem;
+ case 'last':
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ return true;
+ case 'nth':
+ var first = match[2], last = match[3];
+
+ if ( first == 1 && last == 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+ if ( first == 0 ) {
+ return diff == 0;
+ } else {
+ return ( diff % first == 0 && diff / first >= 0 );
+ }
+ }
+ },
+ ID: function(elem, match){
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+ TAG: function(elem, match){
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
+ },
+ CLASS: function(elem, match){
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+ ATTR: function(elem, match){
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value != check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+ POS: function(elem, match, i, array){
+ var name = match[2], filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
+}
+
+var makeArray = function(array, results) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 );
+
+} catch(e){
+ makeArray = function(array, results) {
+ var ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+ } else {
+ for ( var i = 0; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ }
+
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( "sourceIndex" in document.documentElement ) {
+ sortOrder = function( a, b ) {
+ if ( !a.sourceIndex || !b.sourceIndex ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ }
+
+ var ret = a.sourceIndex - b.sourceIndex;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( document.createRange ) {
+ sortOrder = function( a, b ) {
+ if ( !a.ownerDocument || !b.ownerDocument ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ }
+
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+ aRange.setStart(a, 0);
+ aRange.setEnd(a, 0);
+ bRange.setStart(b, 0);
+ bRange.setEnd(b, 0);
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+}
+
+(function(){
+ var form = document.createElement("div"),
+ id = "script" + (new Date).getTime();
+ form.innerHTML = "<a name='" + id + "'/>";
+
+ var root = document.documentElement;
+ root.insertBefore( form, root.firstChild );
+
+ if ( !!document.getElementById( id ) ) {
+ Expr.find.ID = function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match){
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+ root = form = null; // release memory in IE
+})();
+
+(function(){
+
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function(match, context){
+ var results = context.getElementsByTagName(match[1]);
+
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ div.innerHTML = "<a href='#'></a>";
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+ Expr.attrHandle.href = function(elem){
+ return elem.getAttribute("href", 2);
+ };
+ }
+
+ div = null; // release memory in IE
+})();
+
+if ( document.querySelectorAll ) (function(){
+ var oldSizzle = Sizzle, div = document.createElement("div");
+ div.innerHTML = "<p class='TEST'></p>";
+
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed){
+ context = context || document;
+
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(e){}
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ div = null; // release memory in IE
+})();
+
+if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
+ var div = document.createElement("div");
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ if ( div.getElementsByClassName("e").length === 0 )
+ return;
+
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 )
+ return;
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context, isXML) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ div = null; // release memory in IE
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
}
-function $$() {
- return Selector.findChildElements(document, $A(arguments));
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+ return a.compareDocumentPosition(b) & 16;
+} : function(a, b){
+ return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+ !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
+};
+
+var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+
+window.Sizzle = Sizzle;
+
+})();
+
+;(function(engine) {
+ var extendElements = Prototype.Selector.extendElements;
+
+ function select(selector, scope) {
+ return extendElements(engine(selector, scope || document));
+ }
+
+ function match(element, selector) {
+ return engine.matches(selector, [element]).length == 1;
+ }
+
+ Prototype.Selector.engine = engine;
+ Prototype.Selector.select = select;
+ Prototype.Selector.match = match;
+})(Sizzle);
+
+window.Sizzle = Prototype._original_property;
+delete Prototype._original_property;
+
var Form = {
reset: function(form) {
- $(form).reset();
+ form = $(form);
+ form.reset();
return form;
},
@@ -3392,10 +4967,9 @@ var Form = {
var data = elements.inject({ }, function(result, element) {
if (!element.disabled && element.name) {
key = element.name; value = $(element).getValue();
- if (value != null && (element.type != 'submit' || (!submitted &&
+ if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
submit !== false && (!submit || key == submit) && (submitted = true)))) {
if (key in result) {
- // a key is already present; construct an array of values
if (!Object.isArray(result[key])) result[key] = [result[key]];
result[key].push(value);
}
@@ -3415,13 +4989,18 @@ Form.Methods = {
},
getElements: function(form) {
- return $A($(form).getElementsByTagName('*')).inject([],
- function(elements, child) {
- if (Form.Element.Serializers[child.tagName.toLowerCase()])
- elements.push(Element.extend(child));
- return elements;
- }
- );
+ var elements = $(form).getElementsByTagName('*'),
+ element,
+ arr = [ ],
+ serializers = Form.Element.Serializers;
+ for (var i = 0; element = elements[i]; i++) {
+ arr.push(element);
+ }
+ return arr.inject([], function(elements, child) {
+ if (serializers[child.tagName.toLowerCase()])
+ elements.push(Element.extend(child));
+ return elements;
+ })
},
getInputs: function(form, typeName, name) {
@@ -3461,7 +5040,7 @@ Form.Methods = {
}).sortBy(function(element) { return element.tabIndex }).first();
return firstByIndex ? firstByIndex : elements.find(function(element) {
- return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ return /^(?:input|select|textarea)$/i.test(element.tagName);
});
},
@@ -3492,6 +5071,7 @@ Form.Methods = {
/*--------------------------------------------------------------------------*/
+
Form.Element = {
focus: function(element) {
$(element).focus();
@@ -3505,6 +5085,7 @@ Form.Element = {
};
Form.Element.Methods = {
+
serialize: function(element) {
element = $(element);
if (!element.disabled && element.name) {
@@ -3545,7 +5126,7 @@ Form.Element.Methods = {
try {
element.focus();
if (element.select && (element.tagName.toLowerCase() != 'input' ||
- !['button', 'reset', 'submit'].include(element.type)))
+ !(/^(?:button|reset|submit)$/i.test(element.type))))
element.select();
} catch (e) { }
return element;
@@ -3553,7 +5134,6 @@ Form.Element.Methods = {
disable: function(element) {
element = $(element);
- element.blur();
element.disabled = true;
return element;
},
@@ -3568,6 +5148,7 @@ Form.Element.Methods = {
/*--------------------------------------------------------------------------*/
var Field = Form.Element;
+
var $F = Form.Element.Methods.getValue;
/*--------------------------------------------------------------------------*/
@@ -3593,22 +5174,22 @@ Form.Element.Serializers = {
else element.value = value;
},
- select: function(element, index) {
- if (Object.isUndefined(index))
+ select: function(element, value) {
+ if (Object.isUndefined(value))
return this[element.type == 'select-one' ?
'selectOne' : 'selectMany'](element);
else {
- var opt, value, single = !Object.isArray(index);
+ var opt, currentValue, single = !Object.isArray(value);
for (var i = 0, length = element.length; i < length; i++) {
opt = element.options[i];
- value = this.optionValue(opt);
+ currentValue = this.optionValue(opt);
if (single) {
- if (value == index) {
+ if (currentValue == value) {
opt.selected = true;
return;
}
}
- else opt.selected = index.include(value);
+ else opt.selected = value.include(currentValue);
}
}
},
@@ -3630,13 +5211,13 @@ Form.Element.Serializers = {
},
optionValue: function(opt) {
- // extend element because hasAttribute may not be native
return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
}
};
/*--------------------------------------------------------------------------*/
+
Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
initialize: function($super, element, frequency, callback) {
$super(callback, frequency);
@@ -3718,323 +5299,475 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
return Form.serialize(this.element);
}
});
-if (!window.Event) var Event = { };
-
-Object.extend(Event, {
- KEY_BACKSPACE: 8,
- KEY_TAB: 9,
- KEY_RETURN: 13,
- KEY_ESC: 27,
- KEY_LEFT: 37,
- KEY_UP: 38,
- KEY_RIGHT: 39,
- KEY_DOWN: 40,
- KEY_DELETE: 46,
- KEY_HOME: 36,
- KEY_END: 35,
- KEY_PAGEUP: 33,
- KEY_PAGEDOWN: 34,
- KEY_INSERT: 45,
-
- cache: { },
-
- relatedTarget: function(event) {
- var element;
- switch(event.type) {
- case 'mouseover': element = event.fromElement; break;
- case 'mouseout': element = event.toElement; break;
- default: return null;
- }
- return Element.extend(element);
- }
-});
+(function() {
-Event.Methods = (function() {
- var isButton;
+ var Event = {
+ KEY_BACKSPACE: 8,
+ KEY_TAB: 9,
+ KEY_RETURN: 13,
+ KEY_ESC: 27,
+ KEY_LEFT: 37,
+ KEY_UP: 38,
+ KEY_RIGHT: 39,
+ KEY_DOWN: 40,
+ KEY_DELETE: 46,
+ KEY_HOME: 36,
+ KEY_END: 35,
+ KEY_PAGEUP: 33,
+ KEY_PAGEDOWN: 34,
+ KEY_INSERT: 45,
+
+ cache: {}
+ };
+
+ var docEl = document.documentElement;
+ var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
+ && 'onmouseleave' in docEl;
+ var _isButton;
if (Prototype.Browser.IE) {
var buttonMap = { 0: 1, 1: 4, 2: 2 };
- isButton = function(event, code) {
- return event.button == buttonMap[code];
+ _isButton = function(event, code) {
+ return event.button === buttonMap[code];
};
-
} else if (Prototype.Browser.WebKit) {
- isButton = function(event, code) {
+ _isButton = function(event, code) {
switch (code) {
case 0: return event.which == 1 && !event.metaKey;
case 1: return event.which == 1 && event.metaKey;
default: return false;
}
};
-
} else {
- isButton = function(event, code) {
+ _isButton = function(event, code) {
return event.which ? (event.which === code + 1) : (event.button === code);
};
}
- return {
- isLeftClick: function(event) { return isButton(event, 0) },
- isMiddleClick: function(event) { return isButton(event, 1) },
- isRightClick: function(event) { return isButton(event, 2) },
+ function isLeftClick(event) { return _isButton(event, 0) }
- element: function(event) {
- var node = Event.extend(event).target;
- return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
- },
+ function isMiddleClick(event) { return _isButton(event, 1) }
- findElement: function(event, expression) {
- var element = Event.element(event);
- if (!expression) return element;
- var elements = [element].concat(element.ancestors());
- return Selector.findElement(elements, expression, 0);
- },
+ function isRightClick(event) { return _isButton(event, 2) }
- pointer: function(event) {
- return {
- x: event.pageX || (event.clientX +
- (document.documentElement.scrollLeft || document.body.scrollLeft)),
- y: event.pageY || (event.clientY +
- (document.documentElement.scrollTop || document.body.scrollTop))
- };
- },
+ function element(event) {
+ event = Event.extend(event);
+
+ var node = event.target, type = event.type,
+ currentTarget = event.currentTarget;
+
+ if (currentTarget && currentTarget.tagName) {
+ if (type === 'load' || type === 'error' ||
+ (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
+ && currentTarget.type === 'radio'))
+ node = currentTarget;
+ }
- pointerX: function(event) { return Event.pointer(event).x },
- pointerY: function(event) { return Event.pointer(event).y },
+ if (node.nodeType == Node.TEXT_NODE)
+ node = node.parentNode;
- stop: function(event) {
- Event.extend(event);
- event.preventDefault();
- event.stopPropagation();
- event.stopped = true;
+ return Element.extend(node);
+ }
+
+ function findElement(event, expression) {
+ var element = Event.element(event);
+ if (!expression) return element;
+ while (element) {
+ if (Object.isElement(element) && Prototype.Selector.match(element, expression)) {
+ return Element.extend(element);
+ }
+ element = element.parentNode;
}
+ }
+
+ function pointer(event) {
+ return { x: pointerX(event), y: pointerY(event) };
+ }
+
+ function pointerX(event) {
+ var docElement = document.documentElement,
+ body = document.body || { scrollLeft: 0 };
+
+ return event.pageX || (event.clientX +
+ (docElement.scrollLeft || body.scrollLeft) -
+ (docElement.clientLeft || 0));
+ }
+
+ function pointerY(event) {
+ var docElement = document.documentElement,
+ body = document.body || { scrollTop: 0 };
+
+ return event.pageY || (event.clientY +
+ (docElement.scrollTop || body.scrollTop) -
+ (docElement.clientTop || 0));
+ }
+
+
+ function stop(event) {
+ Event.extend(event);
+ event.preventDefault();
+ event.stopPropagation();
+
+ event.stopped = true;
+ }
+
+ Event.Methods = {
+ isLeftClick: isLeftClick,
+ isMiddleClick: isMiddleClick,
+ isRightClick: isRightClick,
+
+ element: element,
+ findElement: findElement,
+
+ pointer: pointer,
+ pointerX: pointerX,
+ pointerY: pointerY,
+
+ stop: stop
};
-})();
-Event.extend = (function() {
+
var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
m[name] = Event.Methods[name].methodize();
return m;
});
if (Prototype.Browser.IE) {
+ function _relatedTarget(event) {
+ var element;
+ switch (event.type) {
+ case 'mouseover': element = event.fromElement; break;
+ case 'mouseout': element = event.toElement; break;
+ default: return null;
+ }
+ return Element.extend(element);
+ }
+
Object.extend(methods, {
stopPropagation: function() { this.cancelBubble = true },
preventDefault: function() { this.returnValue = false },
- inspect: function() { return "[object Event]" }
+ inspect: function() { return '[object Event]' }
});
- return function(event) {
+ Event.extend = function(event, element) {
if (!event) return false;
if (event._extendedByPrototype) return event;
event._extendedByPrototype = Prototype.emptyFunction;
var pointer = Event.pointer(event);
+
Object.extend(event, {
- target: event.srcElement,
- relatedTarget: Event.relatedTarget(event),
+ target: event.srcElement || element,
+ relatedTarget: _relatedTarget(event),
pageX: pointer.x,
pageY: pointer.y
});
+
return Object.extend(event, methods);
};
-
} else {
- Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
+ Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
Object.extend(Event.prototype, methods);
- return Prototype.K;
+ Event.extend = Prototype.K;
}
-})();
-Object.extend(Event, (function() {
- var cache = Event.cache;
+ function _createResponder(element, eventName, handler) {
+ var registry = Element.retrieve(element, 'prototype_event_registry');
- function getEventID(element) {
- if (element._eventID) return element._eventID;
- arguments.callee.id = arguments.callee.id || 1;
- return element._eventID = ++arguments.callee.id;
- }
-
- function getDOMEventName(eventName) {
- if (eventName && eventName.include(':')) return "dataavailable";
- return eventName;
- }
+ if (Object.isUndefined(registry)) {
+ CACHE.push(element);
+ registry = Element.retrieve(element, 'prototype_event_registry', $H());
+ }
- function getCacheForID(id) {
- return cache[id] = cache[id] || { };
- }
+ var respondersForEvent = registry.get(eventName);
+ if (Object.isUndefined(respondersForEvent)) {
+ respondersForEvent = [];
+ registry.set(eventName, respondersForEvent);
+ }
- function getWrappersForEventName(id, eventName) {
- var c = getCacheForID(id);
- return c[eventName] = c[eventName] || [];
- }
+ if (respondersForEvent.pluck('handler').include(handler)) return false;
- function createWrapper(element, eventName, handler) {
- var id = getEventID(element);
- var c = getWrappersForEventName(id, eventName);
- if (c.pluck("handler").include(handler)) return false;
+ var responder;
+ if (eventName.include(":")) {
+ responder = function(event) {
+ if (Object.isUndefined(event.eventName))
+ return false;
- var wrapper = function(event) {
- if (!Event || !Event.extend ||
- (event.eventName && event.eventName != eventName))
+ if (event.eventName !== eventName)
return false;
- Event.extend(event);
- handler.call(element, event)
- };
+ Event.extend(event, element);
+ handler.call(element, event);
+ };
+ } else {
+ if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
+ (eventName === "mouseenter" || eventName === "mouseleave")) {
+ if (eventName === "mouseenter" || eventName === "mouseleave") {
+ responder = function(event) {
+ Event.extend(event, element);
+
+ var parent = event.relatedTarget;
+ while (parent && parent !== element) {
+ try { parent = parent.parentNode; }
+ catch(e) { parent = element; }
+ }
- wrapper.handler = handler;
- c.push(wrapper);
- return wrapper;
- }
+ if (parent === element) return;
- function findWrapper(id, eventName, handler) {
- var c = getWrappersForEventName(id, eventName);
- return c.find(function(wrapper) { return wrapper.handler == handler });
- }
+ handler.call(element, event);
+ };
+ }
+ } else {
+ responder = function(event) {
+ Event.extend(event, element);
+ handler.call(element, event);
+ };
+ }
+ }
- function destroyWrapper(id, eventName, handler) {
- var c = getCacheForID(id);
- if (!c[eventName]) return false;
- c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
+ responder.handler = handler;
+ respondersForEvent.push(responder);
+ return responder;
}
- function destroyCache() {
- for (var id in cache)
- for (var eventName in cache[id])
- cache[id][eventName] = null;
+ function _destroyCache() {
+ for (var i = 0, length = CACHE.length; i < length; i++) {
+ Event.stopObserving(CACHE[i]);
+ CACHE[i] = null;
+ }
}
- if (window.attachEvent) {
- window.attachEvent("onunload", destroyCache);
+ var CACHE = [];
+
+ if (Prototype.Browser.IE)
+ window.attachEvent('onunload', _destroyCache);
+
+ if (Prototype.Browser.WebKit)
+ window.addEventListener('unload', Prototype.emptyFunction, false);
+
+
+ var _getDOMEventName = Prototype.K,
+ translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
+
+ if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
+ _getDOMEventName = function(eventName) {
+ return (translations[eventName] || eventName);
+ };
}
- return {
- observe: function(element, eventName, handler) {
- element = $(element);
- var name = getDOMEventName(eventName);
+ function observe(element, eventName, handler) {
+ element = $(element);
- var wrapper = createWrapper(element, eventName, handler);
- if (!wrapper) return element;
+ var responder = _createResponder(element, eventName, handler);
- if (element.addEventListener) {
- element.addEventListener(name, wrapper, false);
- } else {
- element.attachEvent("on" + name, wrapper);
+ if (!responder) return element;
+
+ if (eventName.include(':')) {
+ if (element.addEventListener)
+ element.addEventListener("dataavailable", responder, false);
+ else {
+ element.attachEvent("ondataavailable", responder);
+ element.attachEvent("onfilterchange", responder);
}
+ } else {
+ var actualEventName = _getDOMEventName(eventName);
+
+ if (element.addEventListener)
+ element.addEventListener(actualEventName, responder, false);
+ else
+ element.attachEvent("on" + actualEventName, responder);
+ }
+
+ return element;
+ }
+
+ function stopObserving(element, eventName, handler) {
+ element = $(element);
+
+ var registry = Element.retrieve(element, 'prototype_event_registry');
+ if (!registry) return element;
+ if (!eventName) {
+ registry.each( function(pair) {
+ var eventName = pair.key;
+ stopObserving(element, eventName);
+ });
return element;
- },
+ }
- stopObserving: function(element, eventName, handler) {
- element = $(element);
- var id = getEventID(element), name = getDOMEventName(eventName);
+ var responders = registry.get(eventName);
+ if (!responders) return element;
- if (!handler && eventName) {
- getWrappersForEventName(id, eventName).each(function(wrapper) {
- element.stopObserving(eventName, wrapper.handler);
- });
- return element;
+ if (!handler) {
+ responders.each(function(r) {
+ stopObserving(element, eventName, r.handler);
+ });
+ return element;
+ }
- } else if (!eventName) {
- Object.keys(getCacheForID(id)).each(function(eventName) {
- element.stopObserving(eventName);
- });
- return element;
+ var responder = responders.find( function(r) { return r.handler === handler; });
+ if (!responder) return element;
+
+ if (eventName.include(':')) {
+ if (element.removeEventListener)
+ element.removeEventListener("dataavailable", responder, false);
+ else {
+ element.detachEvent("ondataavailable", responder);
+ element.detachEvent("onfilterchange", responder);
}
+ } else {
+ var actualEventName = _getDOMEventName(eventName);
+ if (element.removeEventListener)
+ element.removeEventListener(actualEventName, responder, false);
+ else
+ element.detachEvent('on' + actualEventName, responder);
+ }
- var wrapper = findWrapper(id, eventName, handler);
- if (!wrapper) return element;
+ registry.set(eventName, responders.without(responder));
- if (element.removeEventListener) {
- element.removeEventListener(name, wrapper, false);
- } else {
- element.detachEvent("on" + name, wrapper);
- }
+ return element;
+ }
- destroyWrapper(id, eventName, handler);
+ function fire(element, eventName, memo, bubble) {
+ element = $(element);
- return element;
- },
+ if (Object.isUndefined(bubble))
+ bubble = true;
- fire: function(element, eventName, memo) {
- element = $(element);
- if (element == document && document.createEvent && !element.dispatchEvent)
- element = document.documentElement;
+ if (element == document && document.createEvent && !element.dispatchEvent)
+ element = document.documentElement;
- if (document.createEvent) {
- var event = document.createEvent("HTMLEvents");
- event.initEvent("dataavailable", true, true);
- } else {
- var event = document.createEventObject();
- event.eventType = "ondataavailable";
- }
+ var event;
+ if (document.createEvent) {
+ event = document.createEvent('HTMLEvents');
+ event.initEvent('dataavailable', true, true);
+ } else {
+ event = document.createEventObject();
+ event.eventType = bubble ? 'ondataavailable' : 'onfilterchange';
+ }
- event.eventName = eventName;
- event.memo = memo || { };
+ event.eventName = eventName;
+ event.memo = memo || { };
- if (document.createEvent) {
- element.dispatchEvent(event);
- } else {
- element.fireEvent(event.eventType, event);
- }
+ if (document.createEvent)
+ element.dispatchEvent(event);
+ else
+ element.fireEvent(event.eventType, event);
+
+ return Event.extend(event);
+ }
+
+ Event.Handler = Class.create({
+ initialize: function(element, eventName, selector, callback) {
+ this.element = $(element);
+ this.eventName = eventName;
+ this.selector = selector;
+ this.callback = callback;
+ this.handler = this.handleEvent.bind(this);
+ },
- return Event.extend(event);
+ start: function() {
+ Event.observe(this.element, this.eventName, this.handler);
+ return this;
+ },
+
+ stop: function() {
+ Event.stopObserving(this.element, this.eventName, this.handler);
+ return this;
+ },
+
+ handleEvent: function(event) {
+ var element = event.findElement(this.selector);
+ if (element) this.callback.call(this.element, event, element);
}
- };
-})());
+ });
-Object.extend(Event, Event.Methods);
+ function on(element, eventName, selector, callback) {
+ element = $(element);
+ if (Object.isFunction(selector) && Object.isUndefined(callback)) {
+ callback = selector, selector = null;
+ }
-Element.addMethods({
- fire: Event.fire,
- observe: Event.observe,
- stopObserving: Event.stopObserving
-});
+ return new Event.Handler(element, eventName, selector, callback).start();
+ }
-Object.extend(document, {
- fire: Element.Methods.fire.methodize(),
- observe: Element.Methods.observe.methodize(),
- stopObserving: Element.Methods.stopObserving.methodize()
-});
+ Object.extend(Event, Event.Methods);
+
+ Object.extend(Event, {
+ fire: fire,
+ observe: observe,
+ stopObserving: stopObserving,
+ on: on
+ });
+
+ Element.addMethods({
+ fire: fire,
+
+ observe: observe,
+
+ stopObserving: stopObserving,
+
+ on: on
+ });
+
+ Object.extend(document, {
+ fire: fire.methodize(),
+
+ observe: observe.methodize(),
+
+ stopObserving: stopObserving.methodize(),
+
+ on: on.methodize(),
+
+ loaded: false
+ });
+
+ if (window.Event) Object.extend(window.Event, Event);
+ else window.Event = Event;
+})();
(function() {
/* Support for the DOMContentLoaded event is based on work by Dan Webb,
- Matthias Miller, Dean Edwards and John Resig. */
+ Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
- var timer, fired = false;
+ var timer;
function fireContentLoadedEvent() {
- if (fired) return;
- if (timer) window.clearInterval(timer);
- document.fire("dom:loaded");
- fired = true;
+ if (document.loaded) return;
+ if (timer) window.clearTimeout(timer);
+ document.loaded = true;
+ document.fire('dom:loaded');
}
- if (document.addEventListener) {
- if (Prototype.Browser.WebKit) {
- timer = window.setInterval(function() {
- if (/loaded|complete/.test(document.readyState))
- fireContentLoadedEvent();
- }, 0);
-
- Event.observe(window, "load", fireContentLoadedEvent);
+ function checkReadyState() {
+ if (document.readyState === 'complete') {
+ document.stopObserving('readystatechange', checkReadyState);
+ fireContentLoadedEvent();
+ }
+ }
- } else {
- document.addEventListener("DOMContentLoaded",
- fireContentLoadedEvent, false);
+ function pollDoScroll() {
+ try { document.documentElement.doScroll('left'); }
+ catch(e) {
+ timer = pollDoScroll.defer();
+ return;
}
+ fireContentLoadedEvent();
+ }
+ if (document.addEventListener) {
+ document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
} else {
- document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
- $("__onDOMContentLoaded").onreadystatechange = function() {
- if (this.readyState == "complete") {
- this.onreadystatechange = null;
- fireContentLoadedEvent();
- }
- };
+ document.observe('readystatechange', checkReadyState);
+ if (window == top)
+ timer = pollDoScroll.defer();
}
+
+ Event.observe(window, 'load', fireContentLoadedEvent);
})();
+
+Element.addMethods();
+
/*------------------------------- DEPRECATED -------------------------------*/
Hash.toQueryString = Object.toQueryString;
@@ -4063,16 +5796,9 @@ var Insertion = {
var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
-// This should be moved to script.aculo.us; notice the deprecated methods
-// further below, that map to the newer Element methods.
var Position = {
- // set to true if needed, warning: firefox performance problems
- // NOT neeeded for page scrolling, only if draggable contained in
- // scrollable elements
includeScrollOffsets: false,
- // must be called before calling withinIncludingScrolloffset, every time the
- // page is scrolled
prepare: function() {
this.deltaX = window.pageXOffset
|| document.documentElement.scrollLeft
@@ -4084,7 +5810,6 @@ var Position = {
|| 0;
},
- // caches x/y coordinate pair to use with overlap
within: function(element, x, y) {
if (this.includeScrollOffsets)
return this.withinIncludingScrolloffsets(element, x, y);
@@ -4111,7 +5836,6 @@ var Position = {
this.xcomp < this.offset[0] + element.offsetWidth);
},
- // within must be called directly before
overlap: function(mode, element) {
if (!mode) return 0;
if (mode == 'vertical')
@@ -4122,7 +5846,6 @@ var Position = {
element.offsetWidth;
},
- // Deprecation layer -- use newer Element methods now (1.5.2).
cumulativeOffset: Element.Methods.cumulativeOffset,
@@ -4222,4 +5945,57 @@ Object.extend(Element.ClassNames.prototype, Enumerable);
/*--------------------------------------------------------------------------*/
-Element.addMethods(); \ No newline at end of file
+(function() {
+ window.Selector = Class.create({
+ initialize: function(expression) {
+ this.expression = expression.strip();
+ },
+
+ findElements: function(rootElement) {
+ return Prototype.Selector.select(this.expression, rootElement);
+ },
+
+ match: function(element) {
+ return Prototype.Selector.match(element, this.expression);
+ },
+
+ toString: function() {
+ return this.expression;
+ },
+
+ inspect: function() {
+ return "#<Selector: " + this.expression + ">";
+ }
+ });
+
+ Object.extend(Selector, {
+ matchElements: function(elements, expression) {
+ var match = Prototype.Selector.match,
+ results = [];
+
+ for (var i = 0, length = elements.length; i < length; i++) {
+ var element = elements[i];
+ if (match(element, expression)) {
+ results.push(Element.extend(element));
+ }
+ }
+ return results;
+ },
+
+ findElement: function(elements, expression, index) {
+ index = index || 0;
+ var matchIndex = 0, element;
+ for (var i = 0, length = elements.length; i < length; i++) {
+ element = elements[i];
+ if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
+ return Element.extend(element);
+ }
+ }
+ },
+
+ findChildElements: function(element, expressions) {
+ var selector = expressions.toArray().join(', ');
+ return Prototype.Selector.select(selector, element || document);
+ }
+ });
+})();
diff --git a/public/javascripts/rails.js b/public/javascripts/rails.js
new file mode 100644
index 000000000..5cea13c15
--- /dev/null
+++ b/public/javascripts/rails.js
@@ -0,0 +1,202 @@
+(function() {
+ Ajax.Responders.register({
+ onCreate: function(request) {
+ var token = $$('meta[name=csrf-token]')[0];
+ if (token) {
+ if (!request.options.requestHeaders) request.options.requestHeaders = {};
+ request.options.requestHeaders['X-CSRF-Token'] = token.readAttribute('content');
+ }
+ }
+ });
+
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+ function isEventSupported(eventName) {
+ var el = document.createElement('div');
+ eventName = 'on' + eventName;
+ var isSupported = (eventName in el);
+ if (!isSupported) {
+ el.setAttribute(eventName, 'return;');
+ isSupported = typeof el[eventName] == 'function';
+ }
+ el = null;
+ return isSupported;
+ }
+
+ function isForm(element) {
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM';
+ }
+
+ function isInput(element) {
+ if (Object.isElement(element)) {
+ var name = element.nodeName.toUpperCase();
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA';
+ }
+ else return false;
+ }
+
+ var submitBubbles = isEventSupported('submit'),
+ changeBubbles = isEventSupported('change');
+
+ if (!submitBubbles || !changeBubbles) {
+ // augment the Event.Handler class to observe custom events when needed
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
+ function(init, element, eventName, selector, callback) {
+ init(element, eventName, selector, callback);
+ // is the handler being attached to an element that doesn't support this event?
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
+ // "submit" => "emulated:submit"
+ this.eventName = 'emulated:' + this.eventName;
+ }
+ }
+ );
+ }
+
+ if (!submitBubbles) {
+ // discover forms on the page by observing focus events which always bubble
+ document.on('focusin', 'form', function(focusEvent, form) {
+ // special handler for the real "submit" event (one-time operation)
+ if (!form.retrieve('emulated:submit')) {
+ form.on('submit', function(submitEvent) {
+ var emulated = form.fire('emulated:submit', submitEvent, true);
+ // if custom event received preventDefault, cancel the real one too
+ if (emulated.returnValue === false) submitEvent.preventDefault();
+ });
+ form.store('emulated:submit', true);
+ }
+ });
+ }
+
+ if (!changeBubbles) {
+ // discover form inputs on the page
+ document.on('focusin', 'input, select, textarea', function(focusEvent, input) {
+ // special handler for real "change" events
+ if (!input.retrieve('emulated:change')) {
+ input.on('change', function(changeEvent) {
+ input.fire('emulated:change', changeEvent, true);
+ });
+ input.store('emulated:change', true);
+ }
+ });
+ }
+
+ function handleRemote(element) {
+ var method, url, params;
+
+ var event = element.fire("ajax:before");
+ if (event.stopped) return false;
+
+ if (element.tagName.toLowerCase() === 'form') {
+ method = element.readAttribute('method') || 'post';
+ url = element.readAttribute('action');
+ // serialize the form with respect to the submit button that was pressed
+ params = element.serialize({ submit: element.retrieve('rails:submit-button') });
+ // clear the pressed submit button information
+ element.store('rails:submit-button', null);
+ } else {
+ method = element.readAttribute('data-method') || 'get';
+ url = element.readAttribute('href');
+ params = {};
+ }
+
+ new Ajax.Request(url, {
+ method: method,
+ parameters: params,
+ evalScripts: true,
+
+ onCreate: function(response) { element.fire("ajax:create", response); },
+ onComplete: function(response) { element.fire("ajax:complete", response); },
+ onSuccess: function(response) { element.fire("ajax:success", response); },
+ onFailure: function(response) { element.fire("ajax:failure", response); }
+ });
+
+ element.fire("ajax:after");
+ }
+
+ function insertHiddenField(form, name, value) {
+ form.insert(new Element('input', { type: 'hidden', name: name, value: value }));
+ }
+
+ function handleMethod(element) {
+ var method = element.readAttribute('data-method'),
+ url = element.readAttribute('href'),
+ csrf_param = $$('meta[name=csrf-param]')[0],
+ csrf_token = $$('meta[name=csrf-token]')[0];
+
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
+ $(element.parentNode).insert(form);
+
+ if (method !== 'post') {
+ insertHiddenField(form, '_method', method);
+ }
+
+ if (csrf_param) {
+ insertHiddenField(form, csrf_param.readAttribute('content'), csrf_token.readAttribute('content'));
+ }
+
+ form.submit();
+ }
+
+ function disableFormElements(form) {
+ form.select('input[type=submit][data-disable-with]').each(function(input) {
+ input.store('rails:original-value', input.getValue());
+ input.setValue(input.readAttribute('data-disable-with')).disable();
+ });
+ }
+
+ function enableFormElements(form) {
+ form.select('input[type=submit][data-disable-with]').each(function(input) {
+ input.setValue(input.retrieve('rails:original-value')).enable();
+ });
+ }
+
+ function allowAction(element) {
+ var message = element.readAttribute('data-confirm');
+ return !message || confirm(message);
+ }
+
+ document.on('click', 'a[data-confirm], a[data-remote], a[data-method]', function(event, link) {
+ if (!allowAction(link)) {
+ event.stop();
+ return false;
+ }
+
+ if (link.readAttribute('data-remote')) {
+ handleRemote(link);
+ event.stop();
+ } else if (link.readAttribute('data-method')) {
+ handleMethod(link);
+ event.stop();
+ }
+ });
+
+ document.on("click", "form input[type=submit], form button[type=submit], form button:not([type])", function(event, button) {
+ // register the pressed submit button
+ event.findElement('form').store('rails:submit-button', button.name || false);
+ });
+
+ document.on("submit", function(event) {
+ var form = event.findElement();
+
+ if (!allowAction(form)) {
+ event.stop();
+ return false;
+ }
+
+ if (form.readAttribute('data-remote')) {
+ handleRemote(form);
+ event.stop();
+ } else {
+ disableFormElements(form);
+ }
+ });
+
+ document.on('ajax:create', 'form', function(event, form) {
+ if (form == event.findElement()) disableFormElements(form);
+ });
+
+ document.on('ajax:complete', 'form', function(event, form) {
+ if (form == event.findElement()) enableFormElements(form);
+ });
+})();
diff --git a/script/about b/script/about
deleted file mode 100755
index 49a7c2609..000000000
--- a/script/about
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/about'
diff --git a/script/alert-comment-on-request b/script/alert-comment-on-request
index 74782aa13..1222eecf1 100755
--- a/script/alert-comment-on-request
+++ b/script/alert-comment-on-request
@@ -1,7 +1,3 @@
#!/bin/bash
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'RequestMailer.alert_comment_on_request'
-
-
+bundle exec rails runner 'RequestMailer.alert_comment_on_request'
diff --git a/script/alert-new-response-reminders b/script/alert-new-response-reminders
index 59fa76df1..97f558f43 100755
--- a/script/alert-new-response-reminders
+++ b/script/alert-new-response-reminders
@@ -1,7 +1,3 @@
#!/bin/bash
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'RequestMailer.alert_new_response_reminders'
-
-
+bundle exec rails runner 'RequestMailer.alert_new_response_reminders'
diff --git a/script/alert-not-clarified-request b/script/alert-not-clarified-request
index a38fbc70e..fb562beeb 100755
--- a/script/alert-not-clarified-request
+++ b/script/alert-not-clarified-request
@@ -1,7 +1,3 @@
#!/bin/bash
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'RequestMailer.alert_not_clarified_request'
-
-
+bundle exec rails runner 'RequestMailer.alert_not_clarified_request'
diff --git a/script/alert-overdue-requests b/script/alert-overdue-requests
index 46450f1f2..9e597d17d 100755
--- a/script/alert-overdue-requests
+++ b/script/alert-overdue-requests
@@ -1,5 +1,3 @@
#!/bin/bash
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'RequestMailer.alert_overdue_requests()'
+bundle exec rails runner 'RequestMailer.alert_overdue_requests'
diff --git a/script/alert-tracks b/script/alert-tracks
index 117f7a406..9fd32f2a1 100755
--- a/script/alert-tracks
+++ b/script/alert-tracks
@@ -1,11 +1,8 @@
#!/bin/bash
-LOC=`dirname $0`
-
if [ "$1" == "--loop" ]
then
- "$LOC/runner" 'TrackMailer.alert_tracks_loop'
+ bundle exec rails runner 'TrackMailer.alert_tracks_loop'
else
- "$LOC/runner" 'TrackMailer.alert_tracks'
+ bundle exec rails runner 'TrackMailer.alert_tracks'
fi
-
diff --git a/script/annotate-models b/script/annotate-models
index b6e01c010..7b6daa3c5 100755
--- a/script/annotate-models
+++ b/script/annotate-models
@@ -2,4 +2,4 @@
#
# annotates the models in app/ with schema information
-bundle exec annotate -m -p before --exclude tests,fixtures
+bundle exec annotate --show-migration --position before --exclude tests,fixtures
diff --git a/script/autospec b/script/autospec
deleted file mode 100755
index 837bbd7f4..000000000
--- a/script/autospec
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env ruby
-gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
-ENV['RSPEC'] = 'true' # allows autotest to discover rspec
-ENV['AUTOTEST'] = 'true' # allows autotest to run w/ color on linux
-system((RUBY_PLATFORM =~ /mswin|mingw/ ? 'autotest.bat' : 'autotest'), *ARGV) ||
- $stderr.puts("Unable to find autotest. Please install ZenTest or fix your PATH")
diff --git a/script/breakpointer b/script/breakpointer
deleted file mode 100755
index 46a01d1b2..000000000
--- a/script/breakpointer
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/breakpointer'
diff --git a/script/cache-incoming-emails b/script/cache-incoming-emails
index 0b3069bd7..b13efbd8c 100644..100755
--- a/script/cache-incoming-emails
+++ b/script/cache-incoming-emails
@@ -4,6 +4,4 @@
# Will take a while to run! Can use after clear-caches to refresh the database
# level caches if you like.
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'IncomingMessage.find_each() { |im| print "info request " + im.info_request.id.to_s + ", incoming message " + im.id.to_s + ": " + im.extract_attachments!.count.to_s + " attachments extracted to " + im.foi_attachments[0].directory + "; main body folded: " + im.get_main_body_text_folded.size.to_s + " attachment clipped:" + im.get_attachment_text_clipped.size.to_s + "\n" }'
+bundle exec rails runner 'IncomingMessage.find_each { |im| print "info request " + im.info_request.id.to_s + ", incoming message " + im.id.to_s + ": " + im.extract_attachments!.count.to_s + " attachments extracted to " + im.foi_attachments[0].directory + "; main body folded: " + im.get_main_body_text_folded.size.to_s + " attachment clipped:" + im.get_attachment_text_clipped.size.to_s + "\n" }'
diff --git a/script/check-recent-requests-sent b/script/check-recent-requests-sent
index 7840dba4a..1eb87d498 100755
--- a/script/check-recent-requests-sent
+++ b/script/check-recent-requests-sent
@@ -1,8 +1,3 @@
#!/bin/bash
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'MailServerLog.check_recent_requests_have_been_sent'
-
-
-
+bundle exec rails runner 'MailServerLog.check_recent_requests_have_been_sent'
diff --git a/script/clear-caches b/script/clear-caches
index 43fec2811..f97c1f777 100755
--- a/script/clear-caches
+++ b/script/clear-caches
@@ -2,12 +2,11 @@
# Clear the cache of attachment and body text.
-cd "`dirname "$0"`"
+LOC="`dirname "$0"`"
-bundle exec ./runner "ActiveRecord::Base.connection.execute(\"update incoming_messages set cached_attachment_text_clipped = null, cached_main_body_text_unfolded = null, cached_main_body_text_folded = null, sent_at = null, subject = null, mail_from = null, mail_from_domain = null, valid_to_reply_to = null, last_parsed = null\")"
+bundle exec rails runner "ActiveRecord::Base.connection.execute(\"update incoming_messages set cached_attachment_text_clipped = null, cached_main_body_text_unfolded = null, cached_main_body_text_folded = null, sent_at = null, subject = null, mail_from = null, mail_from_domain = null, valid_to_reply_to = null, last_parsed = null\")"
# Remove page cache (do it in two stages so live site gets cache cleared faster)
rm -fr $LOC/../old-cache
mv $LOC/../cache $LOC/../old-cache
rm -fr $LOC/../old-cache
-
diff --git a/script/console b/script/console
deleted file mode 100755
index 83386647f..000000000
--- a/script/console
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/console'
diff --git a/script/dbconsole b/script/dbconsole
deleted file mode 100755
index 39042fad3..000000000
--- a/script/dbconsole
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/dbconsole'
diff --git a/script/delete-old-things b/script/delete-old-things
index 063d85e1f..58c144958 100755
--- a/script/delete-old-things
+++ b/script/delete-old-things
@@ -1,6 +1,4 @@
#!/bin/bash
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'PostRedirect.delete_old_post_redirects()'
-bundle exec ./runner 'TrackThingsSentEmail.delete_old_track_things_sent_email()'
+bundle exec rails runner 'PostRedirect.delete_old_post_redirects'
+bundle exec rails runner 'TrackThingsSentEmail.delete_old_track_things_sent_email'
diff --git a/script/destroy b/script/destroy
deleted file mode 100755
index fddc5160d..000000000
--- a/script/destroy
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/destroy'
diff --git a/script/direct-rspec b/script/direct-rspec
deleted file mode 100755
index 50a1daba1..000000000
--- a/script/direct-rspec
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-./vendor/plugins/rspec/bin/spec $1
-
-# spec/controllers/request_controller_spec.rb
-
-#ruby -I/home/francis/keep/devel/mysociety/foi/vendor/plugins/rspec/lib /home/francis/keep/devel/mysociety/foi/vendor/plugins/rspec/bin/spec spec/controllers/admin_public_body_controller_spec.rb spec/controllers/application_spec.rb spec/controllers/request_controller_spec.rb spec/controllers/user_controller_spec.rb spec/controllers/admin_controller_spec.rb spec/controllers/body_controller_spec.rb spec/models/incoming_message_spec.rb spec/models/user_spec.rb spec/models/request_mailer_spec.rb spec/models/post_redirect_spec.rb spec/models/public_body_spec.rb spec/models/info_request_spec.rb spec/models/user_mailer_spec.rb spec/models/outgoing_message_spec.rb --options /home/francis/keep/devel/mysociety/foi/spec/spec.opts
-
diff --git a/script/generate b/script/generate
deleted file mode 100755
index fb8139d12..000000000
--- a/script/generate
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/generate'
diff --git a/script/handle-mail-replies.rb b/script/handle-mail-replies.rb
index 4e35ee0cf..23430e20a 100755
--- a/script/handle-mail-replies.rb
+++ b/script/handle-mail-replies.rb
@@ -14,12 +14,8 @@
# config file ourselves.
$alaveteli_dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
$:.push(File.join($alaveteli_dir, "commonlib", "rblib"))
-load "config.rb"
$:.push(File.join($alaveteli_dir, "lib"))
$:.push(File.join($alaveteli_dir, "lib", "mail_handler"))
-require "configuration"
-MySociety::Config.set_file(File.join($alaveteli_dir, 'config', 'general'), true)
-MySociety::Config.load_default
require 'mail_handler'
if RUBY_VERSION.to_f >= 1.9
# the default encoding for IO is utf-8, and we use utf-8 internally
@@ -165,7 +161,7 @@ def is_oof?(message)
end
def forward_on(raw_message)
- IO.popen("/usr/sbin/sendmail -i #{Configuration::forward_nonbounce_responses_to}", "w") do |f|
+ IO.popen("/usr/sbin/sendmail -i #{AlaveteliConfiguration::forward_nonbounce_responses_to}", "w") do |f|
f.write(raw_message);
f.close;
end
diff --git a/script/load-mail-server-logs b/script/load-mail-server-logs
index 9ff7a1401..770bf7026 100755
--- a/script/load-mail-server-logs
+++ b/script/load-mail-server-logs
@@ -14,7 +14,7 @@ then
*) f=$(pwd)/$1 ;;
esac
cd "$LOC"
- bundle exec ./runner 'MailServerLog.load_file("'$f'")'
+ bundle exec rails runner 'MailServerLog.load_file("'$f'")'
exit
fi
@@ -23,5 +23,5 @@ cd "$LOC"
LATEST=$( ls $OPTION_MTA_LOG_PATH 2>/dev/null | sort | tail -3 )
for X in $LATEST
do
- bundle exec ./runner 'MailServerLog.load_file("'$X'")'
+ bundle exec rails runner 'MailServerLog.load_file("'$X'")'
done
diff --git a/script/load-sample-data b/script/load-sample-data
index 86e1af128..e91516886 100755
--- a/script/load-sample-data
+++ b/script/load-sample-data
@@ -4,16 +4,28 @@
# the fact that the fixtures aren't aware of the fact that RawEmails
# have a filesystem representation of their contents
-LOC=`dirname "$0"`
+export LOC=`dirname "$0"`
-bundle exec rake --silent spec:db:fixtures:load
+bundle exec rails runner /dev/stdin <<END
+require 'rspec/rails'
+require "#{ENV['LOC']}/../spec/support/load_file_fixtures.rb"
+require "#{ENV['LOC']}/../spec/support/email_helpers.rb"
-"$LOC/runner" /dev/stdin <<END
-env = ENV["RAILS_ENV"]
-require "spec/spec_helper.rb" # this sets RAILS_ENV to 'test'
-ENV["RAILS_ENV"] = env # so restore to what it was before
+RSpec.configure do |config|
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
+end
+
+# HACK: Normally to load fixtures you'd run `rake db:fixtures:load` but since we
+# have .csv files in the fixtures folder Rails tries to load those too. Therefore
+# we've pinched some code to load the fixtures:
+# https://github.com/rails/rails/blob/v3.1.11/activerecord/lib/active_record/railties/databases.rake#L311
+fixtures_dir = "#{ENV['LOC']}/../spec/fixtures"
+
+Dir["#{fixtures_dir}/**/*.yml"].each do |fixture_file|
+ ActiveRecord::Fixtures.create_fixtures(fixtures_dir, fixture_file[(fixtures_dir.size + 1)..-5])
+end
load_raw_emails_data
END
-echo "Loaded fixtures. You may now wish to run $LOC/update-xapian-index"
+echo "Loaded fixtures. You may now wish to run $LOC/update-xapian-index"
diff --git a/script/mailin b/script/mailin
index b4d77f7a4..6ed6bc7db 100755
--- a/script/mailin
+++ b/script/mailin
@@ -13,7 +13,7 @@ source commonlib/shlib/deployfns
read_conf config/general
-script/runner 'RequestMailer.receive(STDIN.read)' <"$INPUT" >"$OUTPUT" 2>&1
+rails runner 'RequestMailer.receive(STDIN.read)' <"$INPUT" >"$OUTPUT" 2>&1
ERROR_CODE=$?
if [ ! "$ERROR_CODE" = "0" ]
then
diff --git a/script/performance/benchmarker b/script/performance/benchmarker
deleted file mode 100755
index 28bfceea0..000000000
--- a/script/performance/benchmarker
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/performance/benchmarker'
diff --git a/script/performance/profiler b/script/performance/profiler
deleted file mode 100755
index 11baf44f2..000000000
--- a/script/performance/profiler
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/performance/profiler'
diff --git a/script/performance/request b/script/performance/request
deleted file mode 100755
index fff6fe660..000000000
--- a/script/performance/request
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/performance/request'
diff --git a/script/plugin b/script/plugin
deleted file mode 100755
index 49f5c441f..000000000
--- a/script/plugin
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/plugin'
diff --git a/script/process/inspector b/script/process/inspector
deleted file mode 100755
index 467962602..000000000
--- a/script/process/inspector
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/process/inspector'
diff --git a/script/process/reaper b/script/process/reaper
deleted file mode 100755
index 2eea898db..000000000
--- a/script/process/reaper
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/process/reaper'
diff --git a/script/process/spawner b/script/process/spawner
deleted file mode 100755
index ac417c3a7..000000000
--- a/script/process/spawner
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/process/spawner'
diff --git a/script/purge-varnish b/script/purge-varnish
index 932cf6635..7dcecd4f9 100755
--- a/script/purge-varnish
+++ b/script/purge-varnish
@@ -4,8 +4,8 @@ LOC=`dirname $0`
if [ "$1" == "--loop" ]
then
- "$LOC/runner" 'PurgeRequest.purge_all_loop'
+ rails runner 'PurgeRequest.purge_all_loop'
else
- "$LOC/runner" 'PurgeRequest.purge_all'
+ rails runner 'PurgeRequest.purge_all'
fi
diff --git a/script/rails b/script/rails
new file mode 100755
index 000000000..f8da2cffd
--- /dev/null
+++ b/script/rails
@@ -0,0 +1,6 @@
+#!/usr/bin/env ruby
+# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
+
+APP_PATH = File.expand_path('../../config/application', __FILE__)
+require File.expand_path('../../config/boot', __FILE__)
+require 'rails/commands'
diff --git a/script/rails-post-deploy b/script/rails-post-deploy
index a1c613312..bd99b0ce2 100755
--- a/script/rails-post-deploy
+++ b/script/rails-post-deploy
@@ -6,7 +6,7 @@
# recent version.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
set -e
#set -x # debug
diff --git a/script/request-creation-graph b/script/request-creation-graph
index d49a361b8..ef1d2cf73 100755
--- a/script/request-creation-graph
+++ b/script/request-creation-graph
@@ -3,7 +3,7 @@
# Plot graph of rate of request creation
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org. WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org. WWW: http://www.mysociety.org/
GPLOT_OUTPUT="set terminal png font 'Vera.ttf' 9 size 1600,600"
EXTENSION=".png"
diff --git a/script/runner b/script/runner
index 1575848de..73b03847d 100755
--- a/script/runner
+++ b/script/runner
@@ -6,7 +6,6 @@ script_dir = File.dirname(__FILE__)
alaveteli_dir = File.expand_path(File.join(script_dir, ".."))
Dir.chdir(alaveteli_dir) do
- require File.join(alaveteli_dir, 'config', 'boot')
if daemon_mode
# Run in daemon mode.
@@ -20,7 +19,7 @@ Dir.chdir(alaveteli_dir) do
# Load the runner in a subprocess
pid = fork do
- require 'commands/runner'
+ `bundle exec rails runner #{ARGV[1]}`
exit 0
end
@@ -35,6 +34,6 @@ Dir.chdir(alaveteli_dir) do
Process.detach(pid)
else
# Not daemon mode
- require 'commands/runner'
+ `bundle exec rails runner #{ARGV[1]}`
end
end
diff --git a/script/server b/script/server
deleted file mode 100755
index dc3edabd5..000000000
--- a/script/server
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path(File.dirname(__FILE__) + '/../config/boot.rb')
-require 'commands/server'
diff --git a/script/spec b/script/spec
deleted file mode 100755
index 46fdbe6e4..000000000
--- a/script/spec
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env ruby
-if ARGV.any? {|arg| %w[--drb -X --generate-options -G --help -h --version -v].include?(arg)}
- require 'rubygems' unless ENV['NO_RUBYGEMS']
-else
- gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
- ENV["RAILS_ENV"] ||= 'test'
- require File.expand_path(File.dirname(__FILE__) + "/../config/environment") unless defined?(RAILS_ROOT)
-end
-require 'spec/autorun'
-exit ::Spec::Runner::CommandLine.run
diff --git a/script/spec-all-pairs b/script/spec-all-pairs
deleted file mode 100755
index 6d7bb17c4..000000000
--- a/script/spec-all-pairs
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/bash
-
-# Try all ordered pairs of spec files,
-# to winkle out order-dependent failures.
-
-log_file=/dev/null
-
-test_pair () {
- bundle exec rake db:test:prepare > /dev/null 2>&1
- output=$(script/spec "$1" "$2" 2>&1)
- if [ $? -eq 0 ]
- then
- echo "OK: $1 $2"
- return 0
- else
- echo >> "$log_file" "FAILED: $1 $2"
- echo >> "$log_file" "======================================="
- echo >> "$log_file" "$output"
- echo >> "$log_file"
-
- echo "FAILED: $1 $2"
- return 1
- fi
-}
-
-all_pairs() {
- specs=spec/*/*.rb
-
- for spec1 in $specs
- do
- all_okay=true
- for spec2 in $specs
- do
- if ! test_pair "$spec1" "$spec2"
- then
- all_okay=false
- fi
- done
- done
-
- $all_okay
- return $?
-}
-
-pairs_from_stdin() {
- all_okay=true
- while read line
- do
- case "$line" in
- \*\ FAILED:\ *|\
- spec/*.rb\ spec/*.rb)
- line=${line#\* FAILED: }
- if ! test_pair $line
- then
- all_okay=false
- fi
- ;;
- *)
- echo "No match: $line"
- ;;
- esac
- done
-
- $all_okay
- return $?
-}
-
-if [ "$1" = --log ]
-then
- shift
- log_file=$1
- shift
- cp /dev/null "$log_file"
-fi
-if [ "$1" = "-" ]
-then
- pairs_from_stdin
-else
- all_pairs
-fi
-exit $?
diff --git a/script/spec_server b/script/spec_server
deleted file mode 100755
index dfdf8ff6c..000000000
--- a/script/spec_server
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env ruby
-$LOAD_PATH.unshift File.dirname(__FILE__) + '/../vendor/plugins/rspec/lib' # For rspec installed as plugin
-require 'rubygems'
-require 'drb/drb'
-require 'rbconfig'
-require 'spec'
-require 'optparse'
-
-# This is based on Florian Weber's TDDMate
-module Spec
- module Runner
- class RailsSpecServer
- def run(argv, stderr, stdout)
- $stdout = stdout
- $stderr = stderr
-
- base = ActiveRecord::Base
- def base.clear_reloadable_connections!
- active_connections.each do |name, conn|
- if conn.requires_reloading?
- conn.disconnect!
- active_connections.delete(name)
- end
- end
- end
-
- if ActionController.const_defined?(:Dispatcher)
- dispatcher = ::ActionController::Dispatcher.new($stdout)
- dispatcher.cleanup_application
- elsif ::Dispatcher.respond_to?(:reset_application!)
- ::Dispatcher.reset_application!
- else
- raise "Application reloading failed"
- end
- if Object.const_defined?(:Fixtures) && Fixtures.respond_to?(:reset_cache)
- Fixtures.reset_cache
- end
-
- ::Dependencies.mechanism = :load
- require_dependency('application.rb') unless Object.const_defined?(:ApplicationController)
- load File.dirname(__FILE__) + '/../spec/spec_helper.rb'
-
- if in_memory_database?
- load "#{Rails.root}/db/schema.rb" # use db agnostic schema by default
- ActiveRecord::Migrator.up('db/migrate') # use migrations
- end
-
- ::Spec::Runner::CommandLine.run(
- ::Spec::Runner::OptionParser.parse(
- argv,
- $stderr,
- $stdout
- )
- )
- end
-
- def in_memory_database?
- ENV["RAILS_ENV"] == "test" and
- ::ActiveRecord::Base.connection.class.to_s == "ActiveRecord::ConnectionAdapters::SQLite3Adapter" and
- ::Rails::Configuration.new.database_configuration['test']['database'] == ':memory:'
- end
- end
- end
-end
-puts "Loading Rails environment"
-
-ENV["RAILS_ENV"] = "test"
-require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
-require 'dispatcher'
-
-def restart_test_server
- puts "restarting"
- config = ::Config::CONFIG
- ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT']
- command_line = [ruby, $0, ARGV].flatten.join(' ')
- exec(command_line)
-end
-
-def daemonize(pid_file = nil)
- return yield if $DEBUG
- pid = Process.fork{
- Process.setsid
- Dir.chdir(Rails.root)
- trap("SIGINT"){ exit! 0 }
- trap("SIGTERM"){ exit! 0 }
- trap("SIGHUP"){ restart_test_server }
- File.open("/dev/null"){|f|
- STDERR.reopen f
- STDIN.reopen f
- STDOUT.reopen f
- }
- yield
- }
- puts "spec_server launched. (PID: %d)" % pid
- File.open(pid_file,"w"){|f| f.puts pid } if pid_file
- exit! 0
-end
-
-options = Hash.new
-opts = OptionParser.new
-opts.on("-d", "--daemon"){|v| options[:daemon] = true }
-opts.on("-p", "--pid PIDFILE"){|v| options[:pid] = v }
-opts.parse!(ARGV)
-
-puts "Ready"
-exec_server = lambda {
- trap("USR2") { restart_test_server } if Signal.list.has_key?("USR2")
- DRb.start_service("druby://localhost:8989", Spec::Runner::RailsSpecServer.new)
- DRb.thread.join
-}
-
-if options[:daemon]
- daemonize(options[:pid], &exec_server)
-else
- exec_server.call
-end
diff --git a/script/stop-new-responses-on-old-requests b/script/stop-new-responses-on-old-requests
index 1e325403e..f317f11ff 100755
--- a/script/stop-new-responses-on-old-requests
+++ b/script/stop-new-responses-on-old-requests
@@ -1,7 +1,3 @@
#!/bin/bash
-cd "`dirname "$0"`"
-
-bundle exec ./runner 'InfoRequest.stop_new_responses_on_old_requests()'
-
-
+bundle exec rails runner 'InfoRequest.stop_new_responses_on_old_requests'
diff --git a/script/test-run b/script/test-run
deleted file mode 100755
index 7810b57d5..000000000
--- a/script/test-run
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-cd ../
-bundle exec rake spec
-
diff --git a/script/user-use-graph b/script/user-use-graph
index 205e02416..f508c9cb6 100755
--- a/script/user-use-graph
+++ b/script/user-use-graph
@@ -3,7 +3,7 @@
# Plot graph of user use of site.
#
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org. WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org. WWW: http://www.mysociety.org/
GPLOT_OUTPUT="set terminal png font 'Vera.ttf' 9 size 1200,400"
EXTENSION=".png"
diff --git a/script/wraptest b/script/wraptest
deleted file mode 100755
index 780c9b4a2..000000000
--- a/script/wraptest
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env ruby
-#
-# wraptest:
-# Test email wrapping function
-#
-# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-#
-
-$:.push(File.join(File.dirname(__FILE__), '../../rblib'))
-load "format.rb"
-
-test_email = '''Dear Sir or Madam,
-
-Again and again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet again I extend this sentence and yet
-
-Hey you.
-
-Yours faithfully,
-
-Boo!
-
---
-
-Sent using GovernmentSpy, a project of UKCOD, registered charity number
-1076346. Is frabcus@fastmail.fm the wrong
-address for Freedom of Information requests to The Geraldine Quango? If so please let us know by emailing
-team@governmentspy quoting reference PB2.
-We\'ll make sure future ones go to the right place.
-'''
-
-test_email.gsub!(/\n/, "\r\n")
-
-puts MySociety::Format.wrap_email_body(test_email)
-
-#puts MySociety::Format.wrap_email_body("Hello this is a string.
-#
-#And another.
-#And a third.")
-
-
-
-
diff --git a/spec/controllers/admin_censor_rule_controller_spec.rb b/spec/controllers/admin_censor_rule_controller_spec.rb
index fb9ddf594..37ffd9764 100644
--- a/spec/controllers/admin_censor_rule_controller_spec.rb
+++ b/spec/controllers/admin_censor_rule_controller_spec.rb
@@ -1,20 +1,16 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe AdminCensorRuleController, "when making censor rules from the admin interface" do
- integrate_views
- before do
- basic_auth_login @request
- PurgeRequest.destroy_all
- end
-
-
+ render_views
+ before { basic_auth_login @request }
+
it "should create a censor rule and purge the corresponding request from varnish" do
- ir = info_requests(:fancy_dog_request)
+ ir = info_requests(:fancy_dog_request)
post :create, :censor_rule => {
:text => "meat",
:replacement => "tofu",
:last_edit_comment => "none",
- :info_request => ir
+ :info_request_id => ir
}
PurgeRequest.all().first.model_id.should == ir.id
end
diff --git a/spec/controllers/admin_general_controller_spec.rb b/spec/controllers/admin_general_controller_spec.rb
index dc1eb0d97..971960762 100644
--- a/spec/controllers/admin_general_controller_spec.rb
+++ b/spec/controllers/admin_general_controller_spec.rb
@@ -4,7 +4,7 @@ describe AdminGeneralController do
describe "when viewing front page of admin interface" do
- integrate_views
+ render_views
before { basic_auth_login @request }
it "should render the front page" do
@@ -14,8 +14,7 @@ describe AdminGeneralController do
it "should redirect to include trailing slash" do
get :index
- response.should redirect_to(:controller => 'admin_general',
- :action => 'index')
+ response.should redirect_to admin_general_index_url(:trailing_slash => true)
end
end
diff --git a/spec/controllers/admin_public_body_controller_spec.rb b/spec/controllers/admin_public_body_controller_spec.rb
index 28182a3cd..8a72db724 100644
--- a/spec/controllers/admin_public_body_controller_spec.rb
+++ b/spec/controllers/admin_public_body_controller_spec.rb
@@ -1,16 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe AdminPublicBodyController, "when administering public bodies" do
- integrate_views
-
- before do
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
- end
-
- after do
- ActionController::Routing::Routes.filters = @old_filters
- end
+ render_views
it "shows the index page" do
get :index
@@ -38,7 +29,7 @@ describe AdminPublicBodyController, "when administering public bodies" do
it "saves edits to a public body" do
public_bodies(:humpadink_public_body).name.should == "Department for Humpadinking"
post :update, { :id => 3, :public_body => { :name => "Renamed", :short_name => "", :tag_string => "some tags", :request_email => 'edited@localhost', :last_edit_comment => 'From test code' } }
- response.flash[:notice].should include('successful')
+ request.flash[:notice].should include('successful')
pb = PublicBody.find(public_bodies(:humpadink_public_body).id)
pb.name.should == "Renamed"
end
@@ -66,7 +57,7 @@ describe AdminPublicBodyController, "when administering public bodies" do
it "mass assigns tags" do
n = PublicBody.count
post :mass_tag_add, { :new_tag => "department", :table_name => "substring" }
- response.flash[:notice].should == "Added tag to table of bodies."
+ request.flash[:notice].should == "Added tag to table of bodies."
response.should redirect_to(:action=>'list')
PublicBody.find_by_tag("department").count.should == n
end
@@ -86,8 +77,7 @@ describe AdminPublicBodyController, "when administering public bodies" do
before do
PublicBody.stub!(:import_csv).and_return([[],[]])
- @file_object = mock("a file upload", :read => 'some contents',
- :original_filename => 'contents.txt')
+ @file_object = fixture_file_upload('/files/fake-authority-type.csv')
end
it 'should handle a nil csv file param' do
@@ -106,7 +96,7 @@ describe AdminPublicBodyController, "when administering public bodies" do
it 'should assign the original filename to the view' do
post :import_csv, { :csv_file => @file_object,
:commit => 'Dry run'}
- assigns[:original_csv_file].should == 'contents.txt'
+ assigns[:original_csv_file].should == 'fake-authority-type.csv'
end
end
@@ -154,7 +144,7 @@ end
describe AdminPublicBodyController, "when administering public bodies and paying attention to authentication" do
- integrate_views
+ render_views
before do
config = MySociety::Config.load_default()
@@ -217,7 +207,7 @@ describe AdminPublicBodyController, "when administering public bodies and paying
it "doesn't let people with good emergency account credentials log in if the emergency user is disabled" do
setup_emergency_credentials('biz', 'fuz')
- Configuration.stub!(:disable_emergency_user).and_return(true)
+ AlaveteliConfiguration.stub!(:disable_emergency_user).and_return(true)
n = PublicBody.count
basic_auth_login(@request, "biz", "fuz")
post :show, { :id => public_bodies(:humpadink_public_body).id, :emergency => 1}
@@ -276,7 +266,7 @@ describe AdminPublicBodyController, "when administering public bodies and paying
end
describe AdminPublicBodyController, "when administering public bodies with i18n" do
- integrate_views
+ render_views
it "shows the index page" do
get :index
@@ -295,13 +285,13 @@ describe AdminPublicBodyController, "when administering public bodies with i18n"
get :edit, {:id => 3, :locale => :en}
# When editing a body, the controller returns all available translations
- assigns[:public_body].translation("es").name.should == 'El Department for Humpadinking'
+ assigns[:public_body].find_translation_by_locale("es").name.should == 'El Department for Humpadinking'
assigns[:public_body].name.should == 'Department for Humpadinking'
response.should render_template('edit')
end
it "saves edits to a public body" do
- PublicBody.with_locale(:es) do
+ I18n.with_locale(:es) do
pb = PublicBody.find(id=3)
pb.name.should == "El Department for Humpadinking"
post :update, {
@@ -317,14 +307,14 @@ describe AdminPublicBodyController, "when administering public bodies with i18n"
}
}
}
- response.flash[:notice].should include('successful')
+ request.flash[:notice].should include('successful')
end
pb = PublicBody.find(public_bodies(:humpadink_public_body).id)
- PublicBody.with_locale(:es) do
+ I18n.with_locale(:es) do
pb.name.should == "Renamed"
end
- PublicBody.with_locale(:en) do
+ I18n.with_locale(:en) do
pb.name.should == "Department for Humpadinking"
end
end
@@ -338,16 +328,7 @@ describe AdminPublicBodyController, "when administering public bodies with i18n"
end
describe AdminPublicBodyController, "when creating public bodies with i18n" do
- integrate_views
-
- before do
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
- end
-
- after do
- ActionController::Routing::Routes.filters = @old_filters
- end
+ render_views
it "creates a new public body in one locale" do
n = PublicBody.count
@@ -370,12 +351,12 @@ describe AdminPublicBodyController, "when creating public bodies with i18n" do
body = PublicBody.find_by_name("New Quango")
body.translations.map {|t| t.locale.to_s}.sort.should == ["en", "es"]
- PublicBody.with_locale(:en) do
+ I18n.with_locale(:en) do
body.name.should == "New Quango"
body.url_name.should == "new_quango"
body.first_letter.should == "N"
end
- PublicBody.with_locale(:es) do
+ I18n.with_locale(:es) do
body.name.should == "Mi Nuevo Quango"
body.url_name.should == "mi_nuevo_quango"
body.first_letter.should == "M"
diff --git a/spec/controllers/admin_request_controller_spec.rb b/spec/controllers/admin_request_controller_spec.rb
index 8a3934685..b7b726507 100644
--- a/spec/controllers/admin_request_controller_spec.rb
+++ b/spec/controllers/admin_request_controller_spec.rb
@@ -1,16 +1,11 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe AdminRequestController, "when administering requests" do
- integrate_views
+ render_views
before { basic_auth_login @request }
before(:each) do
load_raw_emails_data
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
- end
- after do
- ActionController::Routing::Routes.filters = @old_filters
end
it "shows the index/list page" do
@@ -39,7 +34,7 @@ describe AdminRequestController, "when administering requests" do
:awaiting_description => false,
:allow_new_responses_from => 'anybody',
:handle_rejected_responses => 'bounce' } }
- response.flash[:notice].should include('successful')
+ request.flash[:notice].should include('successful')
ir = InfoRequest.find(info_requests(:fancy_dog_request).id)
ir.title.should == "Renamed"
end
@@ -64,7 +59,7 @@ describe AdminRequestController, "when administering requests" do
it "saves edits to an outgoing_message" do
outgoing_messages(:useless_outgoing_message).body.should include("fancy dog")
post :update_outgoing, { :id => outgoing_messages(:useless_outgoing_message), :outgoing_message => { :body => "Why do you have such a delicious cat?" } }
- response.flash[:notice].should include('successful')
+ request.flash[:notice].should include('successful')
ir = OutgoingMessage.find(outgoing_messages(:useless_outgoing_message).id)
ir.body.should include("delicious cat")
end
@@ -82,15 +77,10 @@ describe AdminRequestController, "when administering requests" do
end
describe AdminRequestController, "when administering the holding pen" do
- integrate_views
+ render_views
before(:each) do
basic_auth_login @request
load_raw_emails_data
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
- end
- after do
- ActionController::Routing::Routes.filters = @old_filters
end
it "shows a rejection reason for an incoming message from an invalid address" do
@@ -100,7 +90,7 @@ describe AdminRequestController, "when administering the holding pen" do
ir.save!
receive_incoming_mail('incoming-request-plain.email', ir.incoming_email, "frob@nowhere.com")
get :show_raw_email, :id => InfoRequest.holding_pen_request.get_last_response.raw_email.id
- response.should have_text(/Only the authority can reply to this request/)
+ response.should contain "Only the authority can reply to this request"
end
it "allows redelivery even to a closed request" do
@@ -164,7 +154,7 @@ describe AdminRequestController, "when administering the holding pen" do
receive_incoming_mail('incoming-request-plain.email', ir.incoming_email, "")
InfoRequest.holding_pen_request.incoming_messages.length.should == 2
get :show_raw_email, :id => interesting_email
- response.should have_text(/Could not identify the request/)
+ response.should contain "Could not identify the request"
assigns[:info_requests][0].should == ir
end
@@ -260,13 +250,13 @@ describe AdminRequestController, "when administering the holding pen" do
end
it 'should not send a notification email' do
- ContactMailer.should_not_receive(:deliver_from_admin_message)
+ ContactMailer.should_not_receive(:from_admin_message)
make_request
end
it 'should add a notice to the flash saying that the request has been hidden' do
make_request
- response.flash[:notice].should == "This external request has been hidden"
+ request.flash[:notice].should == "This external request has been hidden"
end
it 'should expire the file cache for the request' do
diff --git a/spec/controllers/admin_track_controller_spec.rb b/spec/controllers/admin_track_controller_spec.rb
index 728c79f1f..f2de6c0d3 100644
--- a/spec/controllers/admin_track_controller_spec.rb
+++ b/spec/controllers/admin_track_controller_spec.rb
@@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe AdminTrackController, "when administering tracks" do
- integrate_views
+ render_views
it "shows the list page" do
get :list
diff --git a/spec/controllers/admin_user_controller_spec.rb b/spec/controllers/admin_user_controller_spec.rb
index cf3665c9f..a6e5a0d7e 100644
--- a/spec/controllers/admin_user_controller_spec.rb
+++ b/spec/controllers/admin_user_controller_spec.rb
@@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe AdminUserController, "when administering users" do
- integrate_views
+ render_views
it "shows the index/list page" do
get :index
diff --git a/spec/controllers/api_controller_spec.rb b/spec/controllers/api_controller_spec.rb
index 1c320f85c..749be9f85 100644
--- a/spec/controllers/api_controller_spec.rb
+++ b/spec/controllers/api_controller_spec.rb
@@ -7,7 +7,7 @@ def normalise_whitespace(s)
return s
end
-Spec::Matchers.define :be_equal_modulo_whitespace_to do |expected|
+RSpec::Matchers.define :be_equal_modulo_whitespace_to do |expected|
match do |actual|
normalise_whitespace(actual) == normalise_whitespace(expected)
end
@@ -173,7 +173,7 @@ describe ApiController, "when using the API" do
"body" => "xxx"
}.to_json
- response.status.should == "500 Internal Server Error"
+ response.status.should == 500
ActiveSupport::JSON.decode(response.body)["errors"].should == [
"Request #{request_id} cannot be updated using the API"]
@@ -195,7 +195,7 @@ describe ApiController, "when using the API" do
"body" => "xxx"
}.to_json
- response.status.should == "500 Internal Server Error"
+ response.status.should == 500
ActiveSupport::JSON.decode(response.body)["errors"].should == [
"You do not own request #{request_id}"]
@@ -213,12 +213,12 @@ describe ApiController, "when using the API" do
"body" => "Are you joking, or are you serious?"
}.to_json,
:attachments => [
- fixture_file_upload("files/tfl.pdf")
+ fixture_file_upload("/files/tfl.pdf")
]
# Make sure it worked
- response.status.to_i.should == 500
+ response.status.should == 500
errors = ActiveSupport::JSON.decode(response.body)["errors"]
errors.should == ["You cannot attach files to messages in the 'request' direction"]
end
@@ -242,7 +242,7 @@ describe ApiController, "when using the API" do
"body" => response_body
}.to_json,
:attachments => [
- fixture_file_upload("files/tfl.pdf")
+ fixture_file_upload("/files/tfl.pdf")
]
# And make sure it worked
@@ -286,7 +286,7 @@ describe ApiController, "when using the API" do
:feed_type => "atom"
response.should be_success
- response.should render_template("api/request_events.atom")
+ response.should render_template("api/request_events")
assigns[:events].size.should > 0
assigns[:events].each do |event|
event.info_request.public_body.should == public_bodies(:geraldine_public_body)
@@ -341,7 +341,7 @@ describe ApiController, "when using the API" do
:feed_type => "atom"
response.should be_success
- response.should render_template("api/request_events.atom")
+ response.should render_template("api/request_events")
assigns[:events].size.should > 0
assigns[:events].each do |event|
event.created_at.should >= Date.new(2010, 1, 1)
@@ -360,7 +360,7 @@ describe ApiController, "when using the API" do
"sent_at" => sent_at,
"body" => response_body
}.to_json
- response.status.should == "404 Not Found"
+ response.status.should == 404
ActiveSupport::JSON.decode(response.body)["errors"].should == ["Could not find request 123459876"]
end
@@ -376,7 +376,7 @@ describe ApiController, "when using the API" do
"sent_at" => sent_at,
"body" => response_body
}.to_json
- response.status.should == "500 Internal Server Error"
+ response.status.should == 500
ActiveSupport::JSON.decode(response.body)["errors"].should == ["Request #{request_id} cannot be updated using the API"]
end
end
diff --git a/spec/controllers/comment_controller_spec.rb b/spec/controllers/comment_controller_spec.rb
index 4a7acee23..c03615ce2 100644
--- a/spec/controllers/comment_controller_spec.rb
+++ b/spec/controllers/comment_controller_spec.rb
@@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe CommentController, "when commenting on a request" do
- integrate_views
+ render_views
it "should give an error and render 'new' template when body text is just some whitespace" do
post :new, :url_title => info_requests(:naughty_chicken_request).url_title,
diff --git a/spec/controllers/general_controller_spec.rb b/spec/controllers/general_controller_spec.rb
index 642ed0e05..9a88dbc3a 100644
--- a/spec/controllers/general_controller_spec.rb
+++ b/spec/controllers/general_controller_spec.rb
@@ -12,7 +12,7 @@ describe GeneralController, "when trying to show the blog" do
it "should fail silently if the blog is returning an error" do
FakeWeb.register_uri(:get, %r|.*|, :body => "Error", :status => ["500", "Error"])
get :blog
- response.status.should == "200 OK"
+ response.status.should == 200
assigns[:blog_items].count.should == 0
end
end
@@ -20,13 +20,13 @@ end
describe GeneralController, 'when getting the blog feed' do
it 'should add a lang param correctly to a url with no querystring' do
- Configuration.stub!(:blog_feed).and_return("http://blog.example.com")
+ AlaveteliConfiguration.stub!(:blog_feed).and_return("http://blog.example.com")
get :blog
assigns[:feed_url].should == "http://blog.example.com?lang=en"
end
it 'should add a lang param correctly to a url with an existing querystring' do
- Configuration.stub!(:blog_feed).and_return("http://blog.example.com?alt=rss")
+ AlaveteliConfiguration.stub!(:blog_feed).and_return("http://blog.example.com?alt=rss")
get :blog
assigns[:feed_url].should == "http://blog.example.com?alt=rss&lang=en"
end
@@ -35,7 +35,7 @@ end
describe GeneralController, "when showing the frontpage" do
- integrate_views
+ render_views
before do
public_body = mock_model(PublicBody, :name => "Example Public Body",
@@ -58,14 +58,14 @@ describe GeneralController, "when showing the frontpage" do
it "should render the front page with default language" do
get :frontpage
- response.should have_tag('html[lang="en"]')
+ response.should have_selector('html[lang="en"]')
end
it "should render the front page with default language" do
old_default_locale = I18n.default_locale
I18n.default_locale = "es"
get :frontpage
- response.should have_tag('html[lang="es"]')
+ response.should have_selector('html[lang="es"]')
I18n.default_locale = old_default_locale
end
@@ -77,7 +77,7 @@ describe GeneralController, "when showing the frontpage" do
old_default_locale = I18n.default_locale
I18n.default_locale = "es"
get :frontpage
- response.should have_tag('html[lang="es"]')
+ response.should have_selector('html[lang="es"]')
I18n.default_locale = old_default_locale
end
@@ -87,7 +87,7 @@ describe GeneralController, "when showing the frontpage" do
accept_language = "es-ES,en-GB,en-US;q=0.8,en;q=0.6"
request.env['HTTP_ACCEPT_LANGUAGE'] = accept_language
get :frontpage
- response.should have_tag('html[lang="es"]')
+ response.should have_selector('html[lang="es"]')
request.env['HTTP_ACCEPT_LANGUAGE'] = nil
end
@@ -104,11 +104,11 @@ describe GeneralController, "when showing the frontpage" do
before do
@default_lang_home_link = /href=".*\/en\//
@other_lang_home_link = /href=".*\/es\//
- @old_include_default_locale_in_urls = Configuration::include_default_locale_in_urls
+ @old_include_default_locale_in_urls = AlaveteliConfiguration::include_default_locale_in_urls
end
def set_default_locale_in_urls(value)
- Configuration.stub!(:include_default_locale_in_urls).and_return(value)
+ AlaveteliConfiguration.stub!(:include_default_locale_in_urls).and_return(value)
load Rails.root.join("config/initializers/fast_gettext.rb")
end
@@ -120,13 +120,13 @@ describe GeneralController, "when showing the frontpage" do
it 'should generate URLs without a locale prepended' do
get :frontpage
- response.should_not have_text(@default_lang_home_link)
+ response.should_not contain @default_lang_home_link
end
it 'should render the front page in the default language when no locale param
is present and the session locale is not the default' do
get(:frontpage, {}, {:locale => 'es'})
- response.should_not have_text(@other_lang_home_link)
+ response.should_not contain @other_lang_home_link
end
end
@@ -134,7 +134,7 @@ describe GeneralController, "when showing the frontpage" do
INCLUDE_DEFAULT_LOCALE_IN_URLS is true' do
set_default_locale_in_urls(true)
get :frontpage
- response.should have_text(@default_lang_home_link)
+ response.body.should match /#{@default_lang_home_link}/
end
after do
@@ -150,28 +150,28 @@ describe GeneralController, "when showing the frontpage" do
it "should generate URLs with a locale prepended when there's more than one locale set" do
get :frontpage
- response.should have_text(home_link_regex)
+ response.body.should match home_link_regex
end
it "should use our test PO files rather than the application one" do
I18n.default_locale = :es
get :frontpage
- response.should have_text(/XOXO/)
+ response.body.should match /XOXO/
I18n.default_locale = :en
end
it "should generate URLs that include the locale when using one that includes an underscore" do
I18n.default_locale = :"en_GB"
get :frontpage
- response.should have_text(/href="\/en_GB\//)
+ response.body.should match /href="\/en_GB\//
I18n.default_locale = :en
end
it "should fall back to the language if the territory is unknown" do
I18n.default_locale = :"en_US"
get :frontpage
- response.should have_text(/href="\/en\//)
- response.should_not have_text(/href="\/en_US\//)
+ response.body.should match /href="\/en\//
+ response.body.should_not match /href="\/en_US\//
I18n.default_locale = :en
end
@@ -181,7 +181,7 @@ describe GeneralController, "when showing the frontpage" do
FastGettext.default_available_locales = I18n.available_locales = ['en']
get :frontpage
- response.should_not have_text(home_link_regex)
+ response.should_not contain home_link_regex
FastGettext.default_available_locales = old_fgt_available_locales
I18n.available_locales = old_i18n_available_locales
@@ -235,7 +235,7 @@ end
describe GeneralController, 'when using xapian search' do
- integrate_views
+ render_views
# rebuild xapian index after fixtures loaded
before(:each) do
@@ -249,7 +249,7 @@ describe GeneralController, 'when using xapian search' do
end
it "should find info request when searching for '\"fancy dog\"'" do
- get :search, :combined => ['"fancy dog"']
+ get :search, :combined => '"fancy dog"'
response.should render_template('search')
assigns[:xapian_requests].matches_estimated.should == 1
assigns[:xapian_requests].results.size.should == 1
@@ -259,7 +259,7 @@ describe GeneralController, 'when using xapian search' do
end
it "should find public body and incoming message when searching for 'geraldine quango'" do
- get :search, :combined => ['geraldine quango']
+ get :search, :combined => 'geraldine quango'
response.should render_template('search')
assigns[:xapian_requests].matches_estimated.should == 1
@@ -272,7 +272,7 @@ describe GeneralController, 'when using xapian search' do
end
it "should filter results based on end of URL being 'all'" do
- get :search, :combined => ['"bob"', "all"]
+ get :search, :combined => "bob/all"
assigns[:xapian_requests].results.map{|x| x[:model]}.should =~ [
info_request_events(:useless_outgoing_message_event),
info_request_events(:silly_outgoing_message_event),
@@ -284,14 +284,14 @@ describe GeneralController, 'when using xapian search' do
end
it "should filter results based on end of URL being 'users'" do
- get :search, :combined => ['"bob"', "users"]
+ get :search, :combined => "bob/users"
assigns[:xapian_requests].should == nil
assigns[:xapian_users].results.map{|x| x[:model]}.should == [users(:bob_smith_user)]
assigns[:xapian_bodies].should == nil
end
it "should filter results based on end of URL being 'requests'" do
- get :search, :combined => ['"bob"', "requests"]
+ get :search, :combined => "bob/requests"
assigns[:xapian_requests].results.map{|x|x[:model]}.should =~ [
info_request_events(:useless_outgoing_message_event),
info_request_events(:silly_outgoing_message_event),
@@ -303,7 +303,7 @@ describe GeneralController, 'when using xapian search' do
end
it "should filter results based on end of URL being 'bodies'" do
- get :search, :combined => ['"quango"', "bodies"]
+ get :search, :combined => "quango/bodies"
assigns[:xapian_requests].should == nil
assigns[:xapian_users].should == nil
assigns[:xapian_bodies].results.map{|x|x[:model]}.should == [public_bodies(:geraldine_public_body)]
@@ -317,7 +317,7 @@ describe GeneralController, 'when using xapian search' do
end
it "should not show unconfirmed users" do
- get :search, :combined => ["unconfirmed", "users"]
+ get :search, :combined => "unconfirmed/users"
response.should render_template('search')
assigns[:xapian_users].results.map{|x|x[:model]}.should == []
end
@@ -328,13 +328,13 @@ describe GeneralController, 'when using xapian search' do
u.save!
update_xapian_index
- get :search, :combined => ["unconfirmed", "users"]
+ get :search, :combined => "unconfirmed/users"
response.should render_template('search')
assigns[:xapian_users].results.map{|x|x[:model]}.should == [u]
end
it "should show tracking links for requests-only searches" do
- get :search, :combined => ['"bob"', "requests"]
+ get :search, :combined => "bob/requests"
response.body.should include('Track this search')
end
diff --git a/spec/controllers/help_controller_spec.rb b/spec/controllers/help_controller_spec.rb
index 28fd08c80..0f6f75eb9 100644
--- a/spec/controllers/help_controller_spec.rb
+++ b/spec/controllers/help_controller_spec.rb
@@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe HelpController, "when using help" do
- integrate_views
+ render_views
it "shows the about page" do
get :about
diff --git a/spec/controllers/public_body_controller_spec.rb b/spec/controllers/public_body_controller_spec.rb
index 5f4012737..22d8418c9 100644
--- a/spec/controllers/public_body_controller_spec.rb
+++ b/spec/controllers/public_body_controller_spec.rb
@@ -2,7 +2,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe PublicBodyController, "when showing a body" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -43,33 +43,28 @@ describe PublicBodyController, "when showing a body" do
:conditions => ["public_body_id = ?", public_bodies(:humpadink_public_body).id])
end
- it "should assign the body using different locale from that used for url_name" do
- PublicBody.with_locale(:es) do
- get :show, {:url_name => "dfh", :view => 'all'}
- assigns[:public_body].notes.should == "Baguette"
- end
+ it "should redirect to the canonical name in the chosen locale" do
+ get :show, {:url_name => "dfh", :view => 'all', :show_locale => "es"}
+ response.should redirect_to "http://test.host/es/body/edfh"
end
it "should assign the body using same locale as that used in url_name" do
- PublicBody.with_locale(:es) do
- get :show, {:url_name => "edfh", :view => 'all'}
- assigns[:public_body].notes.should == "Baguette"
- end
+ get :show, {:url_name => "edfh", :view => 'all', :show_locale => "es"}
+ response.should contain("Baguette")
end
it "should redirect use to the relevant locale even when url_name is for a different locale" do
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
get :show, {:url_name => "edfh", :view => 'all'}
response.should redirect_to "http://test.host/body/dfh"
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
end
it "should remember the filter (view) setting on redirecting" do
get :show, :show_locale => "es", :url_name => "tgq", :view => 'successful'
- response.should redirect_to show_public_body_successful_url(:url_name => "etgq")
+ response.should redirect_to 'http://test.host/es/body/etgq/successful'
end
it "should redirect to newest name if you use historic name of public body in URL" do
@@ -84,7 +79,7 @@ describe PublicBodyController, "when showing a body" do
end
describe PublicBodyController, "when listing bodies" do
- integrate_views
+ render_views
it "should be successful" do
get :list
@@ -92,7 +87,7 @@ describe PublicBodyController, "when listing bodies" do
end
it "should list all bodies from default locale, even when there are no translations for selected locale" do
- PublicBody.with_locale(:en) do
+ I18n.with_locale(:en) do
@english_only = PublicBody.new(:name => 'English only',
:short_name => 'EO',
:request_email => 'english@flourish.org',
@@ -100,7 +95,7 @@ describe PublicBodyController, "when listing bodies" do
:last_edit_comment => '')
@english_only.save
end
- PublicBody.with_locale(:es) do
+ I18n.with_locale(:es) do
get :list
assigns[:public_bodies].include?(@english_only).should == true
end
@@ -112,9 +107,12 @@ describe PublicBodyController, "when listing bodies" do
response.should render_template('list')
- assigns[:public_bodies].should == PublicBody.all(
- :conditions => "id <> #{PublicBody.internal_admin_body.id}",
- :order => "(select name from public_body_translations where public_body_id=public_bodies.id and locale='en')")
+ assigns[:public_bodies].should == [ public_bodies(:other_public_body),
+ public_bodies(:humpadink_public_body),
+ public_bodies(:forlorn_public_body),
+ public_bodies(:geraldine_public_body),
+ public_bodies(:sensible_walks_public_body),
+ public_bodies(:silly_walks_public_body) ]
assigns[:tag].should == "all"
assigns[:description].should == ""
end
@@ -152,11 +150,20 @@ describe PublicBodyController, "when listing bodies" do
get :list, :tag => "other"
response.should render_template('list')
- assigns[:public_bodies].should =~ PublicBody.all(:conditions => "id not in (#{public_bodies(:humpadink_public_body).id}, #{PublicBody.internal_admin_body.id})")
+ assigns[:public_bodies].should == [ public_bodies(:other_public_body),
+ public_bodies(:forlorn_public_body),
+ public_bodies(:geraldine_public_body),
+ public_bodies(:sensible_walks_public_body),
+ public_bodies(:silly_walks_public_body) ]
get :list
response.should render_template('list')
- assigns[:public_bodies].should =~ PublicBody.all(:conditions => "id <> #{PublicBody.internal_admin_body.id}")
+ assigns[:public_bodies].should == [ public_bodies(:other_public_body),
+ public_bodies(:humpadink_public_body),
+ public_bodies(:forlorn_public_body),
+ public_bodies(:geraldine_public_body),
+ public_bodies(:sensible_walks_public_body),
+ public_bodies(:silly_walks_public_body) ]
end
it "should list a machine tagged thing, should get it in both ways" do
@@ -198,7 +205,7 @@ end
describe PublicBodyController, "when doing type ahead searches" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
diff --git a/spec/controllers/request_controller_spec.rb b/spec/controllers/request_controller_spec.rb
index 672c2c361..4161f1118 100644
--- a/spec/controllers/request_controller_spec.rb
+++ b/spec/controllers/request_controller_spec.rb
@@ -2,7 +2,6 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe RequestController, "when listing recent requests" do
-
before(:each) do
load_raw_emails_data
get_fixtures_xapian_index
@@ -90,7 +89,7 @@ describe RequestController, "when listing recent requests" do
end
it "should assign the first page of results" do
- xap_results = mock_model(ActsAsXapian::Search,
+ xap_results = mock(ActsAsXapian::Search,
:results => (1..25).to_a.map { |m| { :model => m } },
:matches_estimated => 1000000)
@@ -103,7 +102,7 @@ describe RequestController, "when listing recent requests" do
end
it "should return 404 for pages we don't want to serve up" do
- xap_results = mock_model(ActsAsXapian::Search,
+ xap_results = mock(ActsAsXapian::Search,
:results => (1..25).to_a.map { |m| { :model => m } },
:matches_estimated => 1000000)
lambda {
@@ -120,10 +119,7 @@ describe RequestController, "when listing recent requests" do
end
describe RequestController, "when changing things that appear on the request page" do
-
- before do
- PurgeRequest.destroy_all
- end
+ render_views
it "should purge the downstream cache when mail is received" do
ir = info_requests(:fancy_dog_request)
@@ -189,7 +185,7 @@ describe RequestController, "when changing things that appear on the request pag
end
describe RequestController, "when showing one request" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -218,20 +214,20 @@ describe RequestController, "when showing one request" do
end
it "should redirect from a numeric URL to pretty one" do
- get :show, :url_title => info_requests(:naughty_chicken_request).id
+ get :show, :url_title => info_requests(:naughty_chicken_request).id.to_s
response.should redirect_to(:action => 'show', :url_title => info_requests(:naughty_chicken_request).url_title)
end
it 'should show actions the request owner can take' do
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.should have_tag('div#owner_actions')
+ response.should have_selector('div#owner_actions')
end
describe 'when the request does allow comments' do
it 'should have a comment link' do
get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' },
{ :user_id => users(:admin_user).id }
- response.should have_tag('#anyone_actions', /Add an annotation/)
+ response.should have_selector('#anyone_actions', :content => "Add an annotation")
end
end
@@ -239,7 +235,7 @@ describe RequestController, "when showing one request" do
it 'should not have a comment link' do
get :show, { :url_title => 'spam_1' },
{ :user_id => users(:admin_user).id }
- response.should_not have_tag('#anyone_actions', /Add an annotation/)
+ response.should_not have_selector('#anyone_actions', :content => "Add an annotation")
end
end
@@ -256,13 +252,13 @@ describe RequestController, "when showing one request" do
it 'should show the describe state form' do
get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' },
{ :user_id => users(:admin_user).id }
- response.should have_tag('div.describe_state_form')
+ response.should have_selector('div.describe_state_form')
end
it 'should ask the user to use the describe state from' do
get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' },
{ :user_id => users(:admin_user).id }
- response.should have_tag('p#request_status', :text => /answer the question above/)
+ response.should have_selector('p#request_status', :content => "answer the question above")
end
end
@@ -280,7 +276,7 @@ describe RequestController, "when showing one request" do
it 'should give a link to requesting an internal review' do
get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' },
{ :user_id => users(:admin_user).id }
- response.should have_tag('p#request_status', :text =>/requesting an internal review/)
+ response.should have_selector('p#request_status', :content => "requesting an internal review")
end
end
@@ -298,7 +294,7 @@ describe RequestController, "when showing one request" do
it 'should give a link to make a followup' do
get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' },
{ :user_id => users(:admin_user).id }
- response.should have_tag('p#request_status a', :text =>/send a follow up message/)
+ response.should have_selector('p#request_status a', :content => "send a follow up message")
end
end
@@ -315,7 +311,7 @@ describe RequestController, "when showing one request" do
it 'should not display actions the request owner can take' do
get :show, :url_title => 'balalas'
- response.should_not have_tag('div#owner_actions')
+ response.should_not have_selector('div#owner_actions')
end
end
@@ -341,12 +337,12 @@ describe RequestController, "when showing one request" do
it 'should not show the describe state form' do
make_request
- response.should_not have_tag('div.describe_state_form')
+ response.should_not have_selector('div.describe_state_form')
end
it 'should not ask the user to use the describe state form' do
make_request
- response.should_not have_tag('p#request_status', :text => /answer the question above/)
+ response.should_not have_selector('p#request_status', :content => "answer the question above")
end
end
@@ -363,7 +359,7 @@ describe RequestController, "when showing one request" do
it 'should not give a link to requesting an internal review' do
make_request
- response.should_not have_tag('p#request_status', :text =>/requesting an internal review/)
+ response.should_not have_selector('p#request_status', :content => "requesting an internal review")
end
end
@@ -379,12 +375,12 @@ describe RequestController, "when showing one request" do
it 'should not give a link to make a followup' do
make_request
- response.should_not have_tag('p#request_status a', :text =>/send a follow up message/)
+ response.should_not have_selector('p#request_status a', :content => "send a follow up message")
end
it 'should not give a link to sign in (in the request status paragraph)' do
make_request
- response.should_not have_tag('p#request_status a', :text => /sign in/)
+ response.should_not have_selector('p#request_status a', :content => "sign in")
end
end
@@ -447,7 +443,7 @@ describe RequestController, "when showing one request" do
describe 'when handling incoming mail' do
- integrate_views
+ render_views
it "should receive incoming messages, send email to creator, and show them" do
ir = info_requests(:fancy_dog_request)
@@ -481,13 +477,13 @@ describe RequestController, "when showing one request" do
(assigns[:info_request_events].size - size_before).should == 1
ir.reload
- get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello.txt', :skip_cache => 1
response.content_type.should == "text/plain"
- response.should have_text(/Second hello/)
+ response.should contain "Second hello"
- get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 3, :file_name => ['hello.txt'], :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 3, :file_name => 'hello.txt', :skip_cache => 1
response.content_type.should == "text/plain"
- response.should have_text(/First hello/)
+ response.should contain "First hello"
end
it 'should cache an attachment on a request with normal prominence' do
@@ -498,24 +494,23 @@ describe RequestController, "when showing one request" do
get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id,
:id => ir.id,
:part => 2,
- :file_name => ['hello.txt']
-
+ :file_name => 'hello.txt'
end
it "should convert message body to UTF8" do
ir = info_requests(:fancy_dog_request)
receive_incoming_mail('iso8859_2_raw_email.email', ir.incoming_email)
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.should have_text(/tënde/u)
+ response.should contain "tënde"
end
it "should generate valid HTML verson of plain text attachments" do
ir = info_requests(:fancy_dog_request)
receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
ir.reload
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello.txt.html', :skip_cache => 1
response.content_type.should == "text/html"
- response.should have_text(/Second hello/)
+ response.should contain "Second hello"
end
# This is a regression test for a bug where URLs of this form were causing 500 errors
@@ -534,11 +529,11 @@ describe RequestController, "when showing one request" do
ir.reload
ugly_id = "55195"
lambda {
- get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello.txt.html', :skip_cache => 1
}.should raise_error(ActiveRecord::RecordNotFound)
lambda {
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello.txt', :skip_cache => 1
}.should raise_error(ActiveRecord::RecordNotFound)
end
it "should return 404 when incoming message and request ids don't match" do
@@ -547,7 +542,7 @@ describe RequestController, "when showing one request" do
receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
ir.reload
lambda {
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => 'hello.txt.html', :skip_cache => 1
}.should raise_error(ActiveRecord::RecordNotFound)
end
it "should return 404 for ugly URLs contain a request id that isn't an integer, even if the integer prefix refers to an actual request" do
@@ -557,11 +552,11 @@ describe RequestController, "when showing one request" do
ugly_id = "%d95" % [info_requests(:naughty_chicken_request).id]
lambda {
- get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello.txt.html', :skip_cache => 1
}.should raise_error(ActiveRecord::RecordNotFound)
lambda {
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello.txt', :skip_cache => 1
}.should raise_error(ActiveRecord::RecordNotFound)
end
it "should return 404 when incoming message and request ids don't match" do
@@ -570,7 +565,7 @@ describe RequestController, "when showing one request" do
receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
ir.reload
lambda {
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => 'hello.txt.html', :skip_cache => 1
}.should raise_error(ActiveRecord::RecordNotFound)
end
@@ -578,9 +573,9 @@ describe RequestController, "when showing one request" do
ir = info_requests(:fancy_dog_request)
receive_incoming_mail('incoming-request-pdf-attachment.email', ir.incoming_email)
ir.reload
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['fs_50379341.pdf.html'], :skip_cache => 1
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'fs_50379341.pdf.html', :skip_cache => 1
response.content_type.should == "text/html"
- response.should have_text(/Walberswick Parish Council/)
+ response.should contain "Walberswick Parish Council"
end
it "should not cause a reparsing of the raw email, even when the result would be a 404" do
@@ -588,7 +583,7 @@ describe RequestController, "when showing one request" do
receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
ir.reload
attachment = IncomingMessage.get_attachment_by_url_part_number(ir.incoming_messages[1].get_attachments_for_display, 2)
- attachment.body.should have_text(/Second hello/)
+ attachment.body.should contain "Second hello"
# change the raw_email associated with the message; this only be reparsed when explicitly asked for
ir.incoming_messages[1].raw_email.data = ir.incoming_messages[1].raw_email.data.sub("Second", "Third")
@@ -596,23 +591,24 @@ describe RequestController, "when showing one request" do
# in a 404 for browsing users. This shouldn't cause a
# re-parse...
lambda {
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.baz.html'], :skip_cache => 1
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello.txt.baz.html', :skip_cache => 1
}.should raise_error(ActiveRecord::RecordNotFound)
attachment = IncomingMessage.get_attachment_by_url_part_number(ir.incoming_messages[1].get_attachments_for_display, 2)
- attachment.body.should have_text(/Second hello/)
+ attachment.body.should contain "Second hello"
# ...nor should asking for it by its correct filename...
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1
- response.should_not have_text(/Third hello/)
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello.txt.html', :skip_cache => 1
+ response.should_not contain "Third hello"
# ...but if we explicitly ask for attachments to be extracted, then they should be
force = true
ir.incoming_messages[1].parse_raw_email!(force)
+ ir.reload
attachment = IncomingMessage.get_attachment_by_url_part_number(ir.incoming_messages[1].get_attachments_for_display, 2)
- attachment.body.should have_text(/Second hello/)
- get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1
- response.should have_text(/Third hello/)
+ attachment.body.should contain "Third hello"
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello.txt.html', :skip_cache => 1
+ response.should contain "Third hello"
end
it "should treat attachments with unknown extensions as binary" do
@@ -620,9 +616,9 @@ describe RequestController, "when showing one request" do
receive_incoming_mail('incoming-request-attachment-unknown-extension.email', ir.incoming_email)
ir.reload
- get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.qwglhm'], :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello.qwglhm', :skip_cache => 1
response.content_type.should == "application/octet-stream"
- response.should have_text(/an unusual sort of file/)
+ response.should contain "an unusual sort of file"
end
it "should not download attachments with wrong file name" do
@@ -631,7 +627,7 @@ describe RequestController, "when showing one request" do
lambda {
get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2,
- :file_name => ['http://trying.to.hack']
+ :file_name => 'http://trying.to.hack'
}.should raise_error(ActiveRecord::RecordNotFound)
end
@@ -648,9 +644,9 @@ describe RequestController, "when showing one request" do
begin
receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
- get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello.txt', :skip_cache => 1
response.content_type.should == "text/plain"
- response.should have_text(/xxxxxx hello/)
+ response.should contain "xxxxxx hello"
ensure
ir.censor_rules.clear
end
@@ -670,9 +666,9 @@ describe RequestController, "when showing one request" do
receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
ir.reload
- get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello.txt', :skip_cache => 1
response.content_type.should == "text/plain"
- response.should have_text(/xxxxxx hello/)
+ response.should contain "xxxxxx hello"
ensure
ir.user.censor_rules.clear
end
@@ -694,11 +690,13 @@ describe RequestController, "when showing one request" do
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
assert assigns[:info_request].info_request_events[3].incoming_message.get_attachments_for_display.count == 2
# the issue is that the info_request_events have got cached on them the old info_requests.
- # where i'm at: trying to replace those fields that got re-read from the raw email. however tests are failing in very strange ways. currently I don't appear to be getting any attachments parsed in at all when in the template (see "*****" in _correspondence.rhtml) but do when I'm in the code.
+ # where i'm at: trying to replace those fields that got re-read from the raw email. however tests are failing in very strange ways. currently I don't appear to be getting any attachments parsed in at all when in the template (see "*****" in _correspondence.html.erb) but do when I'm in the code.
# so at this point, assigns[:info_request].incoming_messages[1].get_attachments_for_display is returning stuff, but the equivalent thing in the template isn't.
# but something odd is that the above is return a whole load of attachments which aren't there in the controller
- response.body.should have_tag("p.attachment strong", /hello.txt/m)
+ response.body.should have_selector("p.attachment strong") do |s|
+ s.should contain /hello.txt/m
+ end
censor_rule = CensorRule.new()
censor_rule.text = "hello.txt"
@@ -708,7 +706,9 @@ describe RequestController, "when showing one request" do
ir.censor_rules << censor_rule
begin
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.body.should have_tag("p.attachment strong", /goodbye.txt/m)
+ response.body.should have_selector("p.attachment strong") do |s|
+ s.should contain /goodbye.txt/m
+ end
ensure
ir.censor_rules.clear
end
@@ -731,17 +731,17 @@ describe RequestController, "when showing one request" do
ir = info_requests(:fancy_dog_request)
session[:user_id] = ir.user.id # bob_smith_user
get :download_entire_request, :url_title => title
- assigns[:url_path].should have_text(/#{title}.zip$/)
+ assigns[:url_path].should contain /#{title}.zip$/
old_path = assigns[:url_path]
- response.location.should have_text(/#{assigns[:url_path]}$/)
+ response.location.should contain /#{assigns[:url_path]}$/
zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", old_path)) { |zipfile|
zipfile.count.should == 1 # just the message
}
receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
get :download_entire_request, :url_title => title
- assigns[:url_path].should have_text(/#{title}.zip$/)
+ assigns[:url_path].should contain /#{title}.zip$/
old_path = assigns[:url_path]
- response.location.should have_text(/#{assigns[:url_path]}$/)
+ response.location.should contain /#{assigns[:url_path]}$/
zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", old_path)) { |zipfile|
zipfile.count.should == 3 # the message plus two "hello.txt" files
}
@@ -752,9 +752,9 @@ describe RequestController, "when showing one request" do
sleep 1
receive_incoming_mail('incoming-request-attachment-unknown-extension.email', ir.incoming_email)
get :download_entire_request, :url_title => title
- assigns[:url_path].should have_text(/#{title}.zip$/)
+ assigns[:url_path].should contain /#{title}.zip$/
assigns[:url_path].should_not == old_path
- response.location.should have_text(/#{assigns[:url_path]}/)
+ response.location.should contain assigns[:url_path]
zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", assigns[:url_path])) { |zipfile|
zipfile.count.should == 4 # the message, two hello.txt plus the unknown attachment
}
@@ -764,14 +764,13 @@ describe RequestController, "when showing one request" do
info_request = info_requests(:external_request)
get :download_entire_request, { :url_title => info_request.url_title },
{ :user_id => users(:bob_smith_user) }
- response.location.should have_text(/#{assigns[:url_path]}$/)
+ response.location.should contain /#{assigns[:url_path]}$/
end
end
end
end
describe RequestController, "when changing prominence of a request" do
-
before(:each) do
load_raw_emails_data
end
@@ -853,14 +852,14 @@ describe RequestController, "when changing prominence of a request" do
:part => 2,
:skip_cache => 1
response.content_type.should == "text/html"
- response.should_not have_text(/Second hello/)
+ response.should_not contain "Second hello"
response.should render_template('request/hidden')
get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id,
:id => ir.id,
:part => 3,
:skip_cache => 1
response.content_type.should == "text/html"
- response.should_not have_text(/First hello/)
+ response.should_not contain "First hello"
response.should render_template('request/hidden')
response.code.should == '410'
end
@@ -876,7 +875,7 @@ describe RequestController, "when changing prominence of a request" do
get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id,
:id => ir.id,
:part => 2,
- :file_name => ['hello.txt']
+ :file_name => 'hello.txt'
end.should raise_error(ActiveRecord::RecordNotFound)
end
@@ -891,7 +890,7 @@ describe RequestController, "when changing prominence of a request" do
get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id,
:id => ir.id,
:part => 2,
- :file_name => ['hello.txt']
+ :file_name => 'hello.txt'
end.should raise_error(ActiveRecord::RecordNotFound)
end
@@ -904,7 +903,6 @@ end
# end
describe RequestController, "when searching for an authority" do
-
# Whether or not sign-in is required for this step is configurable,
# so we make sure we're logged in, just in case
before do
@@ -920,6 +918,8 @@ describe RequestController, "when searching for an authority" do
end
it "should return matching bodies" do
+ get_fixtures_xapian_index
+
session[:user_id] = @user.id
get :select_authority, :query => "Quango"
@@ -944,7 +944,7 @@ describe RequestController, "when searching for an authority" do
end
describe RequestController, "when creating a new request" do
- integrate_views
+ render_views
before do
@user = users(:bob_smith_user)
@@ -1036,7 +1036,7 @@ describe RequestController, "when creating a new request" do
response.should redirect_to show_new_request_url(:url_title => ir.url_title)
# This test uses an explicit path because it's relied in
# Google Analytics goals:
- response.redirected_to.should =~ /request\/why_is_your_quango_called_gerald\/new$/
+ response.redirect_url.should =~ /request\/why_is_your_quango_called_gerald\/new$/
end
it "should give an error if the same request is submitted twice" do
@@ -1180,7 +1180,7 @@ describe RequestController, "when making a new request" do
end
describe RequestController, "when viewing an individual response for reply/followup" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -1201,7 +1201,7 @@ describe RequestController, "when viewing an individual response for reply/follo
it "should offer the opportunity to reply to the main address" do
session[:user_id] = users(:bob_smith_user).id
get :show_response, :id => info_requests(:fancy_dog_request).id, :incoming_message_id => incoming_messages(:useless_incoming_message)
- response.body.should have_tag("div#other_recipients ul li", /the main FOI contact address for/)
+ response.body.should have_selector("div#other_recipients ul li", :content => "the main FOI contact address for")
end
it "should offer an opportunity to reply to another address" do
@@ -1211,7 +1211,7 @@ describe RequestController, "when viewing an individual response for reply/follo
ir.save!
receive_incoming_mail('incoming-request-plain.email', ir.incoming_email, "Frob <frob@bonce.com>")
get :show_response, :id => ir.id, :incoming_message_id => incoming_messages(:useless_incoming_message)
- response.body.should have_tag("div#other_recipients ul li", /Frob/)
+ response.body.should have_selector("div#other_recipients ul li", :content => "Frob")
end
it "should not show individual responses if request hidden, even if request owner" do
@@ -1295,7 +1295,9 @@ describe RequestController, "when classifying an information request" do
before do
@dog_request.stub!(:is_old_unclassified?).and_return(true)
- RequestMailer.stub!(:deliver_old_unclassified_updated)
+ mail_mock = mock("mail")
+ mail_mock.stub(:deliver)
+ RequestMailer.stub!(:old_unclassified_updated).and_return(mail_mock)
end
describe 'when the user is not logged in' do
@@ -1332,7 +1334,7 @@ describe RequestController, "when classifying an information request" do
end
it 'should send an email to the requester letting them know someone has updated the status of their request' do
- RequestMailer.should_receive(:deliver_old_unclassified_updated)
+ RequestMailer.should_receive(:old_unclassified_updated)
post_status('rejected')
end
@@ -1364,7 +1366,7 @@ describe RequestController, "when classifying an information request" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.from_addrs.first.to_s.should == users(:silly_name_user).name_and_email
+ mail.from_addrs.first.to_s.should == users(:silly_name_user).email
end
end
end
@@ -1403,7 +1405,9 @@ describe RequestController, "when classifying an information request" do
end
it 'should send an email to the requester letting them know someone has updated the status of their request' do
- RequestMailer.should_receive(:deliver_old_unclassified_updated)
+ mail_mock = mock("mail")
+ mail_mock.stub :deliver
+ RequestMailer.should_receive(:old_unclassified_updated).and_return(mail_mock)
post_status('rejected')
end
@@ -1442,7 +1446,7 @@ describe RequestController, "when classifying an information request" do
end
it 'should not send an email to the requester letting them know someone has updated the status of their request' do
- RequestMailer.should_not_receive(:deliver_old_unclassified_updated)
+ RequestMailer.should_not_receive(:old_unclassified_updated)
post_status('rejected')
end
@@ -1499,7 +1503,7 @@ describe RequestController, "when classifying an information request" do
end
it 'should not send an email to the requester letting them know someone has updated the status of their request' do
- RequestMailer.should_not_receive(:deliver_old_unclassified_updated)
+ RequestMailer.should_not_receive(:old_unclassified_updated)
post_status('rejected')
end
@@ -1562,11 +1566,10 @@ describe RequestController, "when classifying an information request" do
@dog_request = info_requests(:fancy_dog_request)
@dog_request.stub!(:each).and_return([@dog_request])
InfoRequest.stub!(:find).and_return(@dog_request)
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
end
after do
- ActionController::Routing::Routes.filters = @old_filters
+ RoutingFilter.active = true
end
def request_url
@@ -1670,7 +1673,7 @@ describe RequestController, "when classifying an information request" do
end
describe RequestController, "when sending a followup message" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -1723,7 +1726,7 @@ describe RequestController, "when sending a followup message" do
deliveries.size.should == 1
mail = deliveries[0]
mail.body.should =~ /What a useless response! You suck./
- mail.to_addrs.first.to_s.should == "FOI Person <foiperson@localhost>"
+ mail.to_addrs.first.to_s.should == "foiperson@localhost"
response.should redirect_to(:action => 'show', :url_title => info_requests(:fancy_dog_request).url_title)
@@ -1752,7 +1755,7 @@ end
# it can't check the URLs in the emails I don't think, ugh.
describe RequestController, "sending overdue request alerts" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -1770,9 +1773,9 @@ describe RequestController, "sending overdue request alerts" do
mail = chicken_mails[0]
mail.body.should =~ /promptly, as normally/
- mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email
+ mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.email
- mail.body =~ /(http:\/\/.*\/c\/(.*))/
+ mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/
mail_url = $1
mail_token = $2
@@ -1799,7 +1802,7 @@ describe RequestController, "sending overdue request alerts" do
mail = chicken_mails[0]
mail.body.should =~ /promptly, as normally/
- mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email
+ mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.email
end
it "should send not actually send the overdue alert if the user is banned but should
@@ -1827,9 +1830,9 @@ describe RequestController, "sending overdue request alerts" do
mail = chicken_mails[0]
mail.body.should =~ /required by law/
- mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email
+ mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.email
- mail.body =~ /(http:\/\/.*\/c\/(.*))/
+ mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/
mail_url = $1
mail_token = $2
@@ -1897,7 +1900,7 @@ describe RequestController, "sending overdue request alerts" do
end
describe RequestController, "sending unclassified new response reminder alerts" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -1910,8 +1913,8 @@ describe RequestController, "sending unclassified new response reminder alerts"
deliveries.size.should == 3 # sufficiently late it sends reminders too
mail = deliveries[0]
mail.body.should =~ /To let everyone know/
- mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email
- mail.body =~ /(http:\/\/.*\/c\/(.*))/
+ mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email
+ mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/
mail_url = $1
mail_token = $2
@@ -1927,7 +1930,7 @@ describe RequestController, "sending unclassified new response reminder alerts"
end
describe RequestController, "clarification required alerts" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
end
@@ -1946,8 +1949,8 @@ describe RequestController, "clarification required alerts" do
deliveries.size.should == 1
mail = deliveries[0]
mail.body.should =~ /asked you to explain/
- mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email
- mail.body =~ /(http:\/\/.*\/c\/(.*))/
+ mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email
+ mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/
mail_url = $1
mail_token = $2
@@ -1980,7 +1983,7 @@ describe RequestController, "clarification required alerts" do
end
describe RequestController, "comment alerts" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
end
@@ -1999,8 +2002,8 @@ describe RequestController, "comment alerts" do
deliveries = ActionMailer::Base.deliveries
mail = deliveries[0]
mail.body.should =~ /has annotated your/
- mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email
- mail.body =~ /(http:\/\/.*)/
+ mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email
+ mail.body.to_s =~ /(http:\/\/.*)/
mail_url = $1
mail_url.should match("/request/why_do_you_have_such_a_fancy_dog#comment-#{new_comment.id}")
@@ -2049,8 +2052,8 @@ describe RequestController, "comment alerts" do
deliveries.size.should == 1
mail = deliveries[0]
mail.body.should =~ /There are 2 new annotations/
- mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email
- mail.body =~ /(http:\/\/.*)/
+ mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email
+ mail.body.to_s =~ /(http:\/\/.*)/
mail_url = $1
mail_url.should match("/request/why_do_you_have_such_a_fancy_dog#comment-#{comments(:silly_comment).id}")
@@ -2059,7 +2062,7 @@ describe RequestController, "comment alerts" do
end
describe RequestController, "when viewing comments" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
end
@@ -2067,22 +2070,26 @@ describe RequestController, "when viewing comments" do
it "should link to the user who submitted it" do
session[:user_id] = users(:bob_smith_user).id
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.body.should have_tag("div#comment-1 h2", /Silly.*left an annotation/m)
- response.body.should_not have_tag("div#comment-1 h2", /You.*left an annotation/m)
+ response.body.should have_selector("div#comment-1 h2") do |s|
+ s.should contain /Silly.*left an annotation/m
+ s.should_not contain /You.*left an annotation/m
+ end
end
it "should link to the user who submitted to it, even if it is you" do
session[:user_id] = users(:silly_name_user).id
get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.body.should have_tag("div#comment-1 h2", /Silly.*left an annotation/m)
- response.body.should_not have_tag("div#comment-1 h2", /You.*left an annotation/m)
+ response.body.should have_selector("div#comment-1 h2") do |s|
+ s.should contain /Silly.*left an annotation/m
+ s.should_not contain /You.*left an annotation/m
+ end
end
end
describe RequestController, "authority uploads a response from the web interface" do
- integrate_views
+ render_views
before(:each) do
# domain after the @ is used for authentication of FOI officers, so to test it
@@ -2120,7 +2127,7 @@ describe RequestController, "authority uploads a response from the web interface
session[:user_id] = @normal_user.id
# post up a photo of the parrot
- parrot_upload = fixture_file_upload('files/parrot.png','image/png')
+ parrot_upload = fixture_file_upload('/files/parrot.png','image/png')
post :upload_response, :url_title => 'why_do_you_have_such_a_fancy_dog',
:body => "Find attached a picture of a parrot",
:file_1 => parrot_upload,
@@ -2148,7 +2155,7 @@ describe RequestController, "authority uploads a response from the web interface
session[:user_id] = @foi_officer_user.id
# post up a photo of the parrot
- parrot_upload = fixture_file_upload('files/parrot.png','image/png')
+ parrot_upload = fixture_file_upload('/files/parrot.png','image/png')
post :upload_response, :url_title => 'why_do_you_have_such_a_fancy_dog',
:body => "Find attached a picture of a parrot",
:file_1 => parrot_upload,
@@ -2172,7 +2179,6 @@ describe RequestController, "authority uploads a response from the web interface
end
describe RequestController, "when showing JSON version for API" do
-
before(:each) do
load_raw_emails_data
end
@@ -2191,25 +2197,28 @@ describe RequestController, "when showing JSON version for API" do
end
describe RequestController, "when doing type ahead searches" do
+ render_views
- integrate_views
+ before :each do
+ get_fixtures_xapian_index
+ end
it "should return nothing for the empty query string" do
get :search_typeahead, :q => ""
- response.should render_template('request/_search_ahead.rhtml')
+ response.should render_template('request/_search_ahead')
assigns[:xapian_requests].should be_nil
end
it "should return a request matching the given keyword, but not users with a matching description" do
get :search_typeahead, :q => "chicken"
- response.should render_template('request/_search_ahead.rhtml')
+ response.should render_template('request/_search_ahead')
assigns[:xapian_requests].results.size.should == 1
assigns[:xapian_requests].results[0][:model].title.should == info_requests(:naughty_chicken_request).title
end
it "should return all requests matching any of the given keywords" do
get :search_typeahead, :q => "money dog"
- response.should render_template('request/_search_ahead.rhtml')
+ response.should render_template('request/_search_ahead')
assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ [
info_requests(:fancy_dog_request),
info_requests(:naughty_chicken_request),
@@ -2219,13 +2228,13 @@ describe RequestController, "when doing type ahead searches" do
it "should not return matches for short words" do
get :search_typeahead, :q => "a"
- response.should render_template('request/_search_ahead.rhtml')
+ response.should render_template('request/_search_ahead')
assigns[:xapian_requests].should be_nil
end
it "should do partial matches for longer words" do
get :search_typeahead, :q => "chick"
- response.should render_template('request/_search_ahead.rhtml')
+ response.should render_template('request/_search_ahead')
assigns[:xapian_requests].results.size.should ==1
end
@@ -2250,7 +2259,7 @@ describe RequestController, "when doing type ahead searches" do
end
describe RequestController, "when showing similar requests" do
- integrate_views
+ render_views
it "should work" do
get :similar, :url_title => info_requests(:badger_request).url_title
@@ -2259,6 +2268,8 @@ describe RequestController, "when showing similar requests" do
end
it "should show similar requests" do
+ get_fixtures_xapian_index
+
badger_request = info_requests(:badger_request)
get :similar, :url_title => badger_request.url_title
@@ -2292,7 +2303,7 @@ describe RequestController, "when reporting a request when not logged in" do
end
describe RequestController, "when reporting a request (logged in)" do
- integrate_views
+ render_views
before do
@user = users(:robin_user)
@@ -2368,7 +2379,6 @@ describe RequestController, "when reporting a request (logged in)" do
end
describe RequestController, "when caching fragments" do
-
it "should not fail with long filenames" do
long_name = "blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah.txt"
info_request = mock(InfoRequest, :user_can_view? => true,
@@ -2384,7 +2394,7 @@ describe RequestController, "when caching fragments" do
IncomingMessage.stub!(:find).with("44").and_return(incoming_message)
IncomingMessage.stub!(:get_attachment_by_url_part_number).and_return(attachment)
InfoRequest.stub!(:find).with("132").and_return(info_request)
- params = { :file_name => [long_name],
+ params = { :file_name => long_name,
:controller => "request",
:action => "get_attachment_as_html",
:id => "132",
diff --git a/spec/controllers/services_controller_spec.rb b/spec/controllers/services_controller_spec.rb
index a9950d520..399f48acb 100644
--- a/spec/controllers/services_controller_spec.rb
+++ b/spec/controllers/services_controller_spec.rb
@@ -4,7 +4,7 @@ require 'fakeweb'
describe ServicesController, "when returning a message for people in other countries" do
- integrate_views
+ render_views
# store and restore the locale in the context of the test suite to isolate
# changes made in these tests
@@ -54,27 +54,27 @@ describe ServicesController, "when returning a message for people in other count
it "should return the 'another country' message if the service responds OK" do
config = MySociety::Config.load_default()
config['ISO_COUNTRY_CODE'] = "DE"
- Configuration.stub!(:gaze_url).and_return('http://denmark.com')
+ AlaveteliConfiguration.stub!(:gaze_url).and_return('http://denmark.com')
FakeWeb.register_uri(:get, %r|denmark.com|, :body => "DK")
get :other_country_message
response.should be_success
response.body.should == 'Hello! We have an <a href="/help/alaveteli?country_name=Deutschland">important message</a> for visitors outside Deutschland <span class="close-button">X</span>'
end
it "should default to no message if the country_from_ip domain doesn't exist" do
- Configuration.stub!(:gaze_url).and_return('http://12123sdf14qsd.com')
+ AlaveteliConfiguration.stub!(:gaze_url).and_return('http://12123sdf14qsd.com')
get :other_country_message
response.should be_success
response.body.should == ''
end
it "should default to no message if the country_from_ip service doesn't exist" do
- Configuration.stub!(:gaze_url).and_return('http://www.google.com')
+ AlaveteliConfiguration.stub!(:gaze_url).and_return('http://www.google.com')
get :other_country_message
response.should be_success
response.body.should == ''
end
it "should default to no message if the country_from_ip service returns an error" do
FakeWeb.register_uri(:get, %r|500.com|, :body => "Error", :status => ["500", "Error"])
- Configuration.stub!(:gaze_url).and_return('http://500.com')
+ AlaveteliConfiguration.stub!(:gaze_url).and_return('http://500.com')
get :other_country_message
response.should be_success
response.body.should == ''
diff --git a/spec/controllers/track_controller_spec.rb b/spec/controllers/track_controller_spec.rb
index 5505afe59..e9501b1ed 100644
--- a/spec/controllers/track_controller_spec.rb
+++ b/spec/controllers/track_controller_spec.rb
@@ -49,14 +49,14 @@ describe TrackController, "when making a new track on a request" do
it "should save a search track and redirect to the right place" do
session[:user_id] = @user.id
@track_thing.should_receive(:save!)
- get :track_search_query, :query_array => ["bob variety:sent"], :feed => 'track'
+ get :track_search_query, :query_array => "bob variety:sent", :feed => 'track'
response.should redirect_to(:controller => 'general', :action => 'search', :combined => ["bob", "requests"])
end
end
describe TrackController, "when sending alerts for a track" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -65,8 +65,7 @@ describe TrackController, "when sending alerts for a track" do
it "should send alerts" do
# Don't do clever locale-insertion-unto-URL stuff
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
# set the time the comment event happened at to within the last week
ire = info_request_events(:silly_comment_event)
@@ -80,7 +79,7 @@ describe TrackController, "when sending alerts for a track" do
mail = deliveries[0]
mail.body.should =~ /Alter your subscription/
mail.to_addrs.first.to_s.should include(users(:silly_name_user).email)
- mail.body =~ /(http:\/\/.*\/c\/(.*))/
+ mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/
mail_url = $1
mail_token = $2
@@ -114,7 +113,7 @@ describe TrackController, "when sending alerts for a track" do
deliveries.size.should == 0
# Restore the routing filters
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
end
it "should send localised alerts" do
@@ -133,7 +132,7 @@ describe TrackController, "when sending alerts for a track" do
end
describe TrackController, "when viewing RSS feed for a track" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -163,7 +162,7 @@ end
describe TrackController, "when viewing JSON version of a track feed" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
@@ -205,7 +204,7 @@ end
describe TrackController, "when tracking a public body" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
diff --git a/spec/controllers/user_controller_spec.rb b/spec/controllers/user_controller_spec.rb
index 23006803b..a18554114 100644
--- a/spec/controllers/user_controller_spec.rb
+++ b/spec/controllers/user_controller_spec.rb
@@ -5,7 +5,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
# http://rspec.rubyforge.org/rspec-rails/1.1.12/classes/Spec/Rails/Example/ControllerExampleGroup.html
describe UserController, "when showing a user" do
- integrate_views
+ render_views
before(:each) do
load_raw_emails_data
get_fixtures_xapian_index
@@ -64,7 +64,7 @@ describe UserController, "when showing a user" do
end
describe UserController, "when signing in" do
- integrate_views
+ render_views
def get_last_postredirect
post_redirects = PostRedirect.find_by_sql("select * from post_redirects order by id desc limit 1")
@@ -74,7 +74,7 @@ describe UserController, "when signing in" do
it "should show sign in / sign up page" do
get :signin
- response.should have_tag("input#signin_token")
+ response.should have_selector("input#signin_token")
end
it "should create post redirect to / when you just go to /signin" do
@@ -100,8 +100,7 @@ describe UserController, "when signing in" do
end
it "should log in when you give right email/password, and redirect to where you were" do
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
get :signin, :r => "/list"
response.should render_template('sign')
@@ -112,14 +111,13 @@ describe UserController, "when signing in" do
session[:user_id].should == users(:bob_smith_user).id
# response doesn't contain /en/ but redirect_to does...
response.should redirect_to(:controller => 'request', :action => 'list', :post_redirect => 1)
- response.should_not send_email
+ ActionMailer::Base.deliveries.should be_empty
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
end
it "should not log you in if you use an invalid PostRedirect token, and shouldn't give 500 error either" do
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
post_redirect = "something invalid"
lambda {
@@ -132,7 +130,7 @@ describe UserController, "when signing in" do
response.should render_template('sign')
assigns[:post_redirect].should == nil
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
end
# No idea how to test this in the test framework :(
@@ -152,12 +150,11 @@ describe UserController, "when signing in" do
:token => post_redirect.token
}
response.should render_template('confirm')
- response.should send_email
+ ActionMailer::Base.deliveries.should_not be_empty
end
it "should confirm your email, log you in and redirect you to where you were after you click an email link" do
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
get :signin, :r => "/list"
post_redirect = get_last_postredirect
@@ -165,19 +162,19 @@ describe UserController, "when signing in" do
post :signin, { :user_signin => { :email => 'unconfirmed@localhost', :password => 'jonespassword' },
:token => post_redirect.token
}
- response.should send_email
+ ActionMailer::Base.deliveries.should_not be_empty
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.body =~ /(http:\/\/.*(\/c\/(.*)))/
+ mail.body.to_s =~ /(http:\/\/.*(\/c\/(.*)))/
mail_url = $1
mail_path = $2
mail_token = $3
# check is right confirmation URL
mail_token.should == post_redirect.email_token
- params_from(:get, mail_path).should == { :controller => 'user', :action => 'confirm', :email_token => mail_token }
+ Rails.application.routes.recognize_path(mail_path).should == { :controller => 'user', :action => 'confirm', :email_token => mail_token }
# check confirmation URL works
session[:user_id].should be_nil
@@ -185,12 +182,11 @@ describe UserController, "when signing in" do
session[:user_id].should == users(:unconfirmed_user).id
response.should redirect_to(:controller => 'request', :action => 'list', :post_redirect => 1)
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
end
it "should keep you logged in if you click a confirmation link and are already logged in as an admin" do
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
get :signin, :r => "/list"
post_redirect = get_last_postredirect
@@ -198,19 +194,19 @@ describe UserController, "when signing in" do
post :signin, { :user_signin => { :email => 'unconfirmed@localhost', :password => 'jonespassword' },
:token => post_redirect.token
}
- response.should send_email
+ ActionMailer::Base.deliveries.should_not be_empty
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.body =~ /(http:\/\/.*(\/c\/(.*)))/
+ mail.body.to_s =~ /(http:\/\/.*(\/c\/(.*)))/
mail_url = $1
mail_path = $2
mail_token = $3
# check is right confirmation URL
mail_token.should == post_redirect.email_token
- params_from(:get, mail_path).should == { :controller => 'user', :action => 'confirm', :email_token => mail_token }
+ Rails.application.routes.recognize_path(mail_path).should == { :controller => 'user', :action => 'confirm', :email_token => mail_token }
# Log in as an admin
session[:user_id] = users(:admin_user).id
@@ -222,19 +218,19 @@ describe UserController, "when signing in" do
# And the redirect should still work, of course
response.should redirect_to(:controller => 'request', :action => 'list', :post_redirect => 1)
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
end
end
describe UserController, "when signing up" do
- integrate_views
+ render_views
it "should be an error if you type the password differently each time" do
post :signup, { :user_signup => { :email => 'new@localhost', :name => 'New Person',
:password => 'sillypassword', :password_confirmation => 'sillypasswordtwo' }
}
- assigns[:user_signup].errors[:password].should == 'Please enter the same password twice'
+ assigns[:user_signup].errors[:password].should == ['Please enter the same password twice']
end
it "should be an error to sign up with a misformatted email" do
@@ -285,7 +281,7 @@ describe UserController, "when signing up" do
end
describe UserController, "when signing out" do
- integrate_views
+ render_views
it "should log you out and redirect to the home page" do
session[:user_id] = users(:bob_smith_user).id
@@ -295,21 +291,20 @@ describe UserController, "when signing out" do
end
it "should log you out and redirect you to where you were" do
- old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
session[:user_id] = users(:bob_smith_user).id
get :signout, :r => '/list'
session[:user_id].should be_nil
response.should redirect_to(:controller => 'request', :action => 'list')
- ActionController::Routing::Routes.filters = old_filters
+ RoutingFilter.active = true
end
end
describe UserController, "when sending another user a message" do
- integrate_views
+ render_views
it "should redirect to signin page if you go to the contact form and aren't signed in" do
get :contact, :id => users(:silly_name_user)
@@ -337,16 +332,16 @@ describe UserController, "when sending another user a message" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.body.should include("Bob Smith has used #{Configuration::site_name} to send you the message below")
+ mail.body.should include("Bob Smith has used #{AlaveteliConfiguration::site_name} to send you the message below")
mail.body.should include("Just a test!")
#mail.to_addrs.first.to_s.should == users(:silly_name_user).name_and_email # XXX fix some nastiness with quoting name_and_email
- mail.from_addrs.first.to_s.should == users(:bob_smith_user).name_and_email
+ mail.from_addrs.first.to_s.should == users(:bob_smith_user).email
end
end
describe UserController, "when changing password" do
- integrate_views
+ render_views
it "should show the email form when not logged in" do
get :signchangepassword
@@ -386,7 +381,7 @@ describe UserController, "when changing password" do
post :signchangepassword, { :user => { :password => 'ooo', :password_confirmation => 'ooo' },
:submitted_signchangepassword_do => 1
}
- users(:bob_smith_user).hashed_password.should != old_hash
+ users(:bob_smith_user).reload.hashed_password.should_not == old_hash
response.should redirect_to(:controller => 'user', :action => 'show', :url_name => users(:bob_smith_user).url_name)
end
@@ -416,7 +411,7 @@ describe UserController, "when changing password" do
end
describe UserController, "when changing email address" do
- integrate_views
+ render_views
it "should require login" do
get :signchangeemail
@@ -500,10 +495,10 @@ describe UserController, "when changing email address" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.body.should include("confirm that you want to change")
+ mail.body.should include("confirm that you want to \nchange")
mail.to.should == [ 'newbob@localhost' ]
- mail.body =~ /(http:\/\/.*(\/c\/(.*)))/
+ mail.body.to_s =~ /(http:\/\/.*(\/c\/(.*)))/
mail_url = $1
mail_path = $2
mail_token = $3
@@ -561,16 +556,13 @@ describe UserController, "when changing email address" do
end
describe UserController, "when using profile photos" do
- integrate_views
+ render_views
before do
@user = users(:bob_smith_user)
- @uploadedfile = File.open(file_fixture_name("parrot.png"))
- @uploadedfile.stub!(:original_filename).and_return('parrot.png')
-
- @uploadedfile_2 = File.open(file_fixture_name("parrot.jpg"))
- @uploadedfile_2.stub!(:original_filename).and_return('parrot.jpg')
+ @uploadedfile = fixture_file_upload("/files/parrot.png")
+ @uploadedfile_2 = fixture_file_upload("/files/parrot.jpg")
end
it "should not let you change profile photo if you're not logged in as the user" do
@@ -631,7 +623,7 @@ describe UserController, "when showing JSON version for API" do
end
describe UserController, "when viewing the wall" do
- integrate_views
+ render_views
before(:each) do
get_fixtures_xapian_index
diff --git a/spec/fixtures/foi_attachments.yml b/spec/fixtures/foi_attachments.yml
deleted file mode 100644
index 8b1378917..000000000
--- a/spec/fixtures/foi_attachments.yml
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/spec/fixtures/theme_views/core/application_mailer/core_only.rhtml b/spec/fixtures/theme_views/core/application_mailer/core_only.html.erb
index 53b7798ec..53b7798ec 100644
--- a/spec/fixtures/theme_views/core/application_mailer/core_only.rhtml
+++ b/spec/fixtures/theme_views/core/application_mailer/core_only.html.erb
diff --git a/spec/fixtures/theme_views/core/application_mailer/multipart_core_only.rhtml b/spec/fixtures/theme_views/core/application_mailer/multipart_core_only.html.erb
index 646a349f8..646a349f8 100644
--- a/spec/fixtures/theme_views/core/application_mailer/multipart_core_only.rhtml
+++ b/spec/fixtures/theme_views/core/application_mailer/multipart_core_only.html.erb
diff --git a/spec/fixtures/theme_views/core/application_mailer/simple.rhtml b/spec/fixtures/theme_views/core/application_mailer/simple.html.erb
index a3937c940..a3937c940 100644
--- a/spec/fixtures/theme_views/core/application_mailer/simple.rhtml
+++ b/spec/fixtures/theme_views/core/application_mailer/simple.html.erb
diff --git a/spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.rhtml b/spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.html.erb
index d6423fbb4..d6423fbb4 100644
--- a/spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.rhtml
+++ b/spec/fixtures/theme_views/theme_one/application_mailer/multipart_theme_only.html.erb
diff --git a/spec/fixtures/theme_views/theme_one/application_mailer/simple.rhtml b/spec/fixtures/theme_views/theme_one/application_mailer/simple.html.erb
index ad43e0c87..ad43e0c87 100644
--- a/spec/fixtures/theme_views/theme_one/application_mailer/simple.rhtml
+++ b/spec/fixtures/theme_views/theme_one/application_mailer/simple.html.erb
diff --git a/spec/fixtures/theme_views/theme_one/application_mailer/theme_only.rhtml b/spec/fixtures/theme_views/theme_one/application_mailer/theme_only.html.erb
index 865445815..865445815 100644
--- a/spec/fixtures/theme_views/theme_one/application_mailer/theme_only.rhtml
+++ b/spec/fixtures/theme_views/theme_one/application_mailer/theme_only.html.erb
diff --git a/spec/helpers/link_to_helper_spec.rb b/spec/helpers/link_to_helper_spec.rb
index 3e997f9f9..4cc1d415b 100644
--- a/spec/helpers/link_to_helper_spec.rb
+++ b/spec/helpers/link_to_helper_spec.rb
@@ -8,11 +8,10 @@ describe LinkToHelper do
before do
@mock_request = mock_model(InfoRequest, :url_title => 'test_title')
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
+ RoutingFilter.active = false
end
after do
- ActionController::Routing::Routes.filters = @old_filters
+ RoutingFilter.active = true
end
diff --git a/spec/integration/admin_spec.rb b/spec/integration/admin_spec.rb
index e148ea3ca..8a5e59ba2 100644
--- a/spec/integration/admin_spec.rb
+++ b/spec/integration/admin_spec.rb
@@ -13,7 +13,7 @@ describe "When administering the site" do
# Now fetch the "log in as" link to log in as Bob
get_via_redirect "/admin/user/login_as/#{users(:bob_smith_user).id}", nil, {
- "Authorization" => "Basic " + Base64.encode64("#{Configuration::admin_username}:#{Configuration::admin_password}").strip
+ "Authorization" => "Basic " + Base64.encode64("#{AlaveteliConfiguration::admin_username}:#{AlaveteliConfiguration::admin_password}").strip
}
response.should be_success
session[:user_id].should == users(:bob_smith_user).id
diff --git a/spec/integration/errors_spec.rb b/spec/integration/errors_spec.rb
index a44ed7051..edf570182 100644
--- a/spec/integration/errors_spec.rb
+++ b/spec/integration/errors_spec.rb
@@ -4,26 +4,14 @@ describe "When rendering errors" do
before(:each) do
load_raw_emails_data
- ActionController::Base.consider_all_requests_local = false
end
- after(:each) do
- ActionController::Base.consider_all_requests_local = true
- end
-
- it "should render a 404 for unrouteable URLs" do
- get("/frobsnasm")
- response.body.should include("The page doesn't exist")
- response.code.should == "404"
- end
it "should render a 404 for users that don't exist" do
get("/user/wobsnasm")
- response.body.should include("The page doesn't exist")
response.code.should == "404"
end
it "should render a 404 for bodies that don't exist" do
get("/body/wobsnasm")
- response.body.should include("The page doesn't exist")
response.code.should == "404"
end
it "should render a 500 for general errors" do
@@ -46,7 +34,6 @@ describe "When rendering errors" do
end
it "should render a 404 for non-existent 'details' pages for requests" do
get("/details/request/wobble" )
- response.body.should include("The page doesn't exist")
response.code.should == "404"
end
end
diff --git a/spec/integration/search_request_spec.rb b/spec/integration/search_request_spec.rb
index c564032a6..23a62e97b 100644
--- a/spec/integration/search_request_spec.rb
+++ b/spec/integration/search_request_spec.rb
@@ -13,10 +13,8 @@ describe "When searching" do
end
it "should redirect requests with search in query string to URL-based page" do
- url = '/search/all?query=bob'
- request_via_redirect("post", url)
- response.request.url.should_not include(url)
- response.request.url.should include("/search/bob/all")
+ post '/search/all?query=bob'
+ response.should redirect_to "/en/search/bob/all"
end
it "should correctly execute simple search" do
diff --git a/spec/lib/mail_handler/mail_handler_spec.rb b/spec/lib/mail_handler/mail_handler_spec.rb
index 48c32e2bc..79b779687 100644
--- a/spec/lib/mail_handler/mail_handler_spec.rb
+++ b/spec/lib/mail_handler/mail_handler_spec.rb
@@ -22,7 +22,7 @@ describe 'when creating a mail object from raw data' do
it 'should convert an iso8859 email to utf8' do
mail = get_fixture_mail('iso8859_2_raw_email.email')
- mail.subject.should have_text(/gjatë/u)
+ mail.subject.should match /gjatë/u
MailHandler.get_part_body(mail).is_utf8?.should == true
end
diff --git a/spec/lib/sendmail_return_path_spec.rb b/spec/lib/sendmail_return_path_spec.rb
index 137869b6e..83436c2bd 100644
--- a/spec/lib/sendmail_return_path_spec.rb
+++ b/spec/lib/sendmail_return_path_spec.rb
@@ -1,5 +1,10 @@
# This is a test of the monkey patches in sendmail_return_path.rb
+# In Rails 3 the monkeypatches are not needed anymore because sendmail now has the "-f" flag
+# set correctly. So, strictly these tests are testing the Rails internals. So, that means we really
+# should delete them. Let's do that later when things have settled down. For the time being leave
+# them in
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe "when sending email with an altered return path" do
@@ -28,10 +33,10 @@ describe "when sending email with an altered return path" do
Net::SMTP.stub!(:new).and_return(mock_smtp)
with_delivery_method :smtp do
- ContactMailer.deliver_to_admin_message(
+ ContactMailer.to_admin_message(
"Mr. Test", "test@localhost", "Test script spec/lib/sendmail_return_path_spec.rb",
"This is just a test for a test script", nil, nil, nil
- )
+ ).deliver
end
deliveries = ActionMailer::Base.deliveries
@@ -40,12 +45,12 @@ describe "when sending email with an altered return path" do
it "should set the return path when sending email using sendmail" do
with_stub_popen do
- IO.should_receive(:popen).once.with('/usr/sbin/sendmail -i -t -f "test@localhost"', "w+")
+ IO.should_receive(:popen).once.with('/usr/sbin/sendmail -i -t -f "test@localhost" postmaster@localhost', "w+")
with_delivery_method :sendmail do
- ContactMailer.deliver_to_admin_message(
+ ContactMailer.to_admin_message(
"Mr. Test", "test@localhost", "Test script spec/lib/sendmail_return_path_spec.rb",
"This is just a test for a test script", nil, nil, nil
- )
+ ).deliver
end
end
diff --git a/spec/lib/timezone_fixes_spec.rb b/spec/lib/timezone_fixes_spec.rb
index 9d6ade526..8a9a3bf31 100644
--- a/spec/lib/timezone_fixes_spec.rb
+++ b/spec/lib/timezone_fixes_spec.rb
@@ -3,6 +3,11 @@
# We use MailServerLogDone here just as a totally random model that has a datetime type.
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+# In Rails 3 the monkeypatch that these tests are testing is not necessary. So,
+# since these tests are testing the Rails internals you could argue that they shouldn't
+# be here. Well, you're right. But let's leave them in for the time being until the upgrade is finished.
+# Then, we should probably delete this whole file
+
describe "when doing things with timezones" do
it "should preserve time objects with local time conversion to default timezone UTC
diff --git a/spec/models/application_mailer_spec.rb b/spec/mailers/application_mailer_spec.rb
index acf5f43bc..d8993f78f 100644
--- a/spec/models/application_mailer_spec.rb
+++ b/spec/mailers/application_mailer_spec.rb
@@ -8,8 +8,7 @@ describe ApplicationMailer do
def set_base_views
ApplicationMailer.class_eval do
@previous_view_paths = self.view_paths.dup
- self.view_paths.clear
- self.view_paths << File.join(Rails.root, 'spec', 'fixtures', 'theme_views', 'core')
+ self.view_paths = [File.join(Rails.root, 'spec', 'fixtures', 'theme_views', 'core')]
end
end
@@ -27,13 +26,13 @@ describe ApplicationMailer do
def prepend_theme_views(theme_name)
ApplicationMailer.class_eval do
- view_paths.unshift File.join(Rails.root, 'spec', 'fixtures', 'theme_views', theme_name)
+ prepend_view_path File.join(Rails.root, 'spec', 'fixtures', 'theme_views', theme_name)
end
end
def append_theme_views(theme_name)
ApplicationMailer.class_eval do
- view_paths << File.join(Rails.root, 'spec', 'fixtures', 'theme_views', theme_name)
+ append_view_path File.join(Rails.root, 'spec', 'fixtures', 'theme_views', theme_name)
end
end
@@ -45,11 +44,8 @@ describe ApplicationMailer do
def create_multipart_method(method_name)
ApplicationMailer.send(:define_method, method_name) do
- attachment :content_type => 'message/rfc822',
- :body => 'xxx',
- :filename => "original.eml",
- :transfer_encoding => '7bit',
- :content_disposition => 'inline'
+ attachments['original.eml'] = 'xxx'
+ mail
end
end
@@ -62,32 +58,32 @@ describe ApplicationMailer do
it 'should render a theme template in preference to a core template' do
prepend_theme_views('theme_one')
- @mail = ApplicationMailer.create_simple()
+ @mail = ApplicationMailer.simple
@mail.body.should match('Theme simple')
end
it 'should render the template provided by the theme if no template is available in core' do
prepend_theme_views('theme_one')
- @mail = ApplicationMailer.create_theme_only()
+ @mail = ApplicationMailer.theme_only
@mail.body.should match('Theme only')
end
it 'should render the template provided by core if there is no theme template' do
prepend_theme_views('theme_one')
- @mail = ApplicationMailer.create_core_only()
+ @mail = ApplicationMailer.core_only
@mail.body.should match('Core only')
end
- it 'should raise an error if the template is in neither core nor theme' do
+ it 'should render an empty body if the template is in neither core nor theme' do
prepend_theme_views('theme_one')
- expected_error = 'Missing template application_mailer/neither.erb in view path'
- lambda{ ApplicationMailer.create_neither() }.should raise_error(/#{expected_error}/)
+ @mail = ApplicationMailer.neither
+ @mail.body.should be_empty
end
it 'should render a multipart email using a theme template' do
prepend_theme_views('theme_one')
create_multipart_method('multipart_theme_only')
- @mail = ApplicationMailer.create_multipart_theme_only()
+ @mail = ApplicationMailer.multipart_theme_only
@mail.parts.size.should == 2
message_part = @mail.parts[0].to_s
message_part.should match("Theme multipart")
@@ -96,7 +92,7 @@ describe ApplicationMailer do
it 'should render a multipart email using a core template' do
prepend_theme_views('theme_one')
create_multipart_method('multipart_core_only')
- @mail = ApplicationMailer.create_multipart_core_only()
+ @mail = ApplicationMailer.multipart_core_only
@mail.parts.size.should == 2
message_part = @mail.parts[0].to_s
message_part.should match("Core multipart")
@@ -108,32 +104,32 @@ describe ApplicationMailer do
it 'should render a core template in preference to a theme template' do
append_theme_views('theme_one')
- @mail = ApplicationMailer.create_simple()
+ @mail = ApplicationMailer.simple
@mail.body.should match('Core simple')
end
it 'should render the template provided by the theme if no template is available in core' do
append_theme_views('theme_one')
- @mail = ApplicationMailer.create_theme_only()
+ @mail = ApplicationMailer.theme_only
@mail.body.should match('Theme only')
end
it 'should render the template provided by core if there is no theme template' do
append_theme_views('theme_one')
- @mail = ApplicationMailer.create_core_only()
+ @mail = ApplicationMailer.core_only
@mail.body.should match('Core only')
end
- it 'should raise an error if the template is in neither core nor theme' do
+ it 'should render an empty body if the template is in neither core nor theme' do
append_theme_views('theme_one')
- expected_error = 'Missing template application_mailer/neither.erb in view path'
- lambda{ ApplicationMailer.create_neither() }.should raise_error(/#{expected_error}/)
+ @mail = ApplicationMailer.neither
+ @mail.body.should be_empty
end
it 'should render a multipart email using a core template' do
append_theme_views('theme_one')
create_multipart_method('multipart_core_only')
- @mail = ApplicationMailer.create_multipart_core_only()
+ @mail = ApplicationMailer.multipart_core_only
@mail.parts.size.should == 2
message_part = @mail.parts[0].to_s
message_part.should match("Core multipart")
@@ -142,7 +138,7 @@ describe ApplicationMailer do
it 'should render a multipart email using a theme template' do
append_theme_views('theme_one')
create_multipart_method('multipart_theme_only')
- @mail = ApplicationMailer.create_multipart_theme_only()
+ @mail = ApplicationMailer.multipart_theme_only
@mail.parts.size.should == 2
message_part = @mail.parts[0].to_s
message_part.should match("Theme multipart")
diff --git a/spec/models/outgoing_mailer_spec.rb b/spec/mailers/outgoing_mailer_spec.rb
index 5d1ea2dfb..5d1ea2dfb 100644
--- a/spec/models/outgoing_mailer_spec.rb
+++ b/spec/mailers/outgoing_mailer_spec.rb
diff --git a/spec/models/request_mailer_spec.rb b/spec/mailers/request_mailer_spec.rb
index 40133eedc..23806b35b 100644
--- a/spec/models/request_mailer_spec.rb
+++ b/spec/mailers/request_mailer_spec.rb
@@ -34,7 +34,7 @@ describe RequestMailer, " when receiving incoming mail" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.to.should == [ Configuration::contact_email ]
+ mail.to.should == [ AlaveteliConfiguration::contact_email ]
deliveries.clear
end
@@ -54,7 +54,7 @@ describe RequestMailer, " when receiving incoming mail" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.to.should == [ Configuration::contact_email ]
+ mail.to.should == [ AlaveteliConfiguration::contact_email ]
deliveries.clear
end
@@ -74,7 +74,7 @@ describe RequestMailer, " when receiving incoming mail" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.to.should == [ Configuration::contact_email ]
+ mail.to.should == [ AlaveteliConfiguration::contact_email ]
deliveries.clear
end
@@ -99,7 +99,7 @@ describe RequestMailer, " when receiving incoming mail" do
mail.multipart?.should == true
mail.parts.size.should == 2
message_part = mail.parts[0].to_s
- bounced_mail = MailHandler.mail_from_raw_email(mail.parts[1].body)
+ bounced_mail = MailHandler.mail_from_raw_email(mail.parts[1].body.to_s)
bounced_mail.to.should == [ ir.incoming_email ]
bounced_mail.from.should == [ 'geraldinequango@localhost' ]
bounced_mail.body.include?("That's so totally a rubbish question").should be_true
@@ -160,7 +160,7 @@ describe RequestMailer, " when receiving incoming mail" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
- mail.to.should == [ Configuration::contact_email ]
+ mail.to.should == [ AlaveteliConfiguration::contact_email ]
deliveries.clear
end
@@ -212,7 +212,9 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
:url_title => 'test_title',
:user => @mock_user)
InfoRequest.stub!(:find).and_return([@mock_request])
- RequestMailer.stub!(:deliver_new_response_reminder_alert)
+ mail_mock = mock("mail")
+ mail_mock.stub(:deliver)
+ RequestMailer.stub(:new_response_reminder_alert).and_return(mail_mock)
@sent_alert = mock_model(UserInfoRequestSentAlert, :user= =>nil,
:info_request= => nil,
:alert_type= => nil,
@@ -244,7 +246,7 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
query_params[:conditions].should == expected_conditions
query_params[:include].should == [ :user ]
query_params[:order].should == 'info_requests.id'
- end
+ end.and_return [@mock_request]
send_alerts
end
@@ -269,7 +271,7 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
end
it 'should not send the reminder' do
- RequestMailer.should_not_receive(:deliver_new_response_reminder_alert)
+ RequestMailer.should_not_receive(:new_response_reminder_alert)
send_alerts
end
@@ -293,7 +295,7 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
end
it 'should send the reminder' do
- RequestMailer.should_receive(:deliver_new_response_reminder_alert)
+ RequestMailer.should_receive(:new_response_reminder_alert)
send_alerts
end
end
@@ -311,7 +313,7 @@ describe RequestMailer, 'when sending mail when someone has updated an old uncla
:public_body => @public_body,
:display_status => 'Refused.',
:url_title => 'test_request')
- @mail = RequestMailer.create_old_unclassified_updated(@info_request)
+ @mail = RequestMailer.old_unclassified_updated(@info_request)
end
it 'should have the subject "Someone has updated the status of your request"' do
@@ -344,7 +346,7 @@ describe RequestMailer, 'when sending a new response email' do
end
it 'should not error when sending mails requests with characters requiring quoting in the subject' do
- @mail = RequestMailer.create_new_response(@info_request, @incoming_message)
+ @mail = RequestMailer.new_response(@info_request, @incoming_message)
end
end
@@ -362,13 +364,13 @@ describe RequestMailer, 'requires_admin' do
end
it 'body should contain the full admin URL' do
- mail = RequestMailer.deliver_requires_admin(@info_request)
+ mail = RequestMailer.requires_admin(@info_request).deliver
mail.body.should include('http://test.host/en/admin/request/show/123')
end
it "body should contain the message from the user" do
- mail = RequestMailer.deliver_requires_admin(@info_request, nil, "Something has gone wrong")
+ mail = RequestMailer.requires_admin(@info_request, nil, "Something has gone wrong").deliver
mail.body.should include 'Something has gone wrong'
end
diff --git a/spec/models/track_mailer_spec.rb b/spec/mailers/track_mailer_spec.rb
index 97f12b8f5..9537e6b14 100644
--- a/spec/models/track_mailer_spec.rb
+++ b/spec/mailers/track_mailer_spec.rb
@@ -5,7 +5,9 @@ describe TrackMailer do
describe 'when sending email alerts for tracked things' do
before do
- TrackMailer.stub!(:deliver_event_digest)
+ mail_mock = mock("mail")
+ mail_mock.stub(:deliver)
+ TrackMailer.stub!(:event_digest).and_return(mail_mock)
Time.stub!(:now).and_return(Time.utc(2007, 11, 12, 23, 59))
end
@@ -79,21 +81,21 @@ describe TrackMailer do
sent_email = mock_model(TrackThingsSentEmail, :info_request_event_id => @found_event.id)
@track_things_sent_emails_array.stub!(:find).and_return([sent_email]) # this is for the date range find (created in last 14 days)
@xapian_search.stub!(:results).and_return([@search_result])
- TrackMailer.should_not_receive(:deliver_event_digest)
+ TrackMailer.should_not_receive(:event_digest)
TrackMailer.alert_tracks
end
it 'should not include in the email any events not sent in a previous tracking email that were described before the track was set up' do
@found_event.stub!(:described_at).and_return(@track_thing.created_at - 1.day)
@xapian_search.stub!(:results).and_return([@search_result])
- TrackMailer.should_not_receive(:deliver_event_digest)
+ TrackMailer.should_not_receive(:event_digest)
TrackMailer.alert_tracks
end
it 'should include in the email any events that the user has not been sent a tracking email on that have been described since the track was set up' do
@found_event.stub!(:described_at).and_return(@track_thing.created_at + 1.day)
@xapian_search.stub!(:results).and_return([@search_result])
- TrackMailer.should_receive(:deliver_event_digest)
+ TrackMailer.should_receive(:event_digest)
TrackMailer.alert_tracks
end
@@ -129,7 +131,7 @@ describe TrackMailer do
it 'should not ask for any daily track things for the user' do
expected_conditions = [ "tracking_user_id = ? and track_medium = ?", @user.id, 'email_daily' ]
- TrackThing.should_not_receive(:find).with(:all, :conditions => expected_conditions).and_return([])
+ TrackThing.should_not_receive(:find).with(:all, :conditions => expected_conditions)
TrackMailer.alert_tracks
end
@@ -137,7 +139,7 @@ describe TrackMailer do
@user.stub(:should_be_emailed?).and_return(true)
@user.stub(:receive_email_alerts).and_return(false)
expected_conditions = [ "tracking_user_id = ? and track_medium = ?", @user.id, 'email_daily' ]
- TrackThing.should_not_receive(:find).with(:all, :conditions => expected_conditions).and_return([])
+ TrackThing.should_not_receive(:find).with(:all, :conditions => expected_conditions)
TrackMailer.alert_tracks
end
@@ -169,7 +171,7 @@ describe TrackMailer do
:name_and_email => MailHandler.address_from_name_and_email('Tippy Test', 'tippy@localhost'),
:url_name => 'tippy_test'
)
- TrackMailer.deliver_event_digest(@user, []) # no items in it email for minimal test
+ TrackMailer.event_digest(@user, []).deliver # no items in it email for minimal test
end
it 'should deliver one email, with right headers' do
@@ -194,15 +196,15 @@ describe TrackMailer do
# Force SSL is off in the tests. Since the code that selectively switches the protocols
# is in the initialiser for Rails it's hard to test. Hmmm...
# We could Configuration.stub!(:force_ssl).and_return(true) but the config/environment.rb
- # wouldn't get reloaded
+ # wouldn't get reloaded
it "should have http links in the email" do
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
-
- mail.body.should include("http://")
- mail.body.should_not include("https://")
+
+ mail.body.should include("http://")
+ mail.body.should_not include("https://")
end
end
end
diff --git a/spec/models/censor_rule_spec.rb b/spec/models/censor_rule_spec.rb
index c11b05a03..3782cc630 100644
--- a/spec/models/censor_rule_spec.rb
+++ b/spec/models/censor_rule_spec.rb
@@ -73,10 +73,10 @@ end
describe 'when validating rules' do
- describe 'should be invalid without text' do
+ it 'should be invalid without text' do
censor_rule = CensorRule.new
censor_rule.valid?.should == false
- censor_rule.errors.on(:text).should == "can't be blank"
+ censor_rule.errors[:text].should == ["can't be blank"]
end
describe 'when validating a regexp rule' do
@@ -96,7 +96,7 @@ describe 'when validating rules' do
it 'should add an error message to the text field with the regexp error message' do
Regexp.stub!(:new).and_raise(RegexpError.new("very bad regexp"))
@censor_rule.valid?.should == false
- @censor_rule.errors.on(:text).should == "very bad regexp"
+ @censor_rule.errors[:text].should == ["very bad regexp"]
end
end
@@ -106,7 +106,7 @@ describe 'when validating rules' do
it 'should not add any error message to the text field' do
Regexp.stub!(:new)
@censor_rule.valid?
- @censor_rule.errors.on(:text).should == nil
+ @censor_rule.errors[:text].should == []
end
end
@@ -134,15 +134,21 @@ describe 'when validating rules' do
it 'should not allow a global text censor rule (without user_id, request_id or public_body_id)' do
@censor_rule.valid?.should == false
- @expected_error = 'Censor must apply to an info request a user or a body; is invalid'
- @censor_rule.errors.full_messages.should == [@expected_error]
+
+ expected_error = ["Rule must apply to an info request, a user or a body"]
+ @censor_rule.errors[:user].should == expected_error
+ @censor_rule.errors[:info_request].should == expected_error
+ @censor_rule.errors[:public_body].should == expected_error
end
it 'should not allow a global regex censor rule (without user_id, request_id or public_body_id)' do
@censor_rule.regexp = true
@censor_rule.valid?.should == false
- @expected_error = 'Censor must apply to an info request a user or a body; is invalid'
- @censor_rule.errors.full_messages.should == [@expected_error]
+
+ expected_error = ["Rule must apply to an info request, a user or a body"]
+ @censor_rule.errors[:user].should == expected_error
+ @censor_rule.errors[:info_request].should == expected_error
+ @censor_rule.errors[:public_body].should == expected_error
end
end
diff --git a/spec/models/contact_mailer_spec.rb b/spec/models/contact_mailer_spec.rb
deleted file mode 100644
index 202e45758..000000000
--- a/spec/models/contact_mailer_spec.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
-
-describe ContactMailer, " when blah" do
- before do
- end
-end
-
-
diff --git a/spec/models/incoming_message_spec.rb b/spec/models/incoming_message_spec.rb
index f53a5856a..e22235298 100644
--- a/spec/models/incoming_message_spec.rb
+++ b/spec/models/incoming_message_spec.rb
@@ -27,7 +27,7 @@ describe IncomingMessage, " when dealing with incoming mail" do
end
it "should correctly fold various types of footer" do
- Dir.glob(File.join(Spec::Runner.configuration.fixture_path, "files", "email-folding-example-*.txt")).each do |file|
+ Dir.glob(File.join(RSpec.configuration.fixture_path, "files", "email-folding-example-*.txt")).each do |file|
message = File.read(file)
parsed = IncomingMessage.remove_quoted_sections(message)
expected = File.read("#{file}.expected")
@@ -353,7 +353,7 @@ describe IncomingMessage, " when censoring data" do
end
it "should apply hard-coded privacy rules to HTML files" do
- data = "http://#{Configuration::domain}/c/cheese"
+ data = "http://#{AlaveteliConfiguration::domain}/c/cheese"
@im.html_mask_stuff!(data)
data.should == "[WDTK login link]"
end
@@ -405,6 +405,7 @@ describe IncomingMessage, " when uudecoding bad messages" do
im.stub!(:mail).and_return(mail)
im.extract_attachments!
+ im.reload
attachments = im.foi_attachments
attachments.size.should == 2
attachments[1].filename.should == 'moo.txt'
diff --git a/spec/models/info_request_event_spec.rb b/spec/models/info_request_event_spec.rb
index 796f8b840..842246fd8 100644
--- a/spec/models/info_request_event_spec.rb
+++ b/spec/models/info_request_event_spec.rb
@@ -21,7 +21,7 @@ describe InfoRequestEvent do
:event_type => 'sent',
:params => {})
event.should_receive(:xapian_mark_needs_index)
- event.run_callbacks(:after_save)
+ event.run_callbacks(:save)
end
end
diff --git a/spec/models/info_request_spec.rb b/spec/models/info_request_spec.rb
index 728a538f9..3eb88b2bb 100644
--- a/spec/models/info_request_spec.rb
+++ b/spec/models/info_request_spec.rb
@@ -426,8 +426,8 @@ describe InfoRequest do
before do
Time.stub!(:now).and_return(Time.utc(2007, 11, 9, 23, 59))
- @mock_comment_event = safe_mock_model(InfoRequestEvent, :created_at => Time.now - 23.days, :event_type => 'comment', :response? => false)
- @mock_response_event = safe_mock_model(InfoRequestEvent, :created_at => Time.now - 22.days, :event_type => 'response', :response? => true)
+ @mock_comment_event = mock_model(InfoRequestEvent, :created_at => Time.now - 23.days, :event_type => 'comment', :response? => false)
+ @mock_response_event = mock_model(InfoRequestEvent, :created_at => Time.now - 22.days, :event_type => 'response', :response? => true)
@info_request = InfoRequest.new(:prominence => 'normal',
:awaiting_description => true,
:info_request_events => [@mock_response_event, @mock_comment_event])
@@ -457,16 +457,16 @@ describe InfoRequest do
describe 'when applying censor rules' do
before do
- @global_rule = safe_mock_model(CensorRule, :apply_to_text! => nil,
+ @global_rule = mock_model(CensorRule, :apply_to_text! => nil,
:apply_to_binary! => nil)
- @user_rule = safe_mock_model(CensorRule, :apply_to_text! => nil,
+ @user_rule = mock_model(CensorRule, :apply_to_text! => nil,
:apply_to_binary! => nil)
- @request_rule = safe_mock_model(CensorRule, :apply_to_text! => nil,
+ @request_rule = mock_model(CensorRule, :apply_to_text! => nil,
:apply_to_binary! => nil)
- @body_rule = safe_mock_model(CensorRule, :apply_to_text! => nil,
+ @body_rule = mock_model(CensorRule, :apply_to_text! => nil,
:apply_to_binary! => nil)
- @user = safe_mock_model(User, :censor_rules => [@user_rule])
- @body = safe_mock_model(PublicBody, :censor_rules => [@body_rule])
+ @user = mock_model(User, :censor_rules => [@user_rule])
+ @body = mock_model(PublicBody, :censor_rules => [@body_rule])
@info_request = InfoRequest.new(:prominence => 'normal',
:awaiting_description => true,
:title => 'title')
diff --git a/spec/models/mail_server_log_spec.rb b/spec/models/mail_server_log_spec.rb
index d0a1d202f..2b44a4559 100644
--- a/spec/models/mail_server_log_spec.rb
+++ b/spec/models/mail_server_log_spec.rb
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe MailServerLog do
describe ".load_file" do
before :each do
- Configuration.stub!(:incoming_email_domain).and_return("example.com")
+ AlaveteliConfiguration.stub!(:incoming_email_domain).and_return("example.com")
File.stub_chain(:stat, :mtime).and_return(DateTime.new(2012, 10, 10))
end
@@ -64,8 +64,8 @@ describe MailServerLog do
describe ".email_addresses_on_line" do
before :each do
- Configuration.stub!(:incoming_email_domain).and_return("example.com")
- Configuration.stub!(:incoming_email_prefix).and_return("foi+")
+ AlaveteliConfiguration.stub!(:incoming_email_domain).and_return("example.com")
+ AlaveteliConfiguration.stub!(:incoming_email_prefix).and_return("foi+")
end
it "recognises a single incoming email" do
@@ -106,7 +106,7 @@ describe MailServerLog do
# Postfix logs for a single email go over multiple lines. They are all tied together with the Queue ID.
# See http://onlamp.com/onlamp/2004/01/22/postfix.html
it "loads the postfix log and untangles seperate email transactions using the queue ID" do
- Configuration.stub!(:incoming_email_domain).and_return("example.com")
+ AlaveteliConfiguration.stub!(:incoming_email_domain).and_return("example.com")
log.stub!(:rewind)
ir1 = info_requests(:fancy_dog_request)
ir2 = info_requests(:naughty_chicken_request)
@@ -135,7 +135,7 @@ describe MailServerLog do
describe ".scan_for_postfix_queue_ids" do
it "returns the queue ids of interest with the connected email addresses" do
- Configuration.stub!(:incoming_email_domain).and_return("example.com")
+ AlaveteliConfiguration.stub!(:incoming_email_domain).and_return("example.com")
MailServerLog.scan_for_postfix_queue_ids(log).should == {
"CB55836EE58C" => ["request-14-e0e09f97@example.com"],
"9634B16F7F7" => ["request-10-1234@example.com"]
diff --git a/spec/models/public_body_spec.rb b/spec/models/public_body_spec.rb
index c2e0a6353..bc693b4da 100644
--- a/spec/models/public_body_spec.rb
+++ b/spec/models/public_body_spec.rb
@@ -169,6 +169,14 @@ describe PublicBody, " when saving" do
@public_body.save!
@public_body.first_letter.should == 'T'
end
+
+ it "should save the name when renaming an existing public body" do
+ public_body = public_bodies(:geraldine_public_body)
+ public_body.name = "Mark's Public Body"
+ public_body.save!
+
+ public_body.name.should == "Mark's Public Body"
+ end
end
describe PublicBody, "when searching" do
@@ -210,7 +218,7 @@ describe PublicBody, "when searching" do
end
it "should cope with same url_name across multiple locales" do
- PublicBody.with_locale(:es) do
+ I18n.with_locale(:es) do
# use the unique spanish name to retrieve and edit
body = PublicBody.find_by_url_name_with_historic('etgq')
body.short_name = 'tgq' # Same as english version
@@ -231,7 +239,7 @@ end
describe PublicBody, " when dealing public body locales" do
it "shouldn't fail if it internal_admin_body was created in a locale other than the default" do
# first time, do it with the non-default locale
- PublicBody.with_locale(:es) do
+ I18n.with_locale(:es) do
PublicBody.internal_admin_body
end
@@ -378,7 +386,7 @@ describe PublicBody, " when loading CSV files" do
PublicBody.count.should == original_count + 3
- # XXX Not sure why trying to do a PublicBody.with_locale fails here. Seems related to
+ # XXX Not sure why trying to do a I18n.with_locale fails here. Seems related to
# the way categories are loaded every time from the PublicBody class. For now we just
# test some translation was done.
body = PublicBody.find_by_name('North West Fake Authority')
diff --git a/spec/models/user_mailer_spec.rb b/spec/models/user_mailer_spec.rb
deleted file mode 100644
index 0792aaab2..000000000
--- a/spec/models/user_mailer_spec.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
-
-describe UserMailer, " when blah" do
- before do
- end
-end
-
-
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index e31c3f1b5..651ba4b65 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -152,10 +152,10 @@ end
describe User, "when reindexing referencing models" do
before do
- @request_event = safe_mock_model(InfoRequestEvent, :xapian_mark_needs_index => true)
- @request = safe_mock_model(InfoRequest, :info_request_events => [@request_event])
- @comment_event = safe_mock_model(InfoRequestEvent, :xapian_mark_needs_index => true)
- @comment = safe_mock_model(Comment, :info_request_events => [@comment_event])
+ @request_event = mock_model(InfoRequestEvent, :xapian_mark_needs_index => true)
+ @request = mock_model(InfoRequest, :info_request_events => [@request_event])
+ @comment_event = mock_model(InfoRequestEvent, :xapian_mark_needs_index => true)
+ @comment = mock_model(Comment, :info_request_events => [@comment_event])
@user = User.new(:comments => [@comment], :info_requests => [@request])
end
diff --git a/spec/script/mailin_spec.rb b/spec/script/mailin_spec.rb
index acd06ff3b..46ad39f7f 100644
--- a/spec/script/mailin_spec.rb
+++ b/spec/script/mailin_spec.rb
@@ -32,6 +32,8 @@ describe "When importing mail into the application" do
ir = info_requests(:other_request)
incoming_message = ir.incoming_messages[0]
incoming_message.fully_destroy
+ # And get rid of any remaining purge requests
+ PurgeRequest.destroy_all
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 33e39e6e4..57ab88da2 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,242 +1,141 @@
-require 'simplecov'
-require 'coveralls'
-
-# Generate coverage locally in html as well as in coveralls.io
-SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
- SimpleCov::Formatter::HTMLFormatter,
- Coveralls::SimpleCov::Formatter
-]
-SimpleCov.start('rails') do
- add_filter 'commonlib'
- add_filter 'vendor/plugins'
-end
-
-# This file is copied to ~/spec when you run 'ruby script/generate rspec'
-# from the project root directory.
-ENV["RAILS_ENV"] = 'test'
-require File.expand_path(File.join('..', '..', 'config', 'environment'), __FILE__)
-require 'spec/autorun'
-require 'spec/rails'
-
-# set a default username and password so we can test
-config = MySociety::Config.load_default()
-config['ADMIN_USERNAME'] = 'foo'
-config['ADMIN_PASSWORD'] = 'baz'
-
-# tests assume 20 days
-config['REPLY_LATE_AFTER_DAYS'] = 20
-
-# register a fake Varnish server
-require 'fakeweb'
-FakeWeb.register_uri(:purge, %r|varnish.localdomain|, :body => "OK")
-
-Webrat.configure do |config|
- config.mode = :rails
-end
-
-# Use test-specific translations
-FastGettext.add_text_domain 'app', :path => File.join(File.dirname(__FILE__), 'fixtures', 'locale'), :type => :po
-FastGettext.default_text_domain = 'app'
-Spec::Runner.configure do |config|
- # If you're not using ActiveRecord you should remove these
- # lines, delete config/database.yml and disable :active_record
- # in your config/boot.rb
-
- # fixture_path must end in a separator
- config.fixture_path = File.join(Rails.root, 'spec', 'fixtures') + File::SEPARATOR
- config.global_fixtures = :users,
- :public_bodies,
- :public_body_translations,
- :public_body_versions,
- :info_requests,
- :raw_emails,
- :incoming_messages,
- :outgoing_messages,
- :comments,
- :info_request_events,
- :track_things,
- :foi_attachments,
- :has_tag_string_tags,
- :holidays,
- :track_things_sent_emails
-
- # This section makes the garbage collector run less often to speed up tests
- last_gc_run = Time.now
-
- config.before(:each) do
- GC.disable
- end
-
- config.after(:each) do
- if Time.now - last_gc_run > 4
- GC.enable
- GC.start
- last_gc_run = Time.now
+require 'rubygems'
+require 'spork'
+#uncomment the following line to use spork with the debugger
+#require 'spork/ext/ruby-debug'
+
+Spork.prefork do
+ # Loading more in this block will cause your tests to run faster. However,
+ # if you change any configuration or code from libraries loaded here, you'll
+ # need to restart spork for it take effect.
+
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
+ ENV["RAILS_ENV"] ||= 'test'
+ require File.expand_path("../../config/environment", __FILE__)
+ require 'rspec/rails'
+ require 'rspec/autorun'
+
+ # Requires supporting ruby files with custom matchers and macros, etc,
+ # in spec/support/ and its subdirectories.
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
+
+ # Use test-specific translations
+ FastGettext.add_text_domain 'app', :path => File.join(File.dirname(__FILE__), 'fixtures', 'locale'), :type => :po
+ FastGettext.default_text_domain = 'app'
+
+ RSpec.configure do |config|
+ # ## Mock Framework
+ #
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
+ #
+ # config.mock_with :mocha
+ # config.mock_with :flexmock
+ # config.mock_with :rr
+
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
+
+ # The order (!) of this is important thanks to foreign keys
+ config.global_fixtures = :users,
+ :public_bodies,
+ :public_body_translations,
+ :public_body_versions,
+ :info_requests,
+ :raw_emails,
+ :incoming_messages,
+ :outgoing_messages,
+ :comments,
+ :info_request_events,
+ :track_things,
+ :has_tag_string_tags,
+ :holidays
+
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
+ # examples within a transaction, remove the following line or assign false
+ # instead of true.
+ config.use_transactional_fixtures = true
+
+ # If true, the base class of anonymous controllers will be inferred
+ # automatically. This will be the default behavior in future versions of
+ # rspec-rails.
+ config.infer_base_class_for_anonymous_controllers = false
+
+ # Run specs in random order to surface order dependencies. If you find an
+ # order dependency and want to debug it, you can fix the order by providing
+ # the seed, which is printed after each run.
+ # --seed 1234
+ config.order = "random"
+
+ # This is a workaround for a strange thing where ActionMailer::Base.deliveries isn't being
+ # cleared out correctly in controller specs. So, do it here for everything.
+ config.before(:each) do
+ ActionMailer::Base.deliveries = []
end
- end
- # == Fixtures
- #
- # You can declare fixtures for each example_group like this:
- # describe "...." do
- # fixtures :table_a, :table_b
- #
- # Alternatively, if you prefer to declare them only once, you can
- # do so right here. Just uncomment the next line and replace the fixture
- # names with your fixtures.
- #
- # config.global_fixtures = :table_a, :table_b
- #
- # If you declare global fixtures, be aware that they will be declared
- # for all of your examples, even those that don't use them.
- #
- # You can also declare which fixtures to use (for example fixtures for test/fixtures):
- #
- # config.fixture_path = Rails.root + '/spec/fixtures/'
- #
- # == Mock Framework
- #
- # RSpec uses its own mocking framework by default. If you prefer to
- # use mocha, flexmock or RR, uncomment the appropriate line:
- #
- # config.mock_with :mocha
- # config.mock_with :flexmock
- # config.mock_with :rr
- #
- # == Notes
- #
- # For more information take a look at Spec::Runner::Configuration and Spec::Runner
-end
-
-# XXX No idea what namespace/class/module to put this in
-def receive_incoming_mail(email_name, email_to, email_from = 'geraldinequango@localhost')
- email_name = file_fixture_name(email_name)
- content = File.read(email_name)
- content.gsub!('EMAIL_TO', email_to)
- content.gsub!('EMAIL_FROM', email_from)
- RequestMailer.receive(content)
-end
-
-def file_fixture_name(file_name)
- return File.join(Spec::Runner.configuration.fixture_path, "files", file_name)
-end
+ # Any test that messes with the locale needs to restore the state afterwards so that it
+ # doesn't interfere with any subsequent tests. This is made more complicated by the
+ # ApplicationController#set_gettext_locale which sets the locale and so you may be setting
+ # the locale in your tests and not even realising it. So, let's make things easier for
+ # ourselves and just always restore the locale for all tests.
+ config.before(:each) do
+ @save_i18n_locale = I18n.locale
+ end
-def load_file_fixture(file_name, as_binary=false)
- file_name = file_fixture_name(file_name)
- content = File.open(file_name, 'r') do |file|
- if as_binary
- file.set_encoding(Encoding::BINARY) if file.respond_to?(:set_encoding)
- end
- file.read
+ config.after(:each) do
+ I18n.locale = @save_i18n_locale
end
- return content
-end
-def parse_all_incoming_messages
- IncomingMessage.find(:all).each{ |x| x.parse_raw_email! }
-end
+ # This section makes the garbage collector run less often to speed up tests
+ last_gc_run = Time.now
-def load_raw_emails_data
- raw_emails_yml = File.join(Spec::Runner.configuration.fixture_path, "raw_emails.yml")
- for raw_email_id in YAML::load_file(raw_emails_yml).map{|k,v| v["id"]} do
- raw_email = RawEmail.find(raw_email_id)
- raw_email.data = load_file_fixture("raw_emails/%d.email" % [raw_email_id])
+ config.before(:each) do
+ GC.disable
end
-end
-# Rebuild the current xapian index
-def rebuild_xapian_index(terms = true, values = true, texts = true, dropfirst = true)
- if dropfirst
- begin
- ActsAsXapian.readable_init
- FileUtils.rm_r(ActsAsXapian.db_path)
- rescue RuntimeError
- end
- ActsAsXapian.writable_init
- ActsAsXapian.writable_db.close
+ config.after(:each) do
+ if Time.now - last_gc_run > 4
+ GC.enable
+ GC.start
+ last_gc_run = Time.now
+ end
end
- parse_all_incoming_messages
- # safe_rebuild=true, which involves forking to avoid memory leaks, doesn't work well with rspec.
- # unsafe is significantly faster, and we can afford possible memory leaks while testing.
- models = [PublicBody, User, InfoRequestEvent]
- ActsAsXapian.rebuild_index(models, verbose=false, terms, values, texts, safe_rebuild=false)
-end
-
-# Create a clean xapian index based on the fixture files and the raw_email data.
-def create_fixtures_xapian_index
- load_raw_emails_data
- rebuild_xapian_index
-end
-
-def update_xapian_index
- ActsAsXapian.update_index(flush_to_disk=false, verbose=false)
-end
-
-# Copy the xapian index created in create_fixtures_xapian_index to a temporary
-# copy at the same level and point xapian at the copy
-def get_fixtures_xapian_index()
- # Create a base index for the fixtures if not already created
- $existing_xapian_db ||= create_fixtures_xapian_index
- # Store whatever the xapian db path is originally
- $original_xapian_path ||= ActsAsXapian.db_path
- path_array = $original_xapian_path.split(File::Separator)
- path_array.pop
- temp_path = File.join(path_array, 'test.temp')
- FileUtils.remove_entry_secure(temp_path, force=true)
- FileUtils.cp_r($original_xapian_path, temp_path)
- ActsAsXapian.db_path = temp_path
-end
-
-def basic_auth_login(request, username = nil, password = nil)
- username = Configuration::admin_username if username.nil?
- password = Configuration::admin_password if password.nil?
- request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("#{username}:#{password}")
-end
-
-# to_ary differs in Ruby 1.8 and 1.9
-# @see http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/
-def safe_mock_model(model, args = {})
- mock = mock_model(model, args)
- mock.should_receive(:to_ary).any_number_of_times
- mock
-end
-
-def get_fixture_mail(filename)
- MailHandler.mail_from_raw_email(load_file_fixture(filename))
-end
-
-def load_test_categories
- PublicBodyCategories.add(:en, [
- "Local and regional",
- [ "local_council", "Local councils", "a local council" ],
- "Miscellaneous",
- [ "other", "Miscellaneous", "miscellaneous" ],])
-end
+ end
+ # XXX No idea what namespace/class/module to put this in
+ # Create a clean xapian index based on the fixture files and the raw_email data.
+ def create_fixtures_xapian_index
+ load_raw_emails_data
+ rebuild_xapian_index
+ end
-# Monkeypatch applicationcontroller because the `render_to_string`
-# method in the original breaks all the rspec test assertions such as
-# `should render_template('foo')`. Same problem as
-# http://stackoverflow.com/questions/8174415/is-it-possible-to-assert-template-or-render-template-against-the-same-partial-wi
-# - a bug in either Rails or Rspec I don't have the time to fix :(
+ def with_env_tz(new_tz = 'US/Eastern')
+ old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+ yield
+ ensure
+ old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+ end
-class ApplicationController < ActionController::Base
- def set_popup_banner
- @popup_banner = nil
- end
-end
+ def with_active_record_default_timezone(zone)
+ old_zone, ActiveRecord::Base.default_timezone = ActiveRecord::Base.default_timezone, zone
+ yield
+ ensure
+ ActiveRecord::Base.default_timezone = old_zone
+ end
+ def load_test_categories
+ PublicBodyCategories.add(:en, [
+ "Local and regional",
+ [ "local_council", "Local councils", "a local council" ],
+ "Miscellaneous",
+ [ "other", "Miscellaneous", "miscellaneous" ],])
+ end
-def with_env_tz(new_tz = 'US/Eastern')
- old_tz, ENV['TZ'] = ENV['TZ'], new_tz
- yield
-ensure
- old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+ def basic_auth_login(request, username = nil, password = nil)
+ username = AlaveteliConfiguration::admin_username if username.nil?
+ password = AlaveteliConfiguration::admin_password if password.nil?
+ request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("#{username}:#{password}")
+ end
end
-def with_active_record_default_timezone(zone)
- old_zone, ActiveRecord::Base.default_timezone = ActiveRecord::Base.default_timezone, zone
- yield
-ensure
- ActiveRecord::Base.default_timezone = old_zone
+Spork.each_run do
+ # This code will be run each time you run your specs.
end
diff --git a/spec/support/email_helpers.rb b/spec/support/email_helpers.rb
new file mode 100644
index 000000000..7e98c39f6
--- /dev/null
+++ b/spec/support/email_helpers.rb
@@ -0,0 +1,23 @@
+def load_raw_emails_data
+ raw_emails_yml = File.join(RSpec.configuration.fixture_path, "raw_emails.yml")
+ for raw_email_id in YAML::load_file(raw_emails_yml).map{|k,v| v["id"]} do
+ raw_email = RawEmail.find(raw_email_id)
+ raw_email.data = load_file_fixture("raw_emails/%d.email" % [raw_email_id])
+ end
+end
+
+def receive_incoming_mail(email_name, email_to, email_from = 'geraldinequango@localhost')
+ email_name = file_fixture_name(email_name)
+ content = File.read(email_name)
+ content.gsub!('EMAIL_TO', email_to)
+ content.gsub!('EMAIL_FROM', email_from)
+ RequestMailer.receive(content)
+end
+
+def get_fixture_mail(filename)
+ MailHandler.mail_from_raw_email(load_file_fixture(filename))
+end
+
+def parse_all_incoming_messages
+ IncomingMessage.find(:all).each{ |x| x.parse_raw_email! }
+end
diff --git a/spec/support/load_file_fixtures.rb b/spec/support/load_file_fixtures.rb
new file mode 100644
index 000000000..08079f654
--- /dev/null
+++ b/spec/support/load_file_fixtures.rb
@@ -0,0 +1,14 @@
+def file_fixture_name(file_name)
+ return File.join(RSpec.configuration.fixture_path, "files", file_name)
+end
+
+def load_file_fixture(file_name, as_binary=false)
+ file_name = file_fixture_name(file_name)
+ content = File.open(file_name, 'r') do |file|
+ if as_binary
+ file.set_encoding(Encoding::BINARY) if file.respond_to?(:set_encoding)
+ end
+ file.read
+ end
+ return content
+end
diff --git a/spec/support/xapian_index.rb b/spec/support/xapian_index.rb
new file mode 100644
index 000000000..344c28ebb
--- /dev/null
+++ b/spec/support/xapian_index.rb
@@ -0,0 +1,42 @@
+# Rebuild the current xapian index
+def rebuild_xapian_index(terms = true, values = true, texts = true, dropfirst = true)
+ if dropfirst
+ begin
+ ActsAsXapian.readable_init
+ FileUtils.rm_r(ActsAsXapian.db_path)
+ rescue RuntimeError
+ end
+ ActsAsXapian.writable_init
+ ActsAsXapian.writable_db.close
+ end
+ parse_all_incoming_messages
+ # safe_rebuild=true, which involves forking to avoid memory leaks, doesn't work well with rspec.
+ # unsafe is significantly faster, and we can afford possible memory leaks while testing.
+ models = [PublicBody, User, InfoRequestEvent]
+ ActsAsXapian.rebuild_index(models, verbose=false, terms, values, texts, safe_rebuild=false)
+end
+
+def update_xapian_index
+ ActsAsXapian.update_index(flush_to_disk=false, verbose=false)
+end
+
+# Copy the xapian index created in create_fixtures_xapian_index to a temporary
+# copy at the same level and point xapian at the copy
+def get_fixtures_xapian_index()
+ # Create a base index for the fixtures if not already created
+ $existing_xapian_db ||= create_fixtures_xapian_index
+ # Store whatever the xapian db path is originally
+ $original_xapian_path ||= ActsAsXapian.db_path
+ path_array = $original_xapian_path.split(File::Separator)
+ path_array.pop
+ temp_path = File.join(path_array, 'test.temp')
+ FileUtils.remove_entry_secure(temp_path, force=true)
+ FileUtils.cp_r($original_xapian_path, temp_path)
+ ActsAsXapian.db_path = temp_path
+end
+
+# Create a clean xapian index based on the fixture files and the raw_email data.
+def create_fixtures_xapian_index
+ load_raw_emails_data
+ rebuild_xapian_index
+end
diff --git a/spec/views/public_body/show.rhtml_spec.rb b/spec/views/public_body/show.html.erb_spec.rb
index 23e92dedd..0559fc8ef 100644
--- a/spec/views/public_body/show.rhtml_spec.rb
+++ b/spec/views/public_body/show.html.erb_spec.rb
@@ -1,6 +1,6 @@
require File.expand_path(File.join('..', '..', '..', 'spec_helper'), __FILE__)
-describe "when viewing a body" do
+describe "public_body/show" do
before do
@pb = mock_model(PublicBody,
:name => 'Test Quango',
@@ -17,59 +17,57 @@ describe "when viewing a body" do
@pb.stub!(:is_requestable?).and_return(true)
@pb.stub!(:has_notes?).and_return(false)
@pb.stub!(:has_tag?).and_return(false)
- @xap = mock_model(ActsAsXapian::Search, :matches_estimated => 2)
+ @xap = mock(ActsAsXapian::Search, :matches_estimated => 2)
@xap.stub!(:results).and_return([
{ :model => mock_event },
{ :model => mock_event }
])
- assigns[:public_body] = @pb
- assigns[:track_thing] = mock_model(TrackThing,
- :track_type => 'public_body_updates', :public_body => @pb, :params => {})
- assigns[:xapian_requests] = @xap
- assigns[:page] = 1
- assigns[:per_page] = 10
- # work round a bug in ActionController::TestRequest; allows request.query_string to work in the template
- request.env["REQUEST_URI"] = ""
+ assign(:public_body, @pb)
+ assign(:track_thing, mock_model(TrackThing,
+ :track_type => 'public_body_updates', :public_body => @pb, :params => {}))
+ assign(:xapian_requests, @xap)
+ assign(:page, 1)
+ assign(:per_page, 10)
end
it "should be successful" do
- render "public_body/show"
- response.should be_success
+ render
+ controller.response.should be_success
end
it "should show the body's name" do
- render "public_body/show"
- response.should have_tag("h1", "Test Quango")
+ render
+ response.should have_selector('h1', :content => "Test Quango")
end
it "should tell total number of requests" do
- render "public_body/show"
- response.should include_text("4 Freedom of Information requests")
+ render
+ response.should match "4 Freedom of Information requests"
end
it "should cope with no results" do
@pb.stub!(:info_requests).and_return([])
- render "public_body/show"
- response.should have_tag("p", /Nobody has made any Freedom of Information requests/m)
+ render
+ response.should have_selector('p', :content => "Nobody has made any Freedom of Information requests")
end
it "should cope with Xapian being down" do
- assigns[:xapian_requests] = nil
- render "public_body/show"
- response.should have_tag("p", /The search index is currently offline/m)
+ assign(:xapian_requests, nil)
+ render
+ response.should match "The search index is currently offline"
end
it "should link to Charity Commission site if we have numbers to do so" do
@pb.stub!(:has_tag?).and_return(true)
@pb.stub!(:get_tag_values).and_return(['98765', '12345'])
- render "public_body/show"
- response.should have_tag("div#header_right") do
- with_tag("a[href*=?]", /charity-commission.gov.uk.*RegisteredCharityNumber=98765$/)
+ render
+ response.should have_selector("div#header_right") do
+ have_selector "a", :href => /charity-commission.gov.uk.*RegisteredCharityNumber=98765$/
end
- response.should have_tag("div#header_right") do
- with_tag("a[href*=?]", /charity-commission.gov.uk.*RegisteredCharityNumber=12345$/)
+ response.should have_selector("div#header_right") do
+ have_selector "a", :href => /www.charity-commission.gov.uk.*RegisteredCharityNumber=12345$/
end
end
@@ -77,17 +75,17 @@ describe "when viewing a body" do
@pb.stub!(:has_tag?).and_return(true)
@pb.stub!(:get_tag_values).and_return(['SC1234'])
- render "public_body/show"
- response.should have_tag("div#header_right") do
- with_tag("a[href*=?]", /www.oscr.org.uk.*id=SC1234$/)
+ render
+ response.should have_selector("div#header_right") do
+ have_selector "a", :href => /www.oscr.org.uk.*id=SC1234$/
end
end
it "should not link to Charity Commission site if we don't have number" do
- render "public_body/show"
- response.should have_tag("div#header_right") do
- without_tag("a[href*=?]", /charity-commission.gov.uk/)
+ render
+ response.should have_selector("div#header_right") do
+ have_selector "a", :href => /charity-commission.gov.uk/
end
end
diff --git a/spec/views/request/_after_actions.rhtml_spec.rb b/spec/views/request/_after_actions.html.erb_spec.rb
index 548990c9f..ae398f4ce 100644
--- a/spec/views/request/_after_actions.rhtml_spec.rb
+++ b/spec/views/request/_after_actions.html.erb_spec.rb
@@ -15,51 +15,27 @@ describe 'when displaying actions that can be taken with regard to a request' do
:comments_allowed? => true,
:url_title => 'test_request',
:all_can_view? => true)
- assigns[:info_request] = @mock_request
- end
-
- def do_render
- render :partial => 'request/after_actions'
- end
-
- def expect_owner_div
- do_render
- response.should have_tag('div#owner_actions'){ yield }
- end
-
- def expect_anyone_div
- do_render
- response.should have_tag('div#anyone_actions'){ yield }
- end
-
- def expect_owner_link(text)
- expect_owner_div{ with_tag('a', :text => text) }
- end
-
- def expect_no_owner_link(text)
- expect_owner_div{ without_tag('a', :text => text) }
- end
-
- def expect_anyone_link(text)
- expect_anyone_div{ with_tag('a', :text => text) }
- end
-
- def expect_no_anyone_link(text)
- expect_anyone_div{ without_tag('a', :text => text) }
+ assign :info_request, @mock_request
end
describe 'if the request is old and unclassified' do
before do
- assigns[:old_unclassified] = true
+ assign :old_unclassified, true
end
it 'should not display a link for the request owner to update the status of the request' do
- expect_no_owner_link('Update the status of this request')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#owner_actions') do |div|
+ div.should_not have_selector('a', :content => 'Update the status of this request')
+ end
end
it 'should display a link for anyone to update the status of the request' do
- expect_anyone_link('Update the status of this request')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#anyone_actions') do |div|
+ div.should have_selector('a', :content => 'Update the status of this request')
+ end
end
end
@@ -67,27 +43,39 @@ describe 'when displaying actions that can be taken with regard to a request' do
describe 'if the request is not old and unclassified' do
before do
- assigns[:old_unclassified] = false
+ assign :old_unclassified, false
end
it 'should display a link for the request owner to update the status of the request' do
- expect_owner_link('Update the status of this request')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#owner_actions') do |div|
+ div.should have_selector('a', :content => 'Update the status of this request')
+ end
end
it 'should not display a link for anyone to update the status of the request' do
- expect_no_anyone_link('Update the status of this request')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#anyone_actions') do |div|
+ div.should_not have_selector('a', :content => 'Update the status of this request')
+ end
end
end
it 'should display a link for the request owner to request a review' do
- expect_owner_link('Request an internal review')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#owner_actions') do |div|
+ div.should have_selector('a', :content => 'Request an internal review')
+ end
end
describe 'if the request is viewable by all' do
it 'should display the link to download the entire request' do
- expect_anyone_link('Download a zip file of all correspondence')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#anyone_actions') do |div|
+ div.should have_selector('a', :content => 'Download a zip file of all correspondence')
+ end
end
end
@@ -95,7 +83,10 @@ describe 'when displaying actions that can be taken with regard to a request' do
it 'should not display the link to download the entire request' do
@mock_request.stub!(:all_can_view?).and_return(false)
- expect_no_anyone_link('Download a zip file of all correspondence')
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#anyone_actions') do |div|
+ div.should_not have_selector('a', :content => 'Download a zip file of all correspondence')
+ end
end
end
diff --git a/spec/views/request/_describe_state.rhtml_spec.rb b/spec/views/request/_describe_state.html.erb_spec.rb
index 18778d5d2..88dea53c5 100644
--- a/spec/views/request/_describe_state.rhtml_spec.rb
+++ b/spec/views/request/_describe_state.html.erb_spec.rb
@@ -4,12 +4,12 @@ describe 'when showing the form for describing the state of a request' do
def expect_radio_button(value)
do_render
- response.should have_tag("input[type=radio][value=#{value}]")
+ response.should have_selector('input', :type => 'radio', :value => value)
end
def expect_no_radio_button(value)
do_render
- response.should_not have_tag("input[type=radio][value=#{value}]")
+ response.should_not have_selector('input', :type => 'radio', :value => value)
end
def do_render
@@ -24,25 +24,25 @@ describe 'when showing the form for describing the state of a request' do
:user_name => @mock_user.name,
:is_external? => false
)
- assigns[:info_request] = @mock_request
+ assign :info_request, @mock_request
end
describe 'if the user is a regular user (not the request owner)' do
before do
- assigns[:is_owning_user] = false
+ assign :is_owning_user, false
end
describe 'if the request is not old and unclassified' do
it 'should not show the form' do
do_render
- response.should_not have_tag('h2', :text => 'What best describes the status of this request now?')
+ response.should_not have_selector('h2', :content => 'What best describes the status of this request now?')
end
it 'should give a link to login' do
do_render
- response.should have_tag('a', :text => 'sign in')
+ response.should have_selector('a', :content => 'sign in')
end
end
@@ -50,22 +50,22 @@ describe 'when showing the form for describing the state of a request' do
describe 'if the request is old and unclassified' do
before do
- assigns[:old_unclassified] = true
+ assign :old_unclassified, true
end
it 'should not show the form' do
do_render
- response.should_not have_tag('h2', :text => 'What best describes the status of this request now?')
+ response.should_not have_selector('h2', :content => 'What best describes the status of this request now?')
end
it 'should show the form for someone else to classify the request' do
do_render
- response.should have_tag('h2', :text => /We need your help/)
+ response.should have_selector('h2', :content => 'We need your help')
end
it 'should not give a link to login' do
do_render
- response.should_not have_tag('a', :text => 'sign in')
+ response.should_not have_selector('a', :content => 'sign in')
end
end
@@ -74,7 +74,7 @@ describe 'when showing the form for describing the state of a request' do
describe 'if showing the form to the user owning the request' do
before do
- assigns[:is_owning_user] = true
+ assign :is_owning_user, true
end
describe 'when the request is not in internal review' do
@@ -100,7 +100,7 @@ describe 'when showing the form for describing the state of a request' do
describe 'when the user has asked to update the status of the request' do
before do
- assigns[:update_status] = true
+ assign :update_status, true
end
it 'should show a radio button to set the status to "internal_review"' do
@@ -129,7 +129,7 @@ describe 'when showing the form for describing the state of a request' do
it 'should show the text "The review has finished and overall:"' do
do_render
- response.should have_tag('p', :text => 'The review has finished and overall:')
+ response.should have_selector('p', :content => 'The review has finished and overall:')
end
end
@@ -170,4 +170,4 @@ describe 'when showing the form for describing the state of a request' do
end
end
-end \ No newline at end of file
+end
diff --git a/spec/views/request/list.rhtml_spec.rb b/spec/views/request/list.html.erb_spec.rb
index 137bc359d..521d946bc 100644
--- a/spec/views/request/list.rhtml_spec.rb
+++ b/spec/views/request/list.html.erb_spec.rb
@@ -1,12 +1,10 @@
require File.expand_path(File.join('..', '..', '..', 'spec_helper'), __FILE__)
-describe "when listing recent requests" do
+describe "request/list" do
before do
- assigns[:page] = 1
- assigns[:per_page] = 10
- # work round a bug in ActionController::TestRequest; allows request.query_string to work in the template
- request.env["REQUEST_URI"] = ""
+ assign :page, 1
+ assign :per_page, 10
end
def make_mock_event
@@ -30,21 +28,21 @@ describe "when listing recent requests" do
end
it "should be successful" do
- assigns[:list_results] = [ make_mock_event, make_mock_event ]
- assigns[:matches_estimated] = 2
- assigns[:show_no_more_than] = 100
- render "request/list"
- response.should have_tag("div.request_listing")
- response.should_not have_tag("p", /No requests of this sort yet/m)
+ assign :list_results, [ make_mock_event, make_mock_event ]
+ assign :matches_estimated, 2
+ assign :show_no_more_than, 100
+ render
+ response.should have_selector("div.request_listing")
+ response.should_not have_selector("p", :content => "No requests of this sort yet")
end
it "should cope with no results" do
- assigns[:list_results] = [ ]
- assigns[:matches_estimated] = 0
- assigns[:show_no_more_than] = 0
- render "request/list"
- response.should have_tag("p", /No requests of this sort yet/m)
- response.should_not have_tag("div.request_listing")
+ assign :list_results, [ ]
+ assign :matches_estimated, 0
+ assign :show_no_more_than, 0
+ render
+ response.should have_selector("p", :content => "No requests of this sort yet")
+ response.should_not have_selector("div.request_listing")
end
end
diff --git a/spec/views/request/show.rhtml_spec.rb b/spec/views/request/show.html.erb_spec.rb
index a22f29951..4578268b2 100644
--- a/spec/views/request/show.rhtml_spec.rb
+++ b/spec/views/request/show.html.erb_spec.rb
@@ -1,6 +1,6 @@
require File.expand_path(File.join('..', '..', '..', 'spec_helper'), __FILE__)
-describe 'when viewing an information request' do
+describe 'request/show' do
before do
@mock_body = mock_model(PublicBody, :name => 'test body',
@@ -19,36 +19,28 @@ describe 'when viewing an information request' do
:is_external? => false,
:calculate_status => 'waiting_response',
:date_response_required_by => Date.today,
- :prominence => 'normal')
+ :prominence => 'normal',
+ :comments_allowed? => true,
+ :all_can_view? => true,
+ :url_title => 'test_request')
end
def request_page
- assigns[:info_request] = @mock_request
- assigns[:info_request_events] = []
- assigns[:status] = @mock_request.calculate_status
- template.stub!(:render_partial)
- render 'request/show'
- end
-
- it 'should show the sidebar' do
- template.should_receive(:render_partial).with(:partial => 'sidebar', :locals => {})
- request_page
- end
-
- it 'should show the actions people can take' do
- template.should_receive(:render_partial).with(:partial => 'after_actions', :locals => {})
- request_page
+ assign :info_request, @mock_request
+ assign :info_request_events, []
+ assign :status, @mock_request.calculate_status
+ render
end
describe 'when a status update has been requested' do
before do
- assigns[:update_status] = true
+ assign :update_status, true
end
it 'should show the first form for describing the state of the request' do
request_page
- response.should have_tag("div.describe_state_form#describe_state_form_1")
+ response.should have_selector("div.describe_state_form#describe_state_form_1")
end
end
@@ -61,12 +53,12 @@ describe 'when viewing an information request' do
it 'should show the first form for describing the state of the request' do
request_page
- response.should have_tag("div.describe_state_form#describe_state_form_1")
+ response.should have_selector("div.describe_state_form#describe_state_form_1")
end
it 'should show the second form for describing the state of the request' do
request_page
- response.should have_tag("div.describe_state_form#describe_state_form_2")
+ response.should have_selector("div.describe_state_form#describe_state_form_2")
end
end
@@ -74,7 +66,7 @@ describe 'when viewing an information request' do
describe 'when the user is the request owner' do
before do
- assigns[:is_owning_user] = true
+ assign :is_owning_user, true
end
describe 'when the request status is "waiting clarification"' do
@@ -88,18 +80,13 @@ describe 'when viewing an information request' do
before do
@mock_response = mock_model(IncomingMessage)
@mock_request.stub!(:get_last_response).and_return(@mock_response)
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
- end
- after do
- ActionController::Routing::Routes.filters = @old_filters
end
it 'should show a link to follow up the last response with clarification' do
request_page
- expected_url = "/request/#{@mock_request.id}/response/#{@mock_response.id}#followup"
- response.should have_tag("a[href=#{expected_url}]", :text => 'send a follow up message')
+ expected_url = "/en/request/#{@mock_request.id}/response/#{@mock_response.id}#followup"
+ response.should have_selector("a", :href => expected_url, :content => 'send a follow up message')
end
end
@@ -108,18 +95,13 @@ describe 'when viewing an information request' do
before do
@mock_request.stub!(:get_last_response).and_return(nil)
- @old_filters = ActionController::Routing::Routes.filters
- ActionController::Routing::Routes.filters = RoutingFilter::Chain.new
- end
- after do
- ActionController::Routing::Routes.filters = @old_filters
end
it 'should show a link to follow up the request without reference to a specific response' do
request_page
- expected_url = "/request/#{@mock_request.id}/response#followup"
- response.should have_tag("a[href=#{expected_url}]", :text => 'send a follow up message')
+ expected_url = "/en/request/#{@mock_request.id}/response#followup"
+ response.should have_selector("a", :href => expected_url, :content => 'send a follow up message')
end
end
end
diff --git a/spec/views/request_game/play.rhtml_spec.rb b/spec/views/request_game/play.html.erb_spec.rb
index 24fb6d75d..b5cf57c23 100644
--- a/spec/views/request_game/play.rhtml_spec.rb
+++ b/spec/views/request_game/play.html.erb_spec.rb
@@ -1,6 +1,6 @@
require File.expand_path(File.join('..', '..', '..', 'spec_helper'), __FILE__)
-describe 'when viewing the request game' do
+describe 'request_game/play' do
before do
@mock_body = mock_model(PublicBody, :name => 'test body',
@@ -22,15 +22,15 @@ describe 'when viewing the request game' do
:initial_request_text => 'hi there',
:display_status => 'Awaiting categorisation',
:created_at => Time.now)
- assigns[:league_table_28_days] = []
- assigns[:league_table_all_time] = []
- assigns[:requests] = [@mock_request]
- assigns[:play_urls] = true
+ assign :league_table_28_days, []
+ assign :league_table_all_time, []
+ assign :requests, [@mock_request]
+ assign :play_urls, true
end
it 'should show the correct url for a request' do
- render "request_game/play"
- response.should include_text("/categorise/request/a_test_request")
+ render
+ response.should include("/categorise/request/a_test_request")
end
diff --git a/vendor/plugins/active_record_base_without_table/CHANGELOG b/vendor/plugins/active_record_base_without_table/CHANGELOG
deleted file mode 100644
index c74809532..000000000
--- a/vendor/plugins/active_record_base_without_table/CHANGELOG
+++ /dev/null
@@ -1,3 +0,0 @@
-[27 April 2007]
-
-* Correctly cache class instance variables containing column information [Reported by Nils Jonsson]
diff --git a/vendor/plugins/active_record_base_without_table/MIT-LICENSE b/vendor/plugins/active_record_base_without_table/MIT-LICENSE
deleted file mode 100644
index 602bda208..000000000
--- a/vendor/plugins/active_record_base_without_table/MIT-LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2006 Jonathan Viney
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/plugins/active_record_base_without_table/README b/vendor/plugins/active_record_base_without_table/README
deleted file mode 100644
index 8200d7ad6..000000000
--- a/vendor/plugins/active_record_base_without_table/README
+++ /dev/null
@@ -1,29 +0,0 @@
-= ActiveRecordBaseWithoutTable
-
-If you find this plugin useful, please consider a donation to show your support!
-
- http://www.paypal.com/cgi-bin/webscr?cmd=_send-money
-
- Email address: jonathan.viney@gmail.com
-
-== Instructions
-
-* For edge Rails r7315 or above use http://svn.viney.net.nz/things/branches/active_record_base_without_table
-
-Get the power of ActiveRecord models, including validation, without having a table in the database.
-
- class Contact < ActiveRecord::BaseWithoutTable
- column :name, :string
- column :email_address, :string
- column :message, :text
-
- validates_presence_of :name, :email_address, :string
- end
-
-This model can be used just like a regular model based on a table, except it will never be saved to the database.
-
-There is a good blog post available on the plugin:
-
- http://www.kangarooit.com/developer_blog/2007/02/email-form-validation-in-ruby-on-rails.php
-
-Any bugs, questions, comments please feel free to email me: jonathan.viney@gmail.com
diff --git a/vendor/plugins/active_record_base_without_table/Rakefile b/vendor/plugins/active_record_base_without_table/Rakefile
deleted file mode 100644
index ac9244515..000000000
--- a/vendor/plugins/active_record_base_without_table/Rakefile
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'rake'
-require 'rake/testtask'
-require 'rake/rdoctask'
-
-desc 'Default: run unit tests.'
-task :default => :test
-
-desc 'Test the active_record_base_without_table plugin.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
-end
-
-desc 'Generate documentation for the active_record_base_without_table plugin.'
-Rake::RDocTask.new(:rdoc) do |rdoc|
- rdoc.rdoc_dir = 'rdoc'
- rdoc.title = 'ActiveRecordBaseWithoutTable'
- rdoc.options << '--line-numbers' << '--inline-source'
- rdoc.rdoc_files.include('README')
- rdoc.rdoc_files.include('lib/**/*.rb')
-end
diff --git a/vendor/plugins/active_record_base_without_table/lib/active_record/base_without_table.rb b/vendor/plugins/active_record_base_without_table/lib/active_record/base_without_table.rb
deleted file mode 100644
index 12cb05e02..000000000
--- a/vendor/plugins/active_record_base_without_table/lib/active_record/base_without_table.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-module ActiveRecord
- class BaseWithoutTable < Base
- self.abstract_class = true
-
- def create_or_update
- errors.empty?
- end
-
- class << self
- def columns()
- @columns ||= []
- end
-
- def column(name, sql_type = nil, default = nil, null = true)
- columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
- reset_column_information
- end
-
- # Do not reset @columns
- def reset_column_information
- generated_methods.each { |name| undef_method(name) }
- @column_names = @columns_hash = @content_columns = @dynamic_methods_hash = @read_methods = nil
- end
- end
- end
-end
diff --git a/vendor/plugins/active_record_base_without_table/test/abstract_unit.rb b/vendor/plugins/active_record_base_without_table/test/abstract_unit.rb
deleted file mode 100644
index f72a8785b..000000000
--- a/vendor/plugins/active_record_base_without_table/test/abstract_unit.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require 'test/unit'
-
-begin
- require File.dirname(__FILE__) + '/../../../../config/boot'
- require 'active_record'
-rescue LoadError
- require 'rubygems'
- require_gem 'activerecord'
-end
-
-require File.dirname(__FILE__) + '/../lib/active_record/base_without_table'
-
-config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
-ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log')
-ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'mysql'])
diff --git a/vendor/plugins/active_record_base_without_table/test/active_record_base_without_table_test.rb b/vendor/plugins/active_record_base_without_table/test/active_record_base_without_table_test.rb
deleted file mode 100644
index 8d4bd4115..000000000
--- a/vendor/plugins/active_record_base_without_table/test/active_record_base_without_table_test.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-require File.dirname(__FILE__) + '/abstract_unit'
-
-class Person < ActiveRecord::BaseWithoutTable
- column :name, :string
- column :lucky_number, :integer, 4
-
- validates_presence_of :name
-end
-
-class ActiveRecordBaseWithoutTableTest < Test::Unit::TestCase
- def test_default_value
- assert_equal 4, Person.new.lucky_number
- end
-
- def test_validation
- p = Person.new
-
- assert !p.save
- assert p.errors[:name]
-
- assert p.update_attributes(:name => 'Name')
- end
-
- def test_typecast
- assert_equal 1, Person.new(:lucky_number => "1").lucky_number
- end
-
- def test_cached_column_variables_reset_when_column_defined
- cached_variables = %w(column_names columns_hash content_columns dynamic_methods_hash read_methods)
-
- Person.column_names
- Person.columns_hash
- Person.content_columns
- Person.column_methods_hash
- Person.read_methods
-
- cached_variables.each { |v| assert_not_nil Person.instance_variable_get("@#{v}") }
- Person.column :new_column, :string
- cached_variables.each { |v| assert_nil Person.instance_variable_get("@#{v}") }
- end
-end
diff --git a/vendor/plugins/active_record_base_without_table/test/database.yml b/vendor/plugins/active_record_base_without_table/test/database.yml
deleted file mode 100644
index b952dac55..000000000
--- a/vendor/plugins/active_record_base_without_table/test/database.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-mysql:
- :adapter: mysql
- :host: localhost
- :username: rails
- :password:
- :database: rails_plugin_test
diff --git a/vendor/plugins/acts_as_versioned/CHANGELOG b/vendor/plugins/acts_as_versioned/CHANGELOG
deleted file mode 100644
index 01882d767..000000000
--- a/vendor/plugins/acts_as_versioned/CHANGELOG
+++ /dev/null
@@ -1,82 +0,0 @@
-*GIT* (version numbers are overrated)
-
-* (16 Jun 2008) Backwards Compatibility is overrated (big updates for rails 2.1)
-
- * Use ActiveRecord 2.1's dirty attribute checking instead [Asa Calow]
- * Remove last traces of #non_versioned_fields
- * Remove AR::Base.find_version and AR::Base.find_versions, rely on AR association proxies and named_scope
- * Remove #versions_count, rely on AR association counter caching.
- * Remove #versioned_attributes, basically the same as AR::Base.versioned_columns
-
-* (5 Oct 2006) Allow customization of #versions association options [Dan Peterson]
-
-*0.5.1*
-
-* (8 Aug 2006) Versioned models now belong to the unversioned model. @article_version.article.class => Article [Aslak Hellesoy]
-
-*0.5* # do versions even matter for plugins?
-
-* (21 Apr 2006) Added without_locking and without_revision methods.
-
- Foo.without_revision do
- @foo.update_attributes ...
- end
-
-*0.4*
-
-* (28 March 2006) Rename non_versioned_fields to non_versioned_columns (old one is kept for compatibility).
-* (28 March 2006) Made explicit documentation note that string column names are required for non_versioned_columns.
-
-*0.3.1*
-
-* (7 Jan 2006) explicitly set :foreign_key option for the versioned model's belongs_to assocation for STI [Caged]
-* (7 Jan 2006) added tests to prove has_many :through joins work
-
-*0.3*
-
-* (2 Jan 2006) added ability to share a mixin with versioned class
-* (2 Jan 2006) changed the dynamic version model to MyModel::Version
-
-*0.2.4*
-
-* (27 Nov 2005) added note about possible destructive behavior of if_changed? [Michael Schuerig]
-
-*0.2.3*
-
-* (12 Nov 2005) fixed bug with old behavior of #blank? [Michael Schuerig]
-* (12 Nov 2005) updated tests to use ActiveRecord Schema
-
-*0.2.2*
-
-* (3 Nov 2005) added documentation note to #acts_as_versioned [Martin Jul]
-
-*0.2.1*
-
-* (6 Oct 2005) renamed dirty? to changed? to keep it uniform. it was aliased to keep it backwards compatible.
-
-*0.2*
-
-* (6 Oct 2005) added find_versions and find_version class methods.
-
-* (6 Oct 2005) removed transaction from create_versioned_table().
- this way you can specify your own transaction around a group of operations.
-
-* (30 Sep 2005) fixed bug where find_versions() would order by 'version' twice. (found by Joe Clark)
-
-* (26 Sep 2005) added :sequence_name option to acts_as_versioned to set the sequence name on the versioned model
-
-*0.1.3* (18 Sep 2005)
-
-* First RubyForge release
-
-*0.1.2*
-
-* check if module is already included when acts_as_versioned is called
-
-*0.1.1*
-
-* Adding tests and rdocs
-
-*0.1*
-
-* Initial transfer from Rails ticket: http://dev.rubyonrails.com/ticket/1974 \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/MIT-LICENSE b/vendor/plugins/acts_as_versioned/MIT-LICENSE
deleted file mode 100644
index 5851fdae1..000000000
--- a/vendor/plugins/acts_as_versioned/MIT-LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2005 Rick Olson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/README b/vendor/plugins/acts_as_versioned/README
deleted file mode 100644
index 8961f0522..000000000
--- a/vendor/plugins/acts_as_versioned/README
+++ /dev/null
@@ -1,28 +0,0 @@
-= acts_as_versioned
-
-This library adds simple versioning to an ActiveRecord module. ActiveRecord is required.
-
-== Resources
-
-Install
-
-* gem install acts_as_versioned
-
-Rubyforge project
-
-* http://rubyforge.org/projects/ar-versioned
-
-RDocs
-
-* http://ar-versioned.rubyforge.org
-
-Subversion
-
-* http://techno-weenie.net/svn/projects/acts_as_versioned
-
-Collaboa
-
-* http://collaboa.techno-weenie.net/repository/browse/acts_as_versioned
-
-Special thanks to Dreamer on ##rubyonrails for help in early testing. His ServerSideWiki (http://serversidewiki.com)
-was the first project to use acts_as_versioned <em>in the wild</em>. \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/RUNNING_UNIT_TESTS b/vendor/plugins/acts_as_versioned/RUNNING_UNIT_TESTS
deleted file mode 100644
index a6e55b841..000000000
--- a/vendor/plugins/acts_as_versioned/RUNNING_UNIT_TESTS
+++ /dev/null
@@ -1,41 +0,0 @@
-== Creating the test database
-
-The default name for the test databases is "activerecord_versioned". If you
-want to use another database name then be sure to update the connection
-adapter setups you want to test with in test/connections/<your database>/connection.rb.
-When you have the database online, you can import the fixture tables with
-the test/fixtures/db_definitions/*.sql files.
-
-Make sure that you create database objects with the same user that you specified in i
-connection.rb otherwise (on Postgres, at least) tests for default values will fail.
-
-== Running with Rake
-
-The easiest way to run the unit tests is through Rake. The default task runs
-the entire test suite for all the adapters. You can also run the suite on just
-one adapter by using the tasks test_mysql_ruby, test_ruby_mysql, test_sqlite,
-or test_postresql. For more information, checkout the full array of rake tasks with "rake -T"
-
-Rake can be found at http://rake.rubyforge.org
-
-== Running by hand
-
-Unit tests are located in test directory. If you only want to run a single test suite,
-or don't want to bother with Rake, you can do so with something like:
-
- cd test; ruby -I "connections/native_mysql" base_test.rb
-
-That'll run the base suite using the MySQL-Ruby adapter. Change the adapter
-and test suite name as needed.
-
-== Faster tests
-
-If you are using a database that supports transactions, you can set the
-"AR_TX_FIXTURES" environment variable to "yes" to use transactional fixtures.
-This gives a very large speed boost. With rake:
-
- rake AR_TX_FIXTURES=yes
-
-Or, by hand:
-
- AR_TX_FIXTURES=yes ruby -I connections/native_sqlite3 base_test.rb
diff --git a/vendor/plugins/acts_as_versioned/Rakefile b/vendor/plugins/acts_as_versioned/Rakefile
deleted file mode 100644
index 3ae69e961..000000000
--- a/vendor/plugins/acts_as_versioned/Rakefile
+++ /dev/null
@@ -1,182 +0,0 @@
-require 'rubygems'
-
-Gem::manage_gems
-
-require 'rake/rdoctask'
-require 'rake/packagetask'
-require 'rake/gempackagetask'
-require 'rake/testtask'
-require 'rake/contrib/rubyforgepublisher'
-
-PKG_NAME = 'acts_as_versioned'
-PKG_VERSION = '0.3.1'
-PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
-PROD_HOST = "technoweenie@bidwell.textdrive.com"
-RUBY_FORGE_PROJECT = 'ar-versioned'
-RUBY_FORGE_USER = 'technoweenie'
-
-desc 'Default: run unit tests.'
-task :default => :test
-
-desc 'Test the calculations plugin.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
-end
-
-desc 'Generate documentation for the calculations plugin.'
-Rake::RDocTask.new(:rdoc) do |rdoc|
- rdoc.rdoc_dir = 'rdoc'
- rdoc.title = "#{PKG_NAME} -- Simple versioning with active record models"
- rdoc.options << '--line-numbers --inline-source'
- rdoc.rdoc_files.include('README', 'CHANGELOG', 'RUNNING_UNIT_TESTS')
- rdoc.rdoc_files.include('lib/**/*.rb')
-end
-
-spec = Gem::Specification.new do |s|
- s.name = PKG_NAME
- s.version = PKG_VERSION
- s.platform = Gem::Platform::RUBY
- s.summary = "Simple versioning with active record models"
- s.files = FileList["{lib,test}/**/*"].to_a + %w(README MIT-LICENSE CHANGELOG RUNNING_UNIT_TESTS)
- s.files.delete "acts_as_versioned_plugin.sqlite.db"
- s.files.delete "acts_as_versioned_plugin.sqlite3.db"
- s.files.delete "test/debug.log"
- s.require_path = 'lib'
- s.autorequire = 'acts_as_versioned'
- s.has_rdoc = true
- s.test_files = Dir['test/**/*_test.rb']
- s.add_dependency 'activerecord', '>= 1.10.1'
- s.add_dependency 'activesupport', '>= 1.1.1'
- s.author = "Rick Olson"
- s.email = "technoweenie@gmail.com"
- s.homepage = "http://techno-weenie.net"
-end
-
-Rake::GemPackageTask.new(spec) do |pkg|
- pkg.need_tar = true
-end
-
-desc "Publish the API documentation"
-task :pdoc => [:rdoc] do
- Rake::RubyForgePublisher.new(RUBY_FORGE_PROJECT, RUBY_FORGE_USER).upload
-end
-
-desc 'Publish the gem and API docs'
-task :publish => [:pdoc, :rubyforge_upload]
-
-desc "Publish the release files to RubyForge."
-task :rubyforge_upload => :package do
- files = %w(gem tgz).map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
-
- if RUBY_FORGE_PROJECT then
- require 'net/http'
- require 'open-uri'
-
- project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
- project_data = open(project_uri) { |data| data.read }
- group_id = project_data[/[?&]group_id=(\d+)/, 1]
- raise "Couldn't get group id" unless group_id
-
- # This echos password to shell which is a bit sucky
- if ENV["RUBY_FORGE_PASSWORD"]
- password = ENV["RUBY_FORGE_PASSWORD"]
- else
- print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
- password = STDIN.gets.chomp
- end
-
- login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
- data = [
- "login=1",
- "form_loginname=#{RUBY_FORGE_USER}",
- "form_pw=#{password}"
- ].join("&")
- http.post("/account/login.php", data)
- end
-
- cookie = login_response["set-cookie"]
- raise "Login failed" unless cookie
- headers = { "Cookie" => cookie }
-
- release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
- release_data = open(release_uri, headers) { |data| data.read }
- package_id = release_data[/[?&]package_id=(\d+)/, 1]
- raise "Couldn't get package id" unless package_id
-
- first_file = true
- release_id = ""
-
- files.each do |filename|
- basename = File.basename(filename)
- file_ext = File.extname(filename)
- file_data = File.open(filename, "rb") { |file| file.read }
-
- puts "Releasing #{basename}..."
-
- release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
- release_date = Time.now.strftime("%Y-%m-%d %H:%M")
- type_map = {
- ".zip" => "3000",
- ".tgz" => "3110",
- ".gz" => "3110",
- ".gem" => "1400"
- }; type_map.default = "9999"
- type = type_map[file_ext]
- boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
-
- query_hash = if first_file then
- {
- "group_id" => group_id,
- "package_id" => package_id,
- "release_name" => PKG_FILE_NAME,
- "release_date" => release_date,
- "type_id" => type,
- "processor_id" => "8000", # Any
- "release_notes" => "",
- "release_changes" => "",
- "preformatted" => "1",
- "submit" => "1"
- }
- else
- {
- "group_id" => group_id,
- "release_id" => release_id,
- "package_id" => package_id,
- "step2" => "1",
- "type_id" => type,
- "processor_id" => "8000", # Any
- "submit" => "Add This File"
- }
- end
-
- query = "?" + query_hash.map do |(name, value)|
- [name, URI.encode(value)].join("=")
- end.join("&")
-
- data = [
- "--" + boundary,
- "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
- "Content-Type: application/octet-stream",
- "Content-Transfer-Encoding: binary",
- "", file_data, ""
- ].join("\x0D\x0A")
-
- release_headers = headers.merge(
- "Content-Type" => "multipart/form-data; boundary=#{boundary}"
- )
-
- target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
- http.post(target + query, data, release_headers)
- end
-
- if first_file then
- release_id = release_response.body[/release_id=(\d+)/, 1]
- raise("Couldn't get release id") unless release_id
- end
-
- first_file = false
- end
- end
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/init.rb b/vendor/plugins/acts_as_versioned/init.rb
deleted file mode 100644
index 5937bbc7c..000000000
--- a/vendor/plugins/acts_as_versioned/init.rb
+++ /dev/null
@@ -1 +0,0 @@
-require 'acts_as_versioned' \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb b/vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb
deleted file mode 100644
index 5299e0dc7..000000000
--- a/vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb
+++ /dev/null
@@ -1,490 +0,0 @@
-# Copyright (c) 2005 Rick Olson
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-module ActiveRecord #:nodoc:
- module Acts #:nodoc:
- # Specify this act if you want to save a copy of the row in a versioned table. This assumes there is a
- # versioned table ready and that your model has a version field. This works with optimistic locking if the lock_version
- # column is present as well.
- #
- # The class for the versioned model is derived the first time it is seen. Therefore, if you change your database schema you have to restart
- # your container for the changes to be reflected. In development mode this usually means restarting WEBrick.
- #
- # class Page < ActiveRecord::Base
- # # assumes pages_versions table
- # acts_as_versioned
- # end
- #
- # Example:
- #
- # page = Page.create(:title => 'hello world!')
- # page.version # => 1
- #
- # page.title = 'hello world'
- # page.save
- # page.version # => 2
- # page.versions.size # => 2
- #
- # page.revert_to(1) # using version number
- # page.title # => 'hello world!'
- #
- # page.revert_to(page.versions.last) # using versioned instance
- # page.title # => 'hello world'
- #
- # page.versions.earliest # efficient query to find the first version
- # page.versions.latest # efficient query to find the most recently created version
- #
- #
- # Simple Queries to page between versions
- #
- # page.versions.before(version)
- # page.versions.after(version)
- #
- # Access the previous/next versions from the versioned model itself
- #
- # version = page.versions.latest
- # version.previous # go back one version
- # version.next # go forward one version
- #
- # See ActiveRecord::Acts::Versioned::ClassMethods#acts_as_versioned for configuration options
- module Versioned
- CALLBACKS = [:set_new_version, :save_version, :save_version?]
- def self.included(base) # :nodoc:
- base.extend ClassMethods
- end
-
- module ClassMethods
- # == Configuration options
- #
- # * <tt>class_name</tt> - versioned model class name (default: PageVersion in the above example)
- # * <tt>table_name</tt> - versioned model table name (default: page_versions in the above example)
- # * <tt>foreign_key</tt> - foreign key used to relate the versioned model to the original model (default: page_id in the above example)
- # * <tt>inheritance_column</tt> - name of the column to save the model's inheritance_column value for STI. (default: versioned_type)
- # * <tt>version_column</tt> - name of the column in the model that keeps the version number (default: version)
- # * <tt>sequence_name</tt> - name of the custom sequence to be used by the versioned model.
- # * <tt>limit</tt> - number of revisions to keep, defaults to unlimited
- # * <tt>if</tt> - symbol of method to check before saving a new version. If this method returns false, a new version is not saved.
- # For finer control, pass either a Proc or modify Model#version_condition_met?
- #
- # acts_as_versioned :if => Proc.new { |auction| !auction.expired? }
- #
- # or...
- #
- # class Auction
- # def version_condition_met? # totally bypasses the <tt>:if</tt> option
- # !expired?
- # end
- # end
- #
- # * <tt>if_changed</tt> - Simple way of specifying attributes that are required to be changed before saving a model. This takes
- # either a symbol or array of symbols. WARNING - This will attempt to overwrite any attribute setters you may have.
- # Use this instead if you want to write your own attribute setters (and ignore if_changed):
- #
- # def name=(new_name)
- # write_changed_attribute :name, new_name
- # end
- #
- # * <tt>extend</tt> - Lets you specify a module to be mixed in both the original and versioned models. You can also just pass a block
- # to create an anonymous mixin:
- #
- # class Auction
- # acts_as_versioned do
- # def started?
- # !started_at.nil?
- # end
- # end
- # end
- #
- # or...
- #
- # module AuctionExtension
- # def started?
- # !started_at.nil?
- # end
- # end
- # class Auction
- # acts_as_versioned :extend => AuctionExtension
- # end
- #
- # Example code:
- #
- # @auction = Auction.find(1)
- # @auction.started?
- # @auction.versions.first.started?
- #
- # == Database Schema
- #
- # The model that you're versioning needs to have a 'version' attribute. The model is versioned
- # into a table called #{model}_versions where the model name is singlular. The _versions table should
- # contain all the fields you want versioned, the same version column, and a #{model}_id foreign key field.
- #
- # A lock_version field is also accepted if your model uses Optimistic Locking. If your table uses Single Table inheritance,
- # then that field is reflected in the versioned model as 'versioned_type' by default.
- #
- # Acts_as_versioned comes prepared with the ActiveRecord::Acts::Versioned::ActMethods::ClassMethods#create_versioned_table
- # method, perfect for a migration. It will also create the version column if the main model does not already have it.
- #
- # class AddVersions < ActiveRecord::Migration
- # def self.up
- # # create_versioned_table takes the same options hash
- # # that create_table does
- # Post.create_versioned_table
- # end
- #
- # def self.down
- # Post.drop_versioned_table
- # end
- # end
- #
- # == Changing What Fields Are Versioned
- #
- # By default, acts_as_versioned will version all but these fields:
- #
- # [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column]
- #
- # You can add or change those by modifying #non_versioned_columns. Note that this takes strings and not symbols.
- #
- # class Post < ActiveRecord::Base
- # acts_as_versioned
- # self.non_versioned_columns << 'comments_count'
- # end
- #
- def acts_as_versioned(options = {}, &extension)
- # don't allow multiple calls
- return if self.included_modules.include?(ActiveRecord::Acts::Versioned::ActMethods)
-
- send :include, ActiveRecord::Acts::Versioned::ActMethods
-
- cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name, :versioned_inheritance_column,
- :version_column, :max_version_limit, :track_altered_attributes, :version_condition, :version_sequence_name, :non_versioned_columns,
- :version_association_options, :version_if_changed
-
- self.versioned_class_name = options[:class_name] || "Version"
- self.versioned_foreign_key = options[:foreign_key] || self.to_s.foreign_key
- self.versioned_table_name = options[:table_name] || "#{table_name_prefix}#{base_class.name.demodulize.underscore}_versions#{table_name_suffix}"
- self.versioned_inheritance_column = options[:inheritance_column] || "versioned_#{inheritance_column}"
- self.version_column = options[:version_column] || 'version'
- self.version_sequence_name = options[:sequence_name]
- self.max_version_limit = options[:limit].to_i
- self.version_condition = options[:if] || true
- self.non_versioned_columns = [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column, 'created_at', 'created_on']
- self.version_association_options = {
- :class_name => "#{self.to_s}::#{versioned_class_name}",
- :foreign_key => versioned_foreign_key,
- :dependent => :delete_all
- }.merge(options[:association_options] || {})
-
- if block_given?
- extension_module_name = "#{versioned_class_name}Extension"
- silence_warnings do
- self.const_set(extension_module_name, Module.new(&extension))
- end
-
- options[:extend] = self.const_get(extension_module_name)
- end
-
- class_eval do
- has_many :versions, version_association_options do
- # finds earliest version of this record
- def earliest
- @earliest ||= find(:first, :order => 'version')
- end
-
- # find latest version of this record
- def latest
- @latest ||= find(:first, :order => 'version desc')
- end
- end
- before_save :set_new_version
- after_save :save_version
- after_save :clear_old_versions
-
- unless options[:if_changed].nil?
- self.track_altered_attributes = true
- options[:if_changed] = [options[:if_changed]] unless options[:if_changed].is_a?(Array)
- self.version_if_changed = options[:if_changed]
- end
-
- include options[:extend] if options[:extend].is_a?(Module)
- end
-
- # create the dynamic versioned model
- const_set(versioned_class_name, Class.new(ActiveRecord::Base)).class_eval do
- def self.reloadable? ; false ; end
- # find first version before the given version
- def self.before(version)
- find :first, :order => 'version desc',
- :conditions => ["#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version]
- end
-
- # find first version after the given version.
- def self.after(version)
- find :first, :order => 'version',
- :conditions => ["#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version]
- end
-
- def previous
- self.class.before(self)
- end
-
- def next
- self.class.after(self)
- end
-
- def versions_count
- page.version
- end
- end
-
- versioned_class.cattr_accessor :original_class
- versioned_class.original_class = self
- versioned_class.set_table_name versioned_table_name
- versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym,
- :class_name => "::#{self.to_s}",
- :foreign_key => versioned_foreign_key
- versioned_class.send :include, options[:extend] if options[:extend].is_a?(Module)
- versioned_class.set_sequence_name version_sequence_name if version_sequence_name
- end
- end
-
- module ActMethods
- def self.included(base) # :nodoc:
- base.extend ClassMethods
- end
-
- # Saves a version of the model in the versioned table. This is called in the after_save callback by default
- def save_version
- if @saving_version
- @saving_version = nil
- rev = self.class.versioned_class.new
- clone_versioned_model(self, rev)
- rev.version = send(self.class.version_column)
- rev.send("#{self.class.versioned_foreign_key}=", id)
- rev.save
- end
- end
-
- # Clears old revisions if a limit is set with the :limit option in <tt>acts_as_versioned</tt>.
- # Override this method to set your own criteria for clearing old versions.
- def clear_old_versions
- return if self.class.max_version_limit == 0
- excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
- if excess_baggage > 0
- self.class.versioned_class.delete_all ["version <= ? and #{self.class.versioned_foreign_key} = ?", excess_baggage, id]
- end
- end
-
- # Reverts a model to a given version. Takes either a version number or an instance of the versioned model
- def revert_to(version)
- if version.is_a?(self.class.versioned_class)
- return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
- else
- return false unless version = versions.find_by_version(version)
- end
- self.clone_versioned_model(version, self)
- send("#{self.class.version_column}=", version.version)
- true
- end
-
- # Reverts a model to a given version and saves the model.
- # Takes either a version number or an instance of the versioned model
- def revert_to!(version)
- revert_to(version) ? save_without_revision : false
- end
-
- # Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.
- def save_without_revision
- save_without_revision!
- true
- rescue
- false
- end
-
- def save_without_revision!
- without_locking do
- without_revision do
- save!
- end
- end
- end
-
- def altered?
- track_altered_attributes ? (version_if_changed.map(&:to_s) - changed).length < version_if_changed.length : changed?
- end
-
- # Clones a model. Used when saving a new version or reverting a model's version.
- def clone_versioned_model(orig_model, new_model)
- self.class.versioned_columns.each do |col|
- new_model.send("#{col.name}=", orig_model.send(col.name)) if orig_model.has_attribute?(col.name)
- end
-
- if orig_model.is_a?(self.class.versioned_class)
- new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
- elsif new_model.is_a?(self.class.versioned_class)
- new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
- end
- end
-
- # Checks whether a new version shall be saved or not. Calls <tt>version_condition_met?</tt> and <tt>changed?</tt>.
- def save_version?
- version_condition_met? && altered?
- end
-
- # Checks condition set in the :if option to check whether a revision should be created or not. Override this for
- # custom version condition checking.
- def version_condition_met?
- case
- when version_condition.is_a?(Symbol)
- send(version_condition)
- when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
- version_condition.call(self)
- else
- version_condition
- end
- end
-
- # Executes the block with the versioning callbacks disabled.
- #
- # @foo.without_revision do
- # @foo.save
- # end
- #
- def without_revision(&block)
- self.class.without_revision(&block)
- end
-
- # Turns off optimistic locking for the duration of the block
- #
- # @foo.without_locking do
- # @foo.save
- # end
- #
- def without_locking(&block)
- self.class.without_locking(&block)
- end
-
- def empty_callback() end #:nodoc:
-
- protected
- # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
- def set_new_version
- @saving_version = new_record? || save_version?
- self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
- end
-
- # Gets the next available version for the current record, or 1 for a new record
- def next_version
- (new_record? ? 0 : versions.calculate(:max, :version).to_i) + 1
- end
-
- module ClassMethods
- # Returns an array of columns that are versioned. See non_versioned_columns
- def versioned_columns
- @versioned_columns ||= columns.select { |c| !non_versioned_columns.include?(c.name) }
- end
-
- # Returns an instance of the dynamic versioned model
- def versioned_class
- const_get versioned_class_name
- end
-
- # Rake migration task to create the versioned table using options passed to acts_as_versioned
- def create_versioned_table(create_table_options = {})
- # create version column in main table if it does not exist
- if !self.content_columns.find { |c| %w(version lock_version).include? c.name }
- self.connection.add_column table_name, :version, :integer
- end
-
- self.connection.create_table(versioned_table_name, create_table_options) do |t|
- t.column versioned_foreign_key, :integer
- t.column :version, :integer
- end
-
- updated_col = nil
- self.versioned_columns.each do |col|
- updated_col = col if !updated_col && %(updated_at updated_on).include?(col.name)
- self.connection.add_column versioned_table_name, col.name, col.type,
- :limit => col.limit,
- :default => col.default,
- :scale => col.scale,
- :precision => col.precision
- end
-
- if type_col = self.columns_hash[inheritance_column]
- self.connection.add_column versioned_table_name, versioned_inheritance_column, type_col.type,
- :limit => type_col.limit,
- :default => type_col.default,
- :scale => type_col.scale,
- :precision => type_col.precision
- end
-
- if updated_col.nil?
- self.connection.add_column versioned_table_name, :updated_at, :timestamp
- end
- end
-
- # Rake migration task to drop the versioned table
- def drop_versioned_table
- self.connection.drop_table versioned_table_name
- end
-
- # Executes the block with the versioning callbacks disabled.
- #
- # Foo.without_revision do
- # @foo.save
- # end
- #
- def without_revision(&block)
- class_eval do
- CALLBACKS.each do |attr_name|
- alias_method "orig_#{attr_name}".to_sym, attr_name
- alias_method attr_name, :empty_callback
- end
- end
- block.call
- ensure
- class_eval do
- CALLBACKS.each do |attr_name|
- alias_method attr_name, "orig_#{attr_name}".to_sym
- end
- end
- end
-
- # Turns off optimistic locking for the duration of the block
- #
- # Foo.without_locking do
- # @foo.save
- # end
- #
- def without_locking(&block)
- current = ActiveRecord::Base.lock_optimistically
- ActiveRecord::Base.lock_optimistically = false if current
- result = block.call
- ActiveRecord::Base.lock_optimistically = true if current
- result
- end
- end
- end
- end
- end
-end
-
-ActiveRecord::Base.send :include, ActiveRecord::Acts::Versioned \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/abstract_unit.rb b/vendor/plugins/acts_as_versioned/test/abstract_unit.rb
deleted file mode 100644
index 269667ad0..000000000
--- a/vendor/plugins/acts_as_versioned/test/abstract_unit.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-$:.unshift(File.dirname(__FILE__) + '/../../../rails/activesupport/lib')
-$:.unshift(File.dirname(__FILE__) + '/../../../rails/activerecord/lib')
-$:.unshift(File.dirname(__FILE__) + '/../lib')
-require 'test/unit'
-begin
- require 'active_support'
- require 'active_record'
- require 'active_record/fixtures'
-rescue LoadError
- require 'rubygems'
- retry
-end
-
-begin
- require 'ruby-debug'
- Debugger.start
-rescue LoadError
-end
-
-require 'acts_as_versioned'
-
-config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
-ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
-ActiveRecord::Base.configurations = {'test' => config[ENV['DB'] || 'sqlite3']}
-ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
-
-load(File.dirname(__FILE__) + "/schema.rb")
-
-# set up custom sequence on widget_versions for DBs that support sequences
-if ENV['DB'] == 'postgresql'
- ActiveRecord::Base.connection.execute "DROP SEQUENCE widgets_seq;" rescue nil
- ActiveRecord::Base.connection.remove_column :widget_versions, :id
- ActiveRecord::Base.connection.execute "CREATE SEQUENCE widgets_seq START 101;"
- ActiveRecord::Base.connection.execute "ALTER TABLE widget_versions ADD COLUMN id INTEGER PRIMARY KEY DEFAULT nextval('widgets_seq');"
-end
-
-Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
-$:.unshift(Test::Unit::TestCase.fixture_path)
-
-class Test::Unit::TestCase #:nodoc:
- # Turn off transactional fixtures if you're working with MyISAM tables in MySQL
- self.use_transactional_fixtures = true
-
- # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
- self.use_instantiated_fixtures = false
-
- # Add more helper methods to be used by all tests here...
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/database.yml b/vendor/plugins/acts_as_versioned/test/database.yml
deleted file mode 100644
index 506e6bd37..000000000
--- a/vendor/plugins/acts_as_versioned/test/database.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-sqlite:
- :adapter: sqlite
- :dbfile: acts_as_versioned_plugin.sqlite.db
-sqlite3:
- :adapter: sqlite3
- :dbfile: acts_as_versioned_plugin.sqlite3.db
-postgresql:
- :adapter: postgresql
- :username: postgres
- :password: postgres
- :database: acts_as_versioned_plugin_test
- :min_messages: ERROR
-mysql:
- :adapter: mysql
- :host: localhost
- :username: rails
- :password:
- :database: acts_as_versioned_plugin_test \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/authors.yml b/vendor/plugins/acts_as_versioned/test/fixtures/authors.yml
deleted file mode 100644
index bd7a5aed6..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/authors.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-caged:
- id: 1
- name: caged
-mly:
- id: 2
- name: mly \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/landmark.rb b/vendor/plugins/acts_as_versioned/test/fixtures/landmark.rb
deleted file mode 100644
index cb9b93057..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/landmark.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-class Landmark < ActiveRecord::Base
- acts_as_versioned :if_changed => [ :name, :longitude, :latitude ]
-end
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml b/vendor/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml
deleted file mode 100644
index 2dbd54ed2..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-washington:
- id: 1
- landmark_id: 1
- version: 1
- name: Washington, D.C.
- latitude: 38.895
- longitude: -77.036667
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/landmarks.yml b/vendor/plugins/acts_as_versioned/test/fixtures/landmarks.yml
deleted file mode 100644
index cf0639006..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/landmarks.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-washington:
- id: 1
- name: Washington, D.C.
- latitude: 38.895
- longitude: -77.036667
- doesnt_trigger_version: This is not important
- version: 1
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages.yml b/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages.yml
deleted file mode 100644
index 318e776cb..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-welcome:
- id: 1
- title: Welcome to the weblog
- lock_version: 24
- type: LockedPage
-thinking:
- id: 2
- title: So I was thinking
- lock_version: 24
- type: SpecialLockedPage
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml b/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml
deleted file mode 100644
index 5c978e629..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-welcome_1:
- id: 1
- page_id: 1
- title: Welcome to the weblg
- version: 23
- version_type: LockedPage
-
-welcome_2:
- id: 2
- page_id: 1
- title: Welcome to the weblog
- version: 24
- version_type: LockedPage
-
-thinking_1:
- id: 3
- page_id: 2
- title: So I was thinking!!!
- version: 23
- version_type: SpecialLockedPage
-
-thinking_2:
- id: 4
- page_id: 2
- title: So I was thinking
- version: 24
- version_type: SpecialLockedPage
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb b/vendor/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb
deleted file mode 100644
index 5007b16ad..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddVersionedTables < ActiveRecord::Migration
- def self.up
- create_table("things") do |t|
- t.column :title, :text
- t.column :price, :decimal, :precision => 7, :scale => 2
- t.column :type, :string
- end
- Thing.create_versioned_table
- end
-
- def self.down
- Thing.drop_versioned_table
- drop_table "things" rescue nil
- end
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/page.rb b/vendor/plugins/acts_as_versioned/test/fixtures/page.rb
deleted file mode 100644
index f133e351a..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/page.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-class Page < ActiveRecord::Base
- belongs_to :author
- has_many :authors, :through => :versions, :order => 'name'
- belongs_to :revisor, :class_name => 'Author'
- has_many :revisors, :class_name => 'Author', :through => :versions, :order => 'name'
- acts_as_versioned :if => :feeling_good? do
- def self.included(base)
- base.cattr_accessor :feeling_good
- base.feeling_good = true
- base.belongs_to :author
- base.belongs_to :revisor, :class_name => 'Author'
- end
-
- def feeling_good?
- @@feeling_good == true
- end
- end
-end
-
-module LockedPageExtension
- def hello_world
- 'hello_world'
- end
-end
-
-class LockedPage < ActiveRecord::Base
- acts_as_versioned \
- :inheritance_column => :version_type,
- :foreign_key => :page_id,
- :table_name => :locked_pages_revisions,
- :class_name => 'LockedPageRevision',
- :version_column => :lock_version,
- :limit => 2,
- :if_changed => :title,
- :extend => LockedPageExtension
-end
-
-class SpecialLockedPage < LockedPage
-end
-
-class Author < ActiveRecord::Base
- has_many :pages
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/page_versions.yml b/vendor/plugins/acts_as_versioned/test/fixtures/page_versions.yml
deleted file mode 100644
index ef565fa4f..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/page_versions.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-welcome_2:
- id: 1
- page_id: 1
- title: Welcome to the weblog
- body: Such a lovely day
- version: 24
- author_id: 1
- revisor_id: 1
-welcome_1:
- id: 2
- page_id: 1
- title: Welcome to the weblg
- body: Such a lovely day
- version: 23
- author_id: 2
- revisor_id: 2
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/pages.yml b/vendor/plugins/acts_as_versioned/test/fixtures/pages.yml
deleted file mode 100644
index 9f4ab546a..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/pages.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-welcome:
- id: 1
- title: Welcome to the weblog
- body: Such a lovely day
- version: 24
- author_id: 1
- revisor_id: 1
- created_on: "2008-01-01 00:00:00" \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/fixtures/widget.rb b/vendor/plugins/acts_as_versioned/test/fixtures/widget.rb
deleted file mode 100644
index 086ac2b40..000000000
--- a/vendor/plugins/acts_as_versioned/test/fixtures/widget.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class Widget < ActiveRecord::Base
- acts_as_versioned :sequence_name => 'widgets_seq', :association_options => {
- :dependent => :nullify, :order => 'version desc'
- }
- non_versioned_columns << 'foo'
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_versioned/test/migration_test.rb b/vendor/plugins/acts_as_versioned/test/migration_test.rb
deleted file mode 100644
index 47a7537ce..000000000
--- a/vendor/plugins/acts_as_versioned/test/migration_test.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require File.join(File.dirname(__FILE__), 'abstract_unit')
-
-if ActiveRecord::Base.connection.supports_migrations?
- class Thing < ActiveRecord::Base
- attr_accessor :version
- acts_as_versioned
- end
-
- class MigrationTest < Test::Unit::TestCase
- self.use_transactional_fixtures = false
- def teardown
- if ActiveRecord::Base.connection.respond_to?(:initialize_schema_information)
- ActiveRecord::Base.connection.initialize_schema_information
- ActiveRecord::Base.connection.update "UPDATE schema_info SET version = 0"
- else
- ActiveRecord::Base.connection.initialize_schema_migrations_table
- ActiveRecord::Base.connection.assume_migrated_upto_version(0)
- end
-
- Thing.connection.drop_table "things" rescue nil
- Thing.connection.drop_table "thing_versions" rescue nil
- Thing.reset_column_information
- end
-
- def test_versioned_migration
- assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
- # take 'er up
- ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/')
- t = Thing.create :title => 'blah blah', :price => 123.45, :type => 'Thing'
- assert_equal 1, t.versions.size
-
- # check that the price column has remembered its value correctly
- assert_equal t.price, t.versions.first.price
- assert_equal t.title, t.versions.first.title
- assert_equal t[:type], t.versions.first[:type]
-
- # make sure that the precision of the price column has been preserved
- assert_equal 7, Thing::Version.columns.find{|c| c.name == "price"}.precision
- assert_equal 2, Thing::Version.columns.find{|c| c.name == "price"}.scale
-
- # now lets take 'er back down
- ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/')
- assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
- end
- end
-end
diff --git a/vendor/plugins/acts_as_versioned/test/schema.rb b/vendor/plugins/acts_as_versioned/test/schema.rb
deleted file mode 100644
index 4e7e96319..000000000
--- a/vendor/plugins/acts_as_versioned/test/schema.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-ActiveRecord::Schema.define(:version => 0) do
- create_table :pages, :force => true do |t|
- t.column :version, :integer
- t.column :title, :string, :limit => 255
- t.column :body, :text
- t.column :created_on, :datetime
- t.column :updated_on, :datetime
- t.column :author_id, :integer
- t.column :revisor_id, :integer
- end
-
- create_table :page_versions, :force => true do |t|
- t.column :page_id, :integer
- t.column :version, :integer
- t.column :title, :string, :limit => 255
- t.column :body, :text
- t.column :created_on, :datetime
- t.column :updated_on, :datetime
- t.column :author_id, :integer
- t.column :revisor_id, :integer
- end
-
- add_index :page_versions, [:page_id, :version], :unique => true
-
- create_table :authors, :force => true do |t|
- t.column :page_id, :integer
- t.column :name, :string
- end
-
- create_table :locked_pages, :force => true do |t|
- t.column :lock_version, :integer
- t.column :title, :string, :limit => 255
- t.column :type, :string, :limit => 255
- end
-
- create_table :locked_pages_revisions, :force => true do |t|
- t.column :page_id, :integer
- t.column :version, :integer
- t.column :title, :string, :limit => 255
- t.column :version_type, :string, :limit => 255
- t.column :updated_at, :datetime
- end
-
- add_index :locked_pages_revisions, [:page_id, :version], :unique => true
-
- create_table :widgets, :force => true do |t|
- t.column :name, :string, :limit => 50
- t.column :foo, :string
- t.column :version, :integer
- t.column :updated_at, :datetime
- end
-
- create_table :widget_versions, :force => true do |t|
- t.column :widget_id, :integer
- t.column :name, :string, :limit => 50
- t.column :version, :integer
- t.column :updated_at, :datetime
- end
-
- add_index :widget_versions, [:widget_id, :version], :unique => true
-
- create_table :landmarks, :force => true do |t|
- t.column :name, :string
- t.column :latitude, :float
- t.column :longitude, :float
- t.column :doesnt_trigger_version,:string
- t.column :version, :integer
- end
-
- create_table :landmark_versions, :force => true do |t|
- t.column :landmark_id, :integer
- t.column :name, :string
- t.column :latitude, :float
- t.column :longitude, :float
- t.column :doesnt_trigger_version,:string
- t.column :version, :integer
- end
-
- add_index :landmark_versions, [:landmark_id, :version], :unique => true
-end
diff --git a/vendor/plugins/acts_as_versioned/test/versioned_test.rb b/vendor/plugins/acts_as_versioned/test/versioned_test.rb
deleted file mode 100644
index 6ab9e739c..000000000
--- a/vendor/plugins/acts_as_versioned/test/versioned_test.rb
+++ /dev/null
@@ -1,352 +0,0 @@
-require File.join(File.dirname(__FILE__), 'abstract_unit')
-require File.join(File.dirname(__FILE__), 'fixtures/page')
-require File.join(File.dirname(__FILE__), 'fixtures/widget')
-
-class VersionedTest < Test::Unit::TestCase
- fixtures :pages, :page_versions, :locked_pages, :locked_pages_revisions, :authors, :landmarks, :landmark_versions
- set_fixture_class :page_versions => Page::Version
-
- def test_saves_versioned_copy
- p = Page.create! :title => 'first title', :body => 'first body'
- assert !p.new_record?
- assert_equal 1, p.versions.size
- assert_equal 1, p.version
- assert_instance_of Page.versioned_class, p.versions.first
- end
-
- def test_version_has_unique_created_at
- p = pages(:welcome)
- p.title = 'update me'
- p.save!
- assert_not_equal p.created_on, p.versions.latest.created_on
- end
-
- def test_saves_without_revision
- p = pages(:welcome)
- old_versions = p.versions.count
-
- p.save_without_revision
-
- p.without_revision do
- p.update_attributes :title => 'changed'
- end
-
- assert_equal old_versions, p.versions.count
- end
-
- def test_rollback_with_version_number
- p = pages(:welcome)
- assert_equal 24, p.version
- assert_equal 'Welcome to the weblog', p.title
-
- assert p.revert_to!(23), "Couldn't revert to 23"
- assert_equal 23, p.version
- assert_equal 'Welcome to the weblg', p.title
- end
-
- def test_versioned_class_name
- assert_equal 'Version', Page.versioned_class_name
- assert_equal 'LockedPageRevision', LockedPage.versioned_class_name
- end
-
- def test_versioned_class
- assert_equal Page::Version, Page.versioned_class
- assert_equal LockedPage::LockedPageRevision, LockedPage.versioned_class
- end
-
- def test_special_methods
- assert_nothing_raised { pages(:welcome).feeling_good? }
- assert_nothing_raised { pages(:welcome).versions.first.feeling_good? }
- assert_nothing_raised { locked_pages(:welcome).hello_world }
- assert_nothing_raised { locked_pages(:welcome).versions.first.hello_world }
- end
-
- def test_rollback_with_version_class
- p = pages(:welcome)
- assert_equal 24, p.version
- assert_equal 'Welcome to the weblog', p.title
-
- assert p.revert_to!(p.versions.find_by_version(23)), "Couldn't revert to 23"
- assert_equal 23, p.version
- assert_equal 'Welcome to the weblg', p.title
- end
-
- def test_rollback_fails_with_invalid_revision
- p = locked_pages(:welcome)
- assert !p.revert_to!(locked_pages(:thinking))
- end
-
- def test_saves_versioned_copy_with_options
- p = LockedPage.create! :title => 'first title'
- assert !p.new_record?
- assert_equal 1, p.versions.size
- assert_instance_of LockedPage.versioned_class, p.versions.first
- end
-
- def test_rollback_with_version_number_with_options
- p = locked_pages(:welcome)
- assert_equal 'Welcome to the weblog', p.title
- assert_equal 'LockedPage', p.versions.first.version_type
-
- assert p.revert_to!(p.versions.first.version), "Couldn't revert to 23"
- assert_equal 'Welcome to the weblg', p.title
- assert_equal 'LockedPage', p.versions.first.version_type
- end
-
- def test_rollback_with_version_class_with_options
- p = locked_pages(:welcome)
- assert_equal 'Welcome to the weblog', p.title
- assert_equal 'LockedPage', p.versions.first.version_type
-
- assert p.revert_to!(p.versions.first), "Couldn't revert to 1"
- assert_equal 'Welcome to the weblg', p.title
- assert_equal 'LockedPage', p.versions.first.version_type
- end
-
- def test_saves_versioned_copy_with_sti
- p = SpecialLockedPage.create! :title => 'first title'
- assert !p.new_record?
- assert_equal 1, p.versions.size
- assert_instance_of LockedPage.versioned_class, p.versions.first
- assert_equal 'SpecialLockedPage', p.versions.first.version_type
- end
-
- def test_rollback_with_version_number_with_sti
- p = locked_pages(:thinking)
- assert_equal 'So I was thinking', p.title
-
- assert p.revert_to!(p.versions.first.version), "Couldn't revert to 1"
- assert_equal 'So I was thinking!!!', p.title
- assert_equal 'SpecialLockedPage', p.versions.first.version_type
- end
-
- def test_lock_version_works_with_versioning
- p = locked_pages(:thinking)
- p2 = LockedPage.find(p.id)
-
- p.title = 'fresh title'
- p.save
- assert_equal 2, p.versions.size # limit!
-
- assert_raises(ActiveRecord::StaleObjectError) do
- p2.title = 'stale title'
- p2.save
- end
- end
-
- def test_version_if_condition
- p = Page.create! :title => "title"
- assert_equal 1, p.version
-
- Page.feeling_good = false
- p.save
- assert_equal 1, p.version
- Page.feeling_good = true
- end
-
- def test_version_if_condition2
- # set new if condition
- Page.class_eval do
- def new_feeling_good() title[0..0] == 'a'; end
- alias_method :old_feeling_good, :feeling_good?
- alias_method :feeling_good?, :new_feeling_good
- end
-
- p = Page.create! :title => "title"
- assert_equal 1, p.version # version does not increment
- assert_equal 1, p.versions.count
-
- p.update_attributes(:title => 'new title')
- assert_equal 1, p.version # version does not increment
- assert_equal 1, p.versions.count
-
- p.update_attributes(:title => 'a title')
- assert_equal 2, p.version
- assert_equal 2, p.versions.count
-
- # reset original if condition
- Page.class_eval { alias_method :feeling_good?, :old_feeling_good }
- end
-
- def test_version_if_condition_with_block
- # set new if condition
- old_condition = Page.version_condition
- Page.version_condition = Proc.new { |page| page.title[0..0] == 'b' }
-
- p = Page.create! :title => "title"
- assert_equal 1, p.version # version does not increment
- assert_equal 1, p.versions.count
-
- p.update_attributes(:title => 'a title')
- assert_equal 1, p.version # version does not increment
- assert_equal 1, p.versions.count
-
- p.update_attributes(:title => 'b title')
- assert_equal 2, p.version
- assert_equal 2, p.versions.count
-
- # reset original if condition
- Page.version_condition = old_condition
- end
-
- def test_version_no_limit
- p = Page.create! :title => "title", :body => 'first body'
- p.save
- p.save
- 5.times do |i|
- p.title = "title#{i}"
- p.save
- assert_equal "title#{i}", p.title
- assert_equal (i+2), p.version
- end
- end
-
- def test_version_max_limit
- p = LockedPage.create! :title => "title"
- p.update_attributes(:title => "title1")
- p.update_attributes(:title => "title2")
- 5.times do |i|
- p.title = "title#{i}"
- p.save
- assert_equal "title#{i}", p.title
- assert_equal (i+4), p.lock_version
- assert p.versions(true).size <= 2, "locked version can only store 2 versions"
- end
- end
-
- def test_track_altered_attributes_default_value
- assert !Page.track_altered_attributes
- assert LockedPage.track_altered_attributes
- assert SpecialLockedPage.track_altered_attributes
- end
-
- def test_track_altered_attributes
- p = LockedPage.create! :title => "title"
- assert_equal 1, p.lock_version
- assert_equal 1, p.versions(true).size
-
- p.title = 'title'
- assert !p.save_version?
- p.save
- assert_equal 2, p.lock_version # still increments version because of optimistic locking
- assert_equal 1, p.versions(true).size
-
- p.title = 'updated title'
- assert p.save_version?
- p.save
- assert_equal 3, p.lock_version
- assert_equal 1, p.versions(true).size # version 1 deleted
-
- p.title = 'updated title!'
- assert p.save_version?
- p.save
- assert_equal 4, p.lock_version
- assert_equal 2, p.versions(true).size # version 1 deleted
- end
-
- def test_find_versions
- assert_equal 1, locked_pages(:welcome).versions.find(:all, :conditions => ['title LIKE ?', '%weblog%']).size
- end
-
- def test_find_version
- assert_equal page_versions(:welcome_1), pages(:welcome).versions.find_by_version(23)
- end
-
- def test_with_sequence
- assert_equal 'widgets_seq', Widget.versioned_class.sequence_name
- 3.times { Widget.create! :name => 'new widget' }
- assert_equal 3, Widget.count
- assert_equal 3, Widget.versioned_class.count
- end
-
- def test_has_many_through
- assert_equal [authors(:caged), authors(:mly)], pages(:welcome).authors
- end
-
- def test_has_many_through_with_custom_association
- assert_equal [authors(:caged), authors(:mly)], pages(:welcome).revisors
- end
-
- def test_referential_integrity
- pages(:welcome).destroy
- assert_equal 0, Page.count
- assert_equal 0, Page::Version.count
- end
-
- def test_association_options
- association = Page.reflect_on_association(:versions)
- options = association.options
- assert_equal :delete_all, options[:dependent]
-
- association = Widget.reflect_on_association(:versions)
- options = association.options
- assert_equal :nullify, options[:dependent]
- assert_equal 'version desc', options[:order]
- assert_equal 'widget_id', options[:foreign_key]
-
- widget = Widget.create! :name => 'new widget'
- assert_equal 1, Widget.count
- assert_equal 1, Widget.versioned_class.count
- widget.destroy
- assert_equal 0, Widget.count
- assert_equal 1, Widget.versioned_class.count
- end
-
- def test_versioned_records_should_belong_to_parent
- page = pages(:welcome)
- page_version = page.versions.last
- assert_equal page, page_version.page
- end
-
- def test_unaltered_attributes
- landmarks(:washington).attributes = landmarks(:washington).attributes.except("id")
- assert !landmarks(:washington).changed?
- end
-
- def test_unchanged_string_attributes
- landmarks(:washington).attributes = landmarks(:washington).attributes.except("id").inject({}) { |params, (key, value)| params.update(key => value.to_s) }
- assert !landmarks(:washington).changed?
- end
-
- def test_should_find_earliest_version
- assert_equal page_versions(:welcome_1), pages(:welcome).versions.earliest
- end
-
- def test_should_find_latest_version
- assert_equal page_versions(:welcome_2), pages(:welcome).versions.latest
- end
-
- def test_should_find_previous_version
- assert_equal page_versions(:welcome_1), page_versions(:welcome_2).previous
- assert_equal page_versions(:welcome_1), pages(:welcome).versions.before(page_versions(:welcome_2))
- end
-
- def test_should_find_next_version
- assert_equal page_versions(:welcome_2), page_versions(:welcome_1).next
- assert_equal page_versions(:welcome_2), pages(:welcome).versions.after(page_versions(:welcome_1))
- end
-
- def test_should_find_version_count
- assert_equal 2, pages(:welcome).versions.size
- end
-
- def test_if_changed_creates_version_if_a_listed_column_is_changed
- landmarks(:washington).name = "Washington"
- assert landmarks(:washington).changed?
- assert landmarks(:washington).altered?
- end
-
- def test_if_changed_creates_version_if_all_listed_columns_are_changed
- landmarks(:washington).name = "Washington"
- landmarks(:washington).latitude = 1.0
- landmarks(:washington).longitude = 1.0
- assert landmarks(:washington).changed?
- assert landmarks(:washington).altered?
- end
-
- def test_if_changed_does_not_create_new_version_if_unlisted_column_is_changed
- landmarks(:washington).doesnt_trigger_version = "This should not trigger version"
- assert landmarks(:washington).changed?
- assert !landmarks(:washington).altered?
- end
-end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_xapian/init.rb b/vendor/plugins/acts_as_xapian/init.rb
index 36b43ac0b..1e5b8557b 100644
--- a/vendor/plugins/acts_as_xapian/init.rb
+++ b/vendor/plugins/acts_as_xapian/init.rb
@@ -1,7 +1,7 @@
# acts_as_xapian/init.rb:
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
require 'acts_as_xapian'
diff --git a/vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb b/vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb
index 374fcd65b..725f53512 100644
--- a/vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb
+++ b/vendor/plugins/acts_as_xapian/lib/acts_as_xapian.rb
@@ -2,7 +2,7 @@
# Xapian full text search in Ruby on Rails.
#
# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
#
# Documentation
# =============
@@ -88,11 +88,11 @@ module ActsAsXapian
return unless @@db_path.nil?
# barf if we can't figure out the environment
- environment = (ENV['RAILS_ENV'] or RAILS_ENV)
+ environment = (ENV['RAILS_ENV'] or Rails.env)
raise "Set RAILS_ENV, so acts_as_xapian can find the right Xapian database" if not environment
# check for a config file
- config_file = RAILS_ROOT + "/config/xapian.yml"
+ config_file = Rails.root.to_s + "/config/xapian.yml"
@@config = File.exists?(config_file) ? YAML.load_file(config_file)[environment] : {}
# figure out where the DBs should go
@@ -717,8 +717,16 @@ module ActsAsXapian
if not $?.success?
raise "batch fork child failed, exiting also"
end
- # database connection doesn't survive a fork, rebuild it
- ActiveRecord::Base.connection.reconnect!
+
+ # FIXME: Under Rails 3.1 we get "SSL error: decryption failed or bad record mac", this works around it
+ retry_count = 0
+ begin
+ # database connection doesn't survive a fork, rebuild it
+ ActiveRecord::Base.connection.reconnect!
+ rescue
+ retry_count += 1
+ retry_count > 3 ? raise : retry
+ end
else
# fully reopen the database each time (with a new object)
@@ -758,7 +766,7 @@ module ActsAsXapian
else
values = []
for locale in self.translations.map{|x| x.locale}
- self.class.with_locale(locale) do
+ I18n.with_locale(locale) do
values << single_xapian_value(field, type=type)
end
end
diff --git a/vendor/plugins/exception_notification/README b/vendor/plugins/exception_notification/README
deleted file mode 100644
index d5e343630..000000000
--- a/vendor/plugins/exception_notification/README
+++ /dev/null
@@ -1,144 +0,0 @@
-= Exception Notifier Plugin for Rails
-
-The Exception Notifier plugin provides a mailer object and a default set of
-templates for sending email notifications when errors occur in a Rails
-application. The plugin is configurable, allowing programmers to specify:
-
-* the sender address of the email
-* the recipient addresses
-* the text used to prefix the subject line
-
-The email includes information about the current request, session, and
-environment, and also gives a backtrace of the exception.
-
-== Usage
-
-First, include the ExceptionNotifiable mixin in whichever controller you want
-to generate error emails (typically ApplicationController):
-
- class ApplicationController < ActionController::Base
- include ExceptionNotification::Notifiable
- ...
- end
-
-Then, specify the email recipients in your environment:
-
- ExceptionNotification::Notifier.exception_recipients = %w(joe@schmoe.com bill@schmoe.com)
-
-And that's it! The defaults take care of the rest.
-
-== Configuration
-
-You can tweak other values to your liking, as well. In your environment file,
-just set any or all of the following values:
-
- # defaults to exception.notifier@default.com
- ExceptionNotification::Notifier.sender_address =
- %("Application Error" <app.error@myapp.com>)
-
- # defaults to "[ERROR] "
- ExceptionNotification::Notifier.email_prefix = "[APP] "
-
-Even if you have mixed into ApplicationController you can skip notification in
-some controllers by
-
- class MyController < ApplicationController
- skip_exception_notifications
- end
-
-== Deprecated local_request? overriding
-
-Email notifications will only occur when the IP address is determined not to
-be local. You can specify certain addresses to always be local so that you'll
-get a detailed error instead of the generic error page. You do this in your
-controller (or even per-controller):
-
- consider_local "64.72.18.143", "14.17.21.25"
-
-You can specify subnet masks as well, so that all matching addresses are
-considered local:
-
- consider_local "64.72.18.143/24"
-
-The address "127.0.0.1" is always considered local. If you want to completely
-reset the list of all addresses (for instance, if you wanted "127.0.0.1" to
-NOT be considered local), you can simply do, somewhere in your controller:
-
- local_addresses.clear
-
-NOTE: The above functionality has has been pulled out to consider_local.rb,
-as interfering with rails local determination is orthogonal to notification,
-unnecessarily clutters backtraces, and even occasionally errs on odd ip or
-requests bugs. To return original functionality add an initializer with:
-
- ActionController::Base.send :include, ConsiderLocal
-
-or just include it per controller that wants it
-
- class MyController < ApplicationController
- include ExceptionNotification::ConsiderLocal
- end
-
-== Customization
-
-By default, the notification email includes four parts: request, session,
-environment, and backtrace (in that order). You can customize how each of those
-sections are rendered by placing a partial named for that part in your
-app/views/exception_notifier directory (e.g., _session.rhtml). Each partial has
-access to the following variables:
-
-* @controller: the controller that caused the error
-* @request: the current request object
-* @exception: the exception that was raised
-* @host: the name of the host that made the request
-* @backtrace: a sanitized version of the exception's backtrace
-* @rails_root: a sanitized version of RAILS_ROOT
-* @data: a hash of optional data values that were passed to the notifier
-* @sections: the array of sections to include in the email
-
-You can reorder the sections, or exclude sections completely, by altering the
-ExceptionNotification::Notifier.sections variable. You can even add new sections that
-describe application-specific data--just add the section's name to the list
-(whereever you'd like), and define the corresponding partial. Then, if your
-new section requires information that isn't available by default, make sure
-it is made available to the email using the exception_data macro:
-
- class ApplicationController < ActionController::Base
- ...
- protected
- exception_data :additional_data
-
- def additional_data
- { :document => @document,
- :person => @person }
- end
- ...
- end
-
-In the above case, @document and @person would be made available to the email
-renderer, allowing your new section(s) to access and display them. See the
-existing sections defined by the plugin for examples of how to write your own.
-
-== 404s errors
-
-Notification is skipped if you return a 404 status, which happens by default
-for an ActiveRecord::RecordNotFound or ActionController::UnknownAction error.
-
-== Manually notifying of error in a rescue block
-
-If your controller action manually handles an error, the notifier will never be
-run. To manually notify of an error call notify_about_exception from within the
-rescue block
-
- def index
- #risky operation here
- rescue StandardError => error
- #custom error handling here
- notify_about_exception(error)
- end
-
-== Support and tickets
-
-https://rails.lighthouseapp.com/projects/8995-rails-plugins
-
-Copyright (c) 2005 Jamis Buck, released under the MIT license \ No newline at end of file
diff --git a/vendor/plugins/exception_notification/exception_notification.gemspec b/vendor/plugins/exception_notification/exception_notification.gemspec
deleted file mode 100644
index b3ff82322..000000000
--- a/vendor/plugins/exception_notification/exception_notification.gemspec
+++ /dev/null
@@ -1,11 +0,0 @@
-Gem::Specification.new do |s|
- s.name = 'exception_notification'
- s.version = '2.3.3.0'
- s.authors = ["Jamis Buck", "Josh Peek", "Tim Connor"]
- s.date = %q{2010-03-13}
- s.summary = "Exception notification by email for Rails apps - 2.3-stable compatible version"
- s.email = "timocratic@gmail.com"
-
- s.files = ['README'] + Dir['lib/**/*'] + Dir['views/**/*']
- s.require_path = 'lib'
-end
diff --git a/vendor/plugins/exception_notification/init.rb b/vendor/plugins/exception_notification/init.rb
deleted file mode 100644
index ef215f809..000000000
--- a/vendor/plugins/exception_notification/init.rb
+++ /dev/null
@@ -1 +0,0 @@
-require "exception_notification"
diff --git a/vendor/plugins/exception_notification/lib/exception_notification.rb b/vendor/plugins/exception_notification/lib/exception_notification.rb
deleted file mode 100644
index bf5975201..000000000
--- a/vendor/plugins/exception_notification/lib/exception_notification.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-require "action_mailer"
-module ExceptionNotification
- autoload :Notifiable, 'exception_notification/notifiable'
- autoload :Notifier, 'exception_notification/notifier'
- #autoload :NotifierHelper, 'exception_notification/notifier_helper'
- autoload :ConsiderLocal, 'exception_notification/consider_local'
-end \ No newline at end of file
diff --git a/vendor/plugins/exception_notification/lib/exception_notification/consider_local.rb b/vendor/plugins/exception_notification/lib/exception_notification/consider_local.rb
deleted file mode 100644
index 6b9e236f7..000000000
--- a/vendor/plugins/exception_notification/lib/exception_notification/consider_local.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-#This didn't belong on ExceptionNotifier and made backtraces worse. To keep original functionality in place
-#'ActionController::Base.send :include, ExceptionNotification::ConsiderLocal' or just include in your controller
-module ExceptionNotification::ConsiderLocal
- def self.included(target)
- require 'ipaddr'
- target.extend(ClassMethods)
- end
-
- module ClassMethods
- def consider_local(*args)
- local_addresses.concat(args.flatten.map { |a| IPAddr.new(a) })
- end
-
- def local_addresses
- addresses = read_inheritable_attribute(:local_addresses)
- unless addresses
- addresses = [IPAddr.new("127.0.0.1")]
- write_inheritable_attribute(:local_addresses, addresses)
- end
- addresses
- end
- end
-
-private
-
- def local_request?
- remote = IPAddr.new(request.remote_ip)
- !self.class.local_addresses.detect { |addr| addr.include?(remote) }.nil?
- end
-
-end
diff --git a/vendor/plugins/exception_notification/lib/exception_notification/notifiable.rb b/vendor/plugins/exception_notification/lib/exception_notification/notifiable.rb
deleted file mode 100644
index 19895e8db..000000000
--- a/vendor/plugins/exception_notification/lib/exception_notification/notifiable.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (c) 2005 Jamis Buck
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-module ExceptionNotification::Notifiable
- def self.included(target)
- target.extend(ClassMethods)
- target.skip_exception_notifications false
- end
-
- module ClassMethods
- def exception_data(deliverer=self)
- if deliverer == self
- read_inheritable_attribute(:exception_data)
- else
- write_inheritable_attribute(:exception_data, deliverer)
- end
- end
-
- def skip_exception_notifications(boolean=true)
- write_inheritable_attribute(:skip_exception_notifications, boolean)
- end
-
- def skip_exception_notifications?
- read_inheritable_attribute(:skip_exception_notifications)
- end
- end
-
-private
-
- def rescue_action_in_public(exception)
- super
- notify_about_exception(exception) if deliver_exception_notification?
- end
-
- def deliver_exception_notification?
- !self.class.skip_exception_notifications? && ![404, "404 Not Found"].include?(response.status.to_s)
- end
-
- def notify_about_exception(exception)
- deliverer = self.class.exception_data
- data = case deliverer
- when nil then {}
- when Symbol then send(deliverer)
- when Proc then deliverer.call(self)
- end
-
- ExceptionNotification::Notifier.deliver_exception_notification(exception, self, request, data)
- end
-end
diff --git a/vendor/plugins/exception_notification/lib/exception_notification/notifier.rb b/vendor/plugins/exception_notification/lib/exception_notification/notifier.rb
deleted file mode 100644
index 2cab3f963..000000000
--- a/vendor/plugins/exception_notification/lib/exception_notification/notifier.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-require 'pathname'
-
-# Copyright (c) 2005 Jamis Buck
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-class ExceptionNotification::Notifier < ActionMailer::Base
- self.mailer_name = 'exception_notifier'
- self.view_paths << "#{File.dirname(__FILE__)}/../../views"
-
- # next line is a hack to fix
- # undefined method `find_template' for #<Array:0x000001009cd230>
- # after Rails 2.3.8 -> 2.3.11 upgrade
- self.view_paths = ActionView::PathSet.new(self.view_paths) unless self.view_paths.respond_to?(:find_template)
-
- @@sender_address = %("Exception Notifier" <exception.notifier@default.com>)
- cattr_accessor :sender_address
-
- @@exception_recipients = []
- cattr_accessor :exception_recipients
-
- @@email_prefix = "[ERROR] "
- cattr_accessor :email_prefix
-
- @@sections = %w(request session environment backtrace)
- cattr_accessor :sections
-
- def self.reloadable?() false end
-
- def exception_notification(exception, controller, request, data={})
- source = self.class.exception_source(controller)
- content_type "text/plain"
-
- subject "#{email_prefix}#{source} (#{exception.class}) #{exception.message.inspect}"
-
- recipients exception_recipients
- from sender_address
-
- body data.merge({ :controller => controller, :request => request,
- :exception => exception, :exception_source => source, :host => (request.env["HTTP_X_FORWARDED_HOST"] || request.env["HTTP_HOST"]),
- :backtrace => sanitize_backtrace(exception.backtrace),
- :rails_root => rails_root, :data => data,
- :sections => sections })
- end
-
- def self.exception_source(controller)
- if controller.respond_to?(:controller_name)
- "in #{controller.controller_name}##{controller.action_name}"
- else
- "outside of a controller"
- end
- end
-
-private
-
- def sanitize_backtrace(trace)
- re = Regexp.new(/^#{Regexp.escape(rails_root)}/)
- trace.map { |line| Pathname.new(line.gsub(re, "[RAILS_ROOT]")).cleanpath.to_s }
- end
-
- def rails_root
- @rails_root ||= Pathname.new(RAILS_ROOT).cleanpath.to_s
- end
-end
diff --git a/vendor/plugins/exception_notification/lib/exception_notification/notifier_helper.rb b/vendor/plugins/exception_notification/lib/exception_notification/notifier_helper.rb
deleted file mode 100644
index 942e1c527..000000000
--- a/vendor/plugins/exception_notification/lib/exception_notification/notifier_helper.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-require 'pp'
-
-# Copyright (c) 2005 Jamis Buck
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-module ExceptionNotification::NotifierHelper
- PARAM_FILTER_REPLACEMENT = "[FILTERED]"
-
- def render_section(section)
- RAILS_DEFAULT_LOGGER.info("rendering section #{section.inspect}")
- summary = render("exception_notifier/#{section}").strip
- unless summary.blank?
- title = render("exception_notifier/title", :locals => { :title => section }).strip
- "#{title}\n\n#{summary.gsub(/^/, " ")}\n\n"
- end
- end
-
- def inspect_model_object(model, locals={})
- render('exception_notifier/inspect_model',
- :locals => { :inspect_model => model,
- :show_instance_variables => true,
- :show_attributes => true }.merge(locals))
- end
-
- def inspect_value(value)
- len = 512
- result = object_to_yaml(value).gsub(/\n/, "\n ").strip
- result = result[0,len] + "... (#{result.length-len} bytes more)" if result.length > len+20
- result
- end
-
- def object_to_yaml(object)
- object.to_yaml.sub(/^---\s*/m, "")
- end
-
- def exclude_raw_post_parameters?
- @controller && @controller.respond_to?(:filter_parameters)
- end
-
- def filter_sensitive_post_data_parameters(parameters)
- exclude_raw_post_parameters? ? @controller.__send__(:filter_parameters, parameters) : parameters
- end
-
- def filter_sensitive_post_data_from_env(env_key, env_value)
- return env_value unless exclude_raw_post_parameters?
- return PARAM_FILTER_REPLACEMENT if (env_key =~ /RAW_POST_DATA/i)
- return @controller.__send__(:filter_parameters, {env_key => env_value}).values[0]
- end
-
-end
diff --git a/vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb b/vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb
deleted file mode 100644
index e077f405b..000000000
--- a/vendor/plugins/exception_notification/test/exception_notifier_helper_test.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-require 'test_helper'
-require 'exception_notification/notifier_helper'
-
-class ExceptionNotifierHelperTest < Test::Unit::TestCase
-
- class ExceptionNotifierHelperIncludeTarget
- include ExceptionNotification::NotifierHelper
- end
-
- def setup
- @helper = ExceptionNotifierHelperIncludeTarget.new
- end
-
- # No controller
-
- def test_should_not_exclude_raw_post_parameters_if_no_controller
- assert !@helper.exclude_raw_post_parameters?
- end
-
- # Controller, no filtering
-
- class ControllerWithoutFilterParameters; end
-
- def test_should_not_filter_env_values_for_raw_post_data_keys_if_controller_can_not_filter_parameters
- stub_controller(ControllerWithoutFilterParameters.new)
- assert @helper.filter_sensitive_post_data_from_env("RAW_POST_DATA", "secret").include?("secret")
- end
- def test_should_not_exclude_raw_post_parameters_if_controller_can_not_filter_parameters
- stub_controller(ControllerWithoutFilterParameters.new)
- assert !@helper.exclude_raw_post_parameters?
- end
- def test_should_return_params_if_controller_can_not_filter_parameters
- stub_controller(ControllerWithoutFilterParameters.new)
- assert_equal :params, @helper.filter_sensitive_post_data_parameters(:params)
- end
-
- # Controller with filtering
-
- class ControllerWithFilterParameters
- def filter_parameters(params)
- { "PARAM" => ExceptionNotification::NotifierHelper::PARAM_FILTER_REPLACEMENT }
- end
- end
-
- def test_should_filter_env_values_for_raw_post_data_keys_if_controller_can_filter_parameters
- stub_controller(ControllerWithFilterParameters.new)
- assert !@helper.filter_sensitive_post_data_from_env("RAW_POST_DATA", "secret").include?("secret")
- end
- def test_should_exclude_raw_post_parameters_if_controller_can_filter_parameters
- stub_controller(ControllerWithFilterParameters.new)
- assert @helper.exclude_raw_post_parameters?
- end
- def test_should_delegate_param_filtering_to_controller_if_controller_can_filter_parameters
- stub_controller(ControllerWithFilterParameters.new)
- assert_equal({"PARAM" => "[FILTERED]" }, @helper.filter_sensitive_post_data_parameters({"PARAM" => 'secret'}))
- end
-
- private
- def stub_controller(controller)
- @helper.instance_variable_set(:@controller, controller)
- end
-end \ No newline at end of file
diff --git a/vendor/plugins/exception_notification/test/test_helper.rb b/vendor/plugins/exception_notification/test/test_helper.rb
deleted file mode 100644
index 5831a1784..000000000
--- a/vendor/plugins/exception_notification/test/test_helper.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'test/unit'
-require 'rubygems'
-require 'active_support'
-
-RAILS_ROOT = '.' unless defined?(RAILS_ROOT)
-
-$:.unshift File.join(File.dirname(__FILE__), '../lib')
-require 'exception_notification' \ No newline at end of file
diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml
deleted file mode 100644
index 7d13ba007..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_backtrace.rhtml
+++ /dev/null
@@ -1 +0,0 @@
-<%= @backtrace.join "\n" %>
diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml
deleted file mode 100644
index 42dd803f1..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_environment.rhtml
+++ /dev/null
@@ -1,7 +0,0 @@
-<% max = @request.env.keys.max { |a,b| a.length <=> b.length } -%>
-<% @request.env.keys.sort.each do |key| -%>
-* <%= "%-*s: %s" % [max.length, key, filter_sensitive_post_data_from_env(key, @request.env[key].to_s.strip)] %>
-<% end -%>
-
-* Process: <%= $$ %>
-* Server : <%= `hostname -s`.chomp %>
diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml
deleted file mode 100644
index e817847e4..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_inspect_model.rhtml
+++ /dev/null
@@ -1,16 +0,0 @@
-<% if show_attributes -%>
-[attributes]
-<% attrs = inspect_model.attributes -%>
-<% max = attrs.keys.max { |a,b| a.length <=> b.length } -%>
-<% attrs.keys.sort.each do |attr| -%>
-* <%= "%*-s: %s" % [max.length, attr, object_to_yaml(attrs[attr]).gsub(/\n/, "\n ").strip] %>
-<% end -%>
-<% end -%>
-
-<% if show_instance_variables -%>
-[instance variables]
-<% inspect_model.instance_variables.sort.each do |variable| -%>
-<%- next if variable == "@attributes" -%>
-* <%= variable %>: <%= inspect_value(inspect_model.instance_variable_get(variable)) %>
-<% end -%>
-<% end -%>
diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml
deleted file mode 100644
index 25423093f..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_request.rhtml
+++ /dev/null
@@ -1,4 +0,0 @@
-* URL : <%= @request.protocol %><%= @host %><%= @request.request_uri %>
-* IP address: <%= @request.env["HTTP_X_FORWARDED_FOR"] || @request.env["REMOTE_ADDR"] %>
-* Parameters: <%= filter_sensitive_post_data_parameters(@request.parameters).inspect %>
-* Rails root: <%= @rails_root %>
diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml
deleted file mode 100644
index 308684885..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_session.rhtml
+++ /dev/null
@@ -1,2 +0,0 @@
-* session id: <%= @request.session_options[:id] %>
-* data: <%= @request.session.inspect %> \ No newline at end of file
diff --git a/vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml
deleted file mode 100644
index 1ed5a3f2b..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/_title.rhtml
+++ /dev/null
@@ -1,3 +0,0 @@
--------------------------------
-<%= title.to_s.humanize %>:
--------------------------------
diff --git a/vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml b/vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml
deleted file mode 100644
index 715c105bf..000000000
--- a/vendor/plugins/exception_notification/views/exception_notifier/exception_notification.rhtml
+++ /dev/null
@@ -1,6 +0,0 @@
-A <%= @exception.class %> occurred <%= @exception_source %>:
-
- <%= @exception.message %>
- <%= @backtrace.first %>
-
-<%= @sections.map { |section| render_section(section) }.join %>
diff --git a/vendor/plugins/globalize2/LICENSE b/vendor/plugins/globalize2/LICENSE
deleted file mode 100644
index 94a6b8160..000000000
--- a/vendor/plugins/globalize2/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License
-
-Copyright (c) 2008, 2009 Joshua Harvey
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE. \ No newline at end of file
diff --git a/vendor/plugins/globalize2/README.textile b/vendor/plugins/globalize2/README.textile
deleted file mode 100644
index e47e9bf37..000000000
--- a/vendor/plugins/globalize2/README.textile
+++ /dev/null
@@ -1,86 +0,0 @@
-h1. Globalize2
-
-Globalize2 is the successor of Globalize for Rails.
-
-It is compatible with and builds on the new "I18n api in Ruby on Rails":http://guides.rubyonrails.org/i18n.html. and adds model translations to ActiveRecord.
-
-Globalize2 is much more lightweight and compatible than its predecessor was. Model translations in Globalize2 use default ActiveRecord features and do not limit any ActiveRecord functionality any more.
-
-h2. Requirements
-
-ActiveRecord
-I18n
-
-(or Rails > 2.2)
-
-h2. Installation
-
-To install Globalize2 with its default setup just use:
-
-<pre><code>
-script/plugin install git://github.com/joshmh/globalize2.git
-</code></pre>
-
-h2. Model translations
-
-Model translations allow you to translate your models' attribute values. E.g.
-
-<pre><code>
-class Post < ActiveRecord::Base
- translates :title, :text
-end
-</code></pre>
-
-Allows you to values for the attributes :title and :text per locale:
-
-<pre><code>
-I18n.locale = :en
-post.title # => Globalize2 rocks!
-
-I18n.locale = :he
-post.title # => גלובאלייז2 שולט!
-</code></pre>
-
-In order to make this work, you'll need to add the appropriate translation tables. Globalize2 comes with a handy helper method to help you do this. It's called @create_translation_table!@. Here's an example:
-
-<pre><code>
-class CreatePosts < ActiveRecord::Migration
- def self.up
- create_table :posts do |t|
- t.timestamps
- end
- Post.create_translation_table! :title => :string, :text => :text
- end
- def self.down
- drop_table :posts
- Post.drop_translation_table!
- end
-end
-</code></pre>
-
-Note that the ActiveRecord model @Post@ must already exist and have a @translates@ directive listing the translated fields.
-
-h2. Migration from Globalize
-
-See this script by Tomasz Stachewicz: http://gist.github.com/120867
-
-h2. Changes since Globalize2 v0.1.0
-
-* The association globalize_translations has been renamed to translations.
-
-h2. Alternative Solutions
-
-* "Veger's fork":http://github.com/veger/globalize2 - uses default AR schema for the default locale, delegates to the translations table for other locales only
-* "TranslatableColumns":http://github.com/iain/translatable_columns - have multiple languages of the same attribute in a model (Iain Hecker)
-* "localized_record":http://github.com/glennpow/localized_record - allows records to have localized attributes without any modifications to the database (Glenn Powell)
-* "model_translations":http://github.com/janne/model_translations - Minimal implementation of Globalize2 style model translations (Jan Andersson)
-
-h2. Related solutions
-
-* "globalize2_versioning":http://github.com/joshmh/globalize2_versioning - acts_as_versioned style versioning for Globalize2 (Joshua Harvey)
-* "i18n_multi_locales_validations":http://github.com/ZenCocoon/i18n_multi_locales_validations - multi-locales attributes validations to validates attributes from Globalize2 translations models (Sébastien Grosjean)
-* "Globalize2 Demo App":http://github.com/svenfuchs/globalize2-demo - demo application for Globalize2 (Sven Fuchs)</li>
-* "migrate_from_globalize1":http://gist.github.com/120867 - migrate model translations from Globalize1 to Globalize2 (Tomasz Stachewicz)</li>
-* "easy_globalize2_accessors":http://github.com/astropanic/easy_globalize2_accessors - easily access (read and write) globalize2-translated fields (astropanic, Tomasz Stachewicz)</li>
-* "globalize2-easy-translate":http://github.com/bsamman/globalize2-easy-translate - adds methods to easily access or set translated attributes to your model (bsamman)</li>
-* "batch_translations":http://github.com/alvarezrilla/batch_translations - allow saving multiple Globalize2 translations in the same request (Jose Alvarez Rilla)</li>
diff --git a/vendor/plugins/globalize2/Rakefile b/vendor/plugins/globalize2/Rakefile
deleted file mode 100644
index bc35dada4..000000000
--- a/vendor/plugins/globalize2/Rakefile
+++ /dev/null
@@ -1,39 +0,0 @@
-require 'rake'
-require 'rake/testtask'
-require 'rake/rdoctask'
-
-desc 'Default: run unit tests.'
-task :default => :test
-
-desc 'Test the globalize2 plugin.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
-end
-
-desc 'Generate documentation for the globalize2 plugin.'
-Rake::RDocTask.new(:rdoc) do |rdoc|
- rdoc.rdoc_dir = 'rdoc'
- rdoc.title = 'Globalize2'
- rdoc.options << '--line-numbers' << '--inline-source'
- rdoc.rdoc_files.include('README')
- rdoc.rdoc_files.include('lib/**/*.rb')
-end
-
-begin
- require 'jeweler'
- Jeweler::Tasks.new do |s|
- s.name = "globalize2"
- s.summary = "Rails I18n: de-facto standard library for ActiveRecord data translation"
- s.description = "Rails I18n: de-facto standard library for ActiveRecord data translation"
- s.email = "joshmh@gmail.com"
- s.homepage = "http://github.com/joshmh/globalize2"
- # s.rubyforge_project = ''
- s.authors = ["Sven Fuchs, Joshua Harvey, Clemens Kofler, John-Paul Bader"]
- # s.add_development_dependency ''
- end
- Jeweler::GemcutterTasks.new
-rescue LoadError
- puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
-end
diff --git a/vendor/plugins/globalize2/VERSION b/vendor/plugins/globalize2/VERSION
deleted file mode 100644
index 0c62199f1..000000000
--- a/vendor/plugins/globalize2/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-0.2.1
diff --git a/vendor/plugins/globalize2/generators/db_backend.rb b/vendor/plugins/globalize2/generators/db_backend.rb
deleted file mode 100644
index e69de29bb..000000000
--- a/vendor/plugins/globalize2/generators/db_backend.rb
+++ /dev/null
diff --git a/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb b/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb
deleted file mode 100644
index 0f0261113..000000000
--- a/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-class ActsAsTaggableMigration < ActiveRecord::Migration
- def self.up
- create_table :globalize_translations do |t|
- t.string :locale, :null => false
- t.string :key, :null => false
- t.string :translation
- t.timestamps
- end
-
-# TODO: FINISH DOING MIGRATION -- stopped in the middle
-
- create_table :globalize_translations_map do |t|
- t.string :key, :null => false
- t.integer :translation_id, :null => false
- end
-
- add_index :taggings, :tag_id
- add_index :taggings, [:taggable_id, :taggable_type]
- end
-
- def self.down
- drop_table :globalize_translations
- drop_table :tags
- end
-end
diff --git a/vendor/plugins/globalize2/globalize2.gemspec b/vendor/plugins/globalize2/globalize2.gemspec
deleted file mode 100644
index 89021115e..000000000
--- a/vendor/plugins/globalize2/globalize2.gemspec
+++ /dev/null
@@ -1,81 +0,0 @@
-# Generated by jeweler
-# DO NOT EDIT THIS FILE DIRECTLY
-# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
-# -*- encoding: utf-8 -*-
-
-Gem::Specification.new do |s|
- s.name = %q{globalize2}
- s.version = "0.2.0"
-
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
- s.authors = ["Sven Fuchs, Joshua Harvey, Clemens Kofler, John-Paul Bader"]
- s.date = %q{2010-04-22}
- s.description = %q{Rails I18n: de-facto standard library for ActiveRecord data translation}
- s.email = %q{joshmh@gmail.com}
- s.extra_rdoc_files = [
- "LICENSE",
- "README.textile"
- ]
- s.files = [
- ".gitignore",
- "LICENSE",
- "README.textile",
- "Rakefile",
- "VERSION",
- "generators/db_backend.rb",
- "generators/templates/db_backend_migration.rb",
- "globalize2.gemspec",
- "init.rb",
- "lib/globalize.rb",
- "lib/globalize/active_record.rb",
- "lib/globalize/active_record/adapter.rb",
- "lib/globalize/active_record/attributes.rb",
- "lib/globalize/active_record/migration.rb",
- "lib/i18n/missing_translations_log_handler.rb",
- "lib/i18n/missing_translations_raise_handler.rb",
- "test/active_record/fallbacks_test.rb",
- "test/active_record/migration_test.rb",
- "test/active_record/sti_translated_test.rb",
- "test/active_record/translates_test.rb",
- "test/active_record/translation_class_test.rb",
- "test/active_record/validation_tests.rb",
- "test/active_record_test.rb",
- "test/all.rb",
- "test/data/models.rb",
- "test/data/no_globalize_schema.rb",
- "test/data/schema.rb",
- "test/i18n/missing_translations_test.rb",
- "test/test_helper.rb"
- ]
- s.homepage = %q{http://github.com/joshmh/globalize2}
- s.rdoc_options = ["--charset=UTF-8"]
- s.require_paths = ["lib"]
- s.rubygems_version = %q{1.3.6}
- s.summary = %q{Rails I18n: de-facto standard library for ActiveRecord data translation}
- s.test_files = [
- "test/active_record/fallbacks_test.rb",
- "test/active_record/migration_test.rb",
- "test/active_record/sti_translated_test.rb",
- "test/active_record/translates_test.rb",
- "test/active_record/translation_class_test.rb",
- "test/active_record/validation_tests.rb",
- "test/active_record_test.rb",
- "test/all.rb",
- "test/data/models.rb",
- "test/data/no_globalize_schema.rb",
- "test/data/schema.rb",
- "test/i18n/missing_translations_test.rb",
- "test/test_helper.rb"
- ]
-
- if s.respond_to? :specification_version then
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
- s.specification_version = 3
-
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
- else
- end
- else
- end
-end
-
diff --git a/vendor/plugins/globalize2/init.rb b/vendor/plugins/globalize2/init.rb
deleted file mode 100644
index a4089251b..000000000
--- a/vendor/plugins/globalize2/init.rb
+++ /dev/null
@@ -1 +0,0 @@
-require 'globalize'
diff --git a/vendor/plugins/globalize2/lib/globalize.rb b/vendor/plugins/globalize2/lib/globalize.rb
deleted file mode 100644
index 67c1878ec..000000000
--- a/vendor/plugins/globalize2/lib/globalize.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module Globalize
- autoload :ActiveRecord, 'globalize/active_record'
-
- class << self
- def fallbacks?
- I18n.respond_to?(:fallbacks)
- end
-
- def fallbacks(locale)
- fallbacks? ? I18n.fallbacks[locale] : [locale.to_sym]
- end
- end
-end
-
-ActiveRecord::Base.send(:include, Globalize::ActiveRecord)
diff --git a/vendor/plugins/globalize2/lib/globalize/active_record.rb b/vendor/plugins/globalize2/lib/globalize/active_record.rb
deleted file mode 100644
index 3095bfe28..000000000
--- a/vendor/plugins/globalize2/lib/globalize/active_record.rb
+++ /dev/null
@@ -1,238 +0,0 @@
-module Globalize
- class MigrationError < StandardError; end
- class MigrationMissingTranslatedField < MigrationError; end
- class BadMigrationFieldType < MigrationError; end
-
- module ActiveRecord
- autoload :Adapter, 'globalize/active_record/adapter'
- autoload :Attributes, 'globalize/active_record/attributes'
- autoload :Migration, 'globalize/active_record/migration'
-
- def self.included(base)
- base.extend ActMacro
- end
-
- class << self
- def build_translation_class(target, options)
- options[:table_name] ||= "#{target.table_name.singularize}_translations"
-
- klass = target.const_defined?(:Translation) ?
- target.const_get(:Translation) :
- target.const_set(:Translation, Class.new(::ActiveRecord::Base))
-
- klass.class_eval do
- set_table_name(options[:table_name])
- belongs_to target.name.underscore.gsub('/', '_')
- def locale; read_attribute(:locale).to_sym; end
- def locale=(locale); write_attribute(:locale, locale.to_s); end
- end
-
- klass
- end
- end
-
- module ActMacro
- def locale
- (defined?(@@locale) && @@locale)
- end
-
- def locale=(locale)
- @@locale = locale
- end
-
- def translates(*attr_names)
- return if translates?
- options = attr_names.extract_options!
-
- class_inheritable_accessor :translation_class, :translated_attribute_names
- class_inheritable_writer :required_attributes
- self.translation_class = ActiveRecord.build_translation_class(self, options)
- self.translated_attribute_names = attr_names.map(&:to_sym)
-
- include InstanceMethods
- extend ClassMethods, Migration
-
- after_save :save_translations!
- ActiveSupport::Deprecation.silence do
- # Silence the warning that :class_name is deprecated and will be
- # removed in Rails 3, since it clutters up e.g. test output, and
- # there is nothing obvious that we can replace it with in Rails 2.
-
- has_many :translations, :class_name => translation_class.name,
- :foreign_key => class_name.foreign_key,
- :dependent => :delete_all,
- :extend => HasManyExtensions
- end
-
- named_scope :with_translations, lambda { |locale|
- conditions = required_attributes.map do |attribute|
- "#{quoted_translation_table_name}.#{attribute} IS NOT NULL"
- end
- conditions << "#{quoted_translation_table_name}.locale = ?"
- { :include => :translations, :conditions => [conditions.join(' AND '), locale] }
- }
-
- attr_names.each { |attr_name| translated_attr_accessor(attr_name) }
- end
-
- def translates?
- included_modules.include?(InstanceMethods)
- end
- end
-
- module HasManyExtensions
- def by_locale(locale)
- first(:conditions => { :locale => locale.to_s })
- end
-
- def by_locales(locales)
- all(:conditions => { :locale => locales.map(&:to_s) })
- end
- end
-
- module ClassMethods
- delegate :set_translation_table_name, :to => :translation_class
-
- def with_locale(locale)
- begin
- previous_locale, self.locale = self.locale, locale
- result = yield
- ensure
- self.locale = previous_locale
- end
- result
- end
-
- def translation_table_name
- translation_class.table_name
- end
-
- def quoted_translation_table_name
- translation_class.quoted_table_name
- end
-
- def required_attributes
- @required_attributes ||= reflect_on_all_validations.select do |validation|
- validation.macro == :validates_presence_of && translated_attribute_names.include?(validation.name)
- end.map(&:name)
- end
-
- def respond_to?(method, *args, &block)
- method.to_s =~ /^find_by_(\w+)$/ && translated_attribute_names.include?($1.to_sym) || super
- end
-
- def method_missing(method, *args)
- if method.to_s =~ /^find_by_(\w+)$/ && translated_attribute_names.include?($1.to_sym)
- find_first_by_translated_attr_and_locales($1, args.first)
- elsif method.to_s =~ /^find_all_by_(\w+)$/ && translated_attribute_names.include?($1.to_sym)
- find_all_by_translated_attr_and_locales($1, args.first)
- else
- super
- end
- end
-
- protected
-
- def find_first_by_translated_attr_and_locales(name, value)
- query = "#{translated_attr_name(name)} = ? AND #{translated_attr_name('locale')} IN (?)"
- locales = Globalize.fallbacks(locale || I18n.locale).map(&:to_s)
- find(
- :first,
- :joins => :translations,
- :conditions => [query, value, locales],
- :readonly => false
- )
- end
-
- def find_all_by_translated_attr_and_locales(name, value)
- query = "#{translated_attr_name(name)} = ? AND #{translated_attr_name('locale')} IN (?)"
- locales = Globalize.fallbacks(locale || I18n.locale).map(&:to_s)
- find(
- :all,
- :joins => :translations,
- :conditions => [query, value, locales],
- :readonly => false
- )
- end
-
- def translated_attr_accessor(name)
- define_method "#{name}=", lambda { |value|
- globalize.write(self.class.locale || I18n.locale, name, value)
- self[name] = value
- }
- define_method name, lambda { |*args|
- globalize.fetch(args.first || self.class.locale || I18n.locale, name)
- }
- alias_method "#{name}_before_type_cast", name
- end
-
- def translated_attr_name(name)
- "#{translation_class.table_name}.#{name}"
- end
- end
-
- module InstanceMethods
- def globalize
- @globalize ||= Adapter.new self
- end
-
- def attributes
- self.attribute_names.inject({}) do |attrs, name|
- attrs[name] = read_attribute(name) ||
- (globalize.fetch(I18n.locale, name) rescue nil)
- attrs
- end
- end
-
- def attributes=(attributes, *args)
- if attributes.respond_to?(:delete) && locale = attributes.delete(:locale)
- self.class.with_locale(locale) { super }
- else
- super
- end
- end
-
- def attribute_names
- translated_attribute_names.map(&:to_s) + super
- end
-
- def available_locales
- translations.scoped(:select => 'DISTINCT locale').map(&:locale)
- end
-
- def translated_locales
- translations.map(&:locale)
- end
-
- def translated_attributes
- translated_attribute_names.inject({}) do |attributes, name|
- attributes.merge(name => send(name))
- end
- end
-
- def set_translations(options)
- options.keys.each do |locale|
- translation = translations.find_by_locale(locale.to_s) ||
- translations.build(:locale => locale.to_s)
- translation.update_attributes!(options[locale])
- end
- end
-
- def reload(options = nil)
- translated_attribute_names.each { |name| @attributes.delete(name.to_s) }
- globalize.reset
- super(options)
- end
-
- protected
-
- def save_translations!
- globalize.save_translations!
- end
- end
- end
-end
-
-def globalize_write(name, value)
- globalize.write(self.class.locale || I18n.locale, name, value)
-end
diff --git a/vendor/plugins/globalize2/lib/globalize/active_record/adapter.rb b/vendor/plugins/globalize2/lib/globalize/active_record/adapter.rb
deleted file mode 100644
index 12f89ec01..000000000
--- a/vendor/plugins/globalize2/lib/globalize/active_record/adapter.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-module Globalize
- module ActiveRecord
- class Adapter
- # The cache caches attributes that already were looked up for read access.
- # The stash keeps track of new or changed values that need to be saved.
- attr_reader :record, :cache, :stash
-
- def initialize(record)
- @record = record
- @cache = Attributes.new
- @stash = Attributes.new
- end
-
- def fetch(locale, attr_name)
- cache.contains?(locale, attr_name) ?
- cache.read(locale, attr_name) :
- cache.write(locale, attr_name, fetch_attribute(locale, attr_name))
- end
-
- def write(locale, attr_name, value)
- stash.write(locale, attr_name, value)
- cache.write(locale, attr_name, value)
- end
-
- def save_translations!
- stash.each do |locale, attrs|
- translation = record.translations.find_or_initialize_by_locale(locale.to_s)
- attrs.each { |attr_name, value| translation[attr_name] = value }
- translation.save!
- end
- stash.clear
- end
-
- def reset
- cache.clear
- # stash.clear
- end
-
- protected
-
- def fetch_translation(locale)
- locale = locale.to_sym
- record.translations.loaded? ? record.translations.detect { |t| t.locale == locale } :
- record.translations.by_locale(locale)
- end
-
- def fetch_translations(locale)
- # only query if not already included with :include => translations
- record.translations.loaded? ? record.translations :
- record.translations.by_locales(Globalize.fallbacks(locale))
- end
-
- def fetch_attribute(locale, attr_name)
- translations = fetch_translations(locale)
- value, requested_locale = nil, locale
-
- Globalize.fallbacks(locale).each do |fallback|
- translation = translations.detect { |t| t.locale == fallback }
- value = translation && translation.send(attr_name)
- locale = fallback && break if value
- end
-
- set_metadata(value, :locale => locale, :requested_locale => requested_locale)
- value
- end
-
- def set_metadata(object, metadata)
- if object.respond_to?(:translation_metadata)
- object.translation_metadata.merge!(meta_data)
- end
- end
-
- def translation_metadata_accessor(object)
- return if obj.respond_to?(:translation_metadata)
- class << object; attr_accessor :translation_metadata end
- object.translation_metadata ||= {}
- end
- end
- end
-end
diff --git a/vendor/plugins/globalize2/lib/globalize/active_record/attributes.rb b/vendor/plugins/globalize2/lib/globalize/active_record/attributes.rb
deleted file mode 100644
index 7bd923ce2..000000000
--- a/vendor/plugins/globalize2/lib/globalize/active_record/attributes.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# Helper class for storing values per locale. Used by Globalize::Adapter
-# to stash and cache attribute values.
-module Globalize
- module ActiveRecord
- class Attributes < Hash
- def [](locale)
- locale = locale.to_sym
- self[locale] = {} unless has_key?(locale)
- self.fetch(locale)
- end
-
- def contains?(locale, attr_name)
- self[locale].has_key?(attr_name)
- end
-
- def read(locale, attr_name)
- self[locale][attr_name]
- end
-
- def write(locale, attr_name, value)
- self[locale][attr_name] = value
- end
- end
- end
-end
diff --git a/vendor/plugins/globalize2/lib/globalize/active_record/migration.rb b/vendor/plugins/globalize2/lib/globalize/active_record/migration.rb
deleted file mode 100644
index fa63aed8c..000000000
--- a/vendor/plugins/globalize2/lib/globalize/active_record/migration.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-module Globalize
- module ActiveRecord
- module Migration
- def create_translation_table!(fields)
- translated_attribute_names.each do |f|
- raise MigrationMissingTranslatedField, "Missing translated field #{f}" unless fields[f]
- end
-
- fields.each do |name, type|
- if translated_attribute_names.include?(name) && ![:string, :text].include?(type)
- raise BadMigrationFieldType, "Bad field type for #{name}, should be :string or :text"
- end
- end
-
- self.connection.create_table(translation_table_name) do |t|
- t.references table_name.sub(/^#{table_name_prefix}/, "").singularize
- t.string :locale
- fields.each do |name, type|
- t.column name, type
- end
- t.timestamps
- end
-
- self.connection.add_index(
- translation_table_name,
- "#{table_name.sub(/^#{table_name_prefix}/, "").singularize}_id",
- :name => translation_index_name
- )
- end
-
- def translation_index_name
- require 'digest/sha1'
- # FIXME what's the max size of an index name?
- index_name = "index_#{translation_table_name}_on_#{self.table_name.singularize}_id"
- index_name.size < 50 ? index_name : "index_#{Digest::SHA1.hexdigest(index_name)}"
- end
-
- def drop_translation_table!
- self.connection.remove_index(translation_table_name, :name => translation_index_name) rescue nil
- self.connection.drop_table(translation_table_name)
- end
- end
- end
-end
diff --git a/vendor/plugins/globalize2/lib/i18n/missing_translations_log_handler.rb b/vendor/plugins/globalize2/lib/i18n/missing_translations_log_handler.rb
deleted file mode 100644
index 24c10890a..000000000
--- a/vendor/plugins/globalize2/lib/i18n/missing_translations_log_handler.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# A simple exception handler that behaves like the default exception handler
-# but additionally logs missing translations to a given log.
-#
-# Useful for identifying missing translations during testing.
-#
-# E.g.
-#
-# require 'globalize/i18n/missing_translations_log_handler'
-# I18n.missing_translations_logger = RAILS_DEFAULT_LOGGER
-# I18n.exception_handler = :missing_translations_log_handler
-#
-# To set up a different log file:
-#
-# logger = Logger.new("#{RAILS_ROOT}/log/missing_translations.log")
-# I18n.missing_translations_logger = logger
-
-module I18n
- @@missing_translations_logger = nil
-
- class << self
- def missing_translations_logger
- @@missing_translations_logger ||= begin
- require 'logger' unless defined?(Logger)
- Logger.new(STDOUT)
- end
- end
-
- def missing_translations_logger=(logger)
- @@missing_translations_logger = logger
- end
-
- def missing_translations_log_handler(exception, locale, key, options)
- if MissingTranslationData === exception
- missing_translations_logger.warn(exception.message)
- return exception.message
- else
- raise exception
- end
- end
- end
-end
diff --git a/vendor/plugins/globalize2/lib/i18n/missing_translations_raise_handler.rb b/vendor/plugins/globalize2/lib/i18n/missing_translations_raise_handler.rb
deleted file mode 100644
index 18237b151..000000000
--- a/vendor/plugins/globalize2/lib/i18n/missing_translations_raise_handler.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# A simple exception handler that behaves like the default exception handler
-# but also raises on missing translations.
-#
-# Useful for identifying missing translations during testing.
-#
-# E.g.
-#
-# require 'globalize/i18n/missing_translations_raise_handler'
-# I18n.exception_handler = :missing_translations_raise_handler
-module I18n
- class << self
- def missing_translations_raise_handler(exception, locale, key, options)
- raise exception
- end
- end
-end
-
-I18n.exception_handler = :missing_translations_raise_handler
-
-ActionView::Helpers::TranslationHelper.module_eval do
- def translate(key, options = {})
- I18n.translate(key, options)
- end
- alias :t :translate
-end
diff --git a/vendor/plugins/globalize2/test/active_record/fallbacks_test.rb b/vendor/plugins/globalize2/test/active_record/fallbacks_test.rb
deleted file mode 100644
index 449ec8b2b..000000000
--- a/vendor/plugins/globalize2/test/active_record/fallbacks_test.rb
+++ /dev/null
@@ -1,102 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-if I18n.respond_to?(:fallbacks)
- class TranslatedTest < ActiveSupport::TestCase
- def setup
- I18n.locale = :'en-US'
- I18n.fallbacks.clear
- reset_db!
- ActiveRecord::Base.locale = nil
- end
-
- def teardown
- I18n.fallbacks.clear
- end
-
- test "keeping one field in new locale when other field is changed" do
- I18n.fallbacks.map 'de-DE' => [ 'en-US' ]
- post = Post.create :subject => 'foo'
- I18n.locale = 'de-DE'
- post.content = 'bar'
- assert_equal 'foo', post.subject
- end
-
- test "modifying non-required field in a new locale" do
- I18n.fallbacks.map 'de-DE' => [ 'en-US' ]
- post = Post.create :subject => 'foo'
- I18n.locale = 'de-DE'
- post.content = 'bar'
- assert post.save
- end
-
- test "resolves a simple fallback" do
- I18n.locale = 'de-DE'
- post = Post.create :subject => 'foo'
- I18n.locale = 'de'
- post.subject = 'baz'
- post.content = 'bar'
- post.save
- I18n.locale = 'de-DE'
- assert_equal 'foo', post.subject
- assert_equal 'bar', post.content
- end
-
- test "resolves a simple fallback without reloading" do
- I18n.locale = 'de-DE'
- post = Post.new :subject => 'foo'
- I18n.locale = 'de'
- post.subject = 'baz'
- post.content = 'bar'
- I18n.locale = 'de-DE'
- assert_equal 'foo', post.subject
- assert_equal 'bar', post.content
- end
-
- test "resolves a complex fallback without reloading" do
- I18n.fallbacks.map 'de' => %w(en he)
- I18n.locale = 'de'
- post = Post.new
- I18n.locale = 'en'
- post.subject = 'foo'
- I18n.locale = 'he'
- post.subject = 'baz'
- post.content = 'bar'
- I18n.locale = 'de'
- assert_equal 'foo', post.subject
- assert_equal 'bar', post.content
- end
-
- test 'fallbacks with lots of locale switching' do
- I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
- post = Post.create :subject => 'foo'
-
- I18n.locale = :'de-DE'
- assert_equal 'foo', post.subject
-
- I18n.locale = :'en-US'
- post.update_attribute :subject, 'bar'
-
- I18n.locale = :'de-DE'
- assert_equal 'bar', post.subject
- end
-
- test 'fallbacks with lots of locale switching' do
- I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
- child = Child.create :content => 'foo'
-
- I18n.locale = :'de-DE'
- assert_equal 'foo', child.content
-
- I18n.locale = :'en-US'
- child.update_attribute :content, 'bar'
-
- I18n.locale = :'de-DE'
- assert_equal 'bar', child.content
- end
- end
-end
-
-# TODO should validate_presence_of take fallbacks into account? maybe we need
-# an extra validation call, or more options for validate_presence_of.
-
diff --git a/vendor/plugins/globalize2/test/active_record/migration_test.rb b/vendor/plugins/globalize2/test/active_record/migration_test.rb
deleted file mode 100644
index 359d811f0..000000000
--- a/vendor/plugins/globalize2/test/active_record/migration_test.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-class MigrationTest < ActiveSupport::TestCase
- def setup
- reset_db!
- Post.drop_translation_table!
- end
-
- test 'globalize table added' do
- assert !Post.connection.table_exists?(:post_translations)
- assert !Post.connection.index_exists?(:post_translations, :post_id)
-
- Post.create_translation_table!(:subject => :string, :content => :text)
- assert Post.connection.table_exists?(:post_translations)
- assert Post.connection.index_exists?(:post_translations, :post_id)
-
- columns = Post.connection.columns(:post_translations)
- assert locale = columns.detect { |c| c.name == 'locale' }
- assert_equal :string, locale.type
- assert subject = columns.detect { |c| c.name == 'subject' }
- assert_equal :string, subject.type
- assert content = columns.detect { |c| c.name == 'content' }
- assert_equal :text, content.type
- assert post_id = columns.detect { |c| c.name == 'post_id' }
- assert_equal :integer, post_id.type
- assert created_at = columns.detect { |c| c.name == 'created_at' }
- assert_equal :datetime, created_at.type
- assert updated_at = columns.detect { |c| c.name == 'updated_at' }
- assert_equal :datetime, updated_at.type
- end
-
- test 'globalize table dropped' do
- assert !Post.connection.table_exists?( :post_translations )
- assert !Post.connection.index_exists?( :post_translations, :post_id )
- Post.create_translation_table! :subject => :string, :content => :text
- assert Post.connection.table_exists?( :post_translations )
- assert Post.connection.index_exists?( :post_translations, :post_id )
- Post.drop_translation_table!
- assert !Post.connection.table_exists?( :post_translations )
- assert !Post.connection.index_exists?( :post_translations, :post_id )
- end
-
- test 'exception on missing field inputs' do
- assert_raise Globalize::MigrationMissingTranslatedField do
- Post.create_translation_table! :content => :text
- end
- end
-
- test 'exception on bad input type' do
- assert_raise Globalize::BadMigrationFieldType do
- Post.create_translation_table! :subject => :string, :content => :integer
- end
- end
-
- test "exception on bad input type isn't raised for untranslated fields" do
- assert_nothing_raised do
- Post.create_translation_table! :subject => :string, :content => :string, :views_count => :integer
- end
- end
-
- test 'create_translation_table! should not be called on non-translated models' do
- assert_raise NoMethodError do
- Blog.create_translation_table! :name => :string
- end
- end
-
- test 'drop_translation_table! should not be called on non-translated models' do
- assert_raise NoMethodError do
- Blog.drop_translation_table!
- end
- end
-
- test "translation_index_name returns a readable index name when it's not longer than 50 characters" do
- assert_equal 'index_post_translations_on_post_id', Post.send(:translation_index_name)
- end
-
- test "translation_index_name returns a hashed index name when it's longer than 50 characters" do
- class UltraLongModelNameWithoutProper < ActiveRecord::Base
- translates :foo
- end
- name = UltraLongModelNameWithoutProper.send(:translation_index_name)
- assert_match /^index_[a-z0-9]{40}$/, name
- end
-
- test 'globalize table added when table has long name' do
- UltraLongModelNameWithoutProper.create_translation_table!(
- :subject => :string, :content => :text
- )
-
- assert UltraLongModelNameWithoutProper.connection.table_exists?(
- :ultra_long_model_name_without_proper_translations
- )
- assert UltraLongModelNameWithoutProper.connection.index_exists?(
- :ultra_long_model_name_without_proper_translations,
- :name => UltraLongModelNameWithoutProper.send(
- :translation_index_name
- )
- )
- end
-
- test 'globalize table dropped when table has long name' do
- UltraLongModelNameWithoutProper.drop_translation_table!
- UltraLongModelNameWithoutProper.create_translation_table!(
- :subject => :string, :content => :text
- )
- UltraLongModelNameWithoutProper.drop_translation_table!
-
- assert !UltraLongModelNameWithoutProper.connection.table_exists?(
- :ultra_long_model_name_without_proper_translations
- )
- assert !UltraLongModelNameWithoutProper.connection.index_exists?(
- :ultra_long_model_name_without_proper_translations,
- :ultra_long_model_name_without_proper_id
- )
- end
-
-end
diff --git a/vendor/plugins/globalize2/test/active_record/sti_translated_test.rb b/vendor/plugins/globalize2/test/active_record/sti_translated_test.rb
deleted file mode 100644
index f529b8d6e..000000000
--- a/vendor/plugins/globalize2/test/active_record/sti_translated_test.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-class StiTranslatedTest < ActiveSupport::TestCase
- def setup
- I18n.locale = :'en-US'
- reset_db!
- end
-
- test "works with simple dynamic finders" do
- foo = Child.create :content => 'foo'
- Child.create :content => 'bar'
- child = Child.find_by_content('foo')
- assert_equal foo, child
- end
-
- test 'change attribute on globalized model' do
- child = Child.create :content => 'foo'
- assert_equal [], child.changed
- child.content = 'bar'
- assert_equal [ 'content' ], child.changed
- child.content = 'baz'
- assert_member 'content', child.changed
- end
-
- test 'change attribute on globalized model after locale switching' do
- child = Child.create :content => 'foo'
- assert_equal [], child.changed
- child.content = 'bar'
- I18n.locale = :de
- assert_equal [ 'content' ], child.changed
- end
-
- test "saves all locales, even after locale switching" do
- child = Child.new :content => 'foo'
- I18n.locale = 'de-DE'
- child.content = 'bar'
- I18n.locale = 'he-IL'
- child.content = 'baz'
- child.save
- I18n.locale = 'en-US'
- child = Child.first
- assert_equal 'foo', child.content
- I18n.locale = 'de-DE'
- assert_equal 'bar', child.content
- I18n.locale = 'he-IL'
- assert_equal 'baz', child.content
- end
-end
diff --git a/vendor/plugins/globalize2/test/active_record/translates_test.rb b/vendor/plugins/globalize2/test/active_record/translates_test.rb
deleted file mode 100644
index 1831063fb..000000000
--- a/vendor/plugins/globalize2/test/active_record/translates_test.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-class TranslatesTest < ActiveSupport::TestCase
- def setup
- I18n.locale = nil
- ActiveRecord::Base.locale = nil
- reset_db!
- end
-
- test 'defines a :locale accessors on ActiveRecord::Base' do
- ActiveRecord::Base.locale = :de
- assert_equal :de, ActiveRecord::Base.locale
- end
-
- test 'the :locale reader on ActiveRecord::Base does not default to I18n.locale (anymore)' do
- I18n.locale = :en
- assert_nil ActiveRecord::Base.locale
- end
-
- test 'ActiveRecord::Base.with_locale temporarily sets the given locale and yields the block' do
- I18n.locale = :en
- post = Post.with_locale(:de) do
- Post.create!(:subject => 'Titel', :content => 'Inhalt')
- end
- assert_nil Post.locale
- assert_equal :en, I18n.locale
-
- I18n.locale = :de
- assert_equal 'Titel', post.subject
- end
-
- test 'translation_class returns the Translation class' do
- assert_equal Post::Translation, Post.translation_class
- end
-
- test 'defines a has_many association on the model class' do
- assert_has_many Post, :translations
- end
-
- test 'defines a scope for retrieving locales that have complete translations' do
- post = Post.create!(:subject => 'subject', :content => 'content')
- assert_equal [:en], post.translated_locales
- end
-
- test 'sets the given attributes to translated_attribute_names' do
- assert_equal [:subject, :content], Post.translated_attribute_names
- end
-
- test 'defines accessors for the translated attributes' do
- post = Post.new
- assert post.respond_to?(:subject)
- assert post.respond_to?(:subject=)
- end
-
- test 'attribute reader without arguments will use the current locale on ActiveRecord::Base or I18n' do
- post = Post.with_locale(:de) do
- Post.create!(:subject => 'Titel', :content => 'Inhalt')
- end
- I18n.locale = :de
- assert_equal 'Titel', post.subject
-
- I18n.locale = :en
- ActiveRecord::Base.locale = :de
- assert_equal 'Titel', post.subject
- end
-
- test 'attribute reader when passed a locale will use the given locale' do
- post = Post.with_locale(:de) do
- Post.create!(:subject => 'Titel', :content => 'Inhalt')
- end
- assert_equal 'Titel', post.subject(:de)
- end
-
- test 'attribute reader will use the current locale on ActiveRecord::Base or I18n' do
- post = Post.with_locale(:en) do
- Post.create!(:subject => 'title', :content => 'content')
- end
- I18n.locale = :de
- post.subject = 'Titel'
- assert_equal 'Titel', post.subject
-
- ActiveRecord::Base.locale = :en
- post.subject = 'title'
- assert_equal 'title', post.subject
- end
-
- test "find_by_xx records have writable attributes" do
- Post.create :subject => "change me"
- p = Post.find_by_subject("change me")
- p.subject = "changed"
- assert_nothing_raised(ActiveRecord::ReadOnlyRecord) do
- p.save
- end
- end
-end
diff --git a/vendor/plugins/globalize2/test/active_record/translation_class_test.rb b/vendor/plugins/globalize2/test/active_record/translation_class_test.rb
deleted file mode 100644
index 1628416d7..000000000
--- a/vendor/plugins/globalize2/test/active_record/translation_class_test.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-class TranlationClassTest < ActiveSupport::TestCase
- def setup
- reset_db!
- end
-
- test 'defines a Translation class nested in the model class' do
- assert Post.const_defined?(:Translation)
- end
-
- test 'defines a belongs_to association' do
- assert_belongs_to Post::Translation, :post
- end
-
- test 'defines a reader for :locale that always returns a symbol' do
- post = Post::Translation.new
- post.write_attribute('locale', 'de')
- assert_equal :de, post.locale
- end
-
- test 'defines a write for :locale that always writes a string' do
- post = Post::Translation.new
- post.locale = :de
- assert_equal 'de', post.read_attribute('locale')
- end
-end
-
-
diff --git a/vendor/plugins/globalize2/test/active_record/validation_tests.rb b/vendor/plugins/globalize2/test/active_record/validation_tests.rb
deleted file mode 100644
index 0148fa384..000000000
--- a/vendor/plugins/globalize2/test/active_record/validation_tests.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/../data/models')
-
-class ValidationTest < ActiveSupport::TestCase
- def setup
- reset_db!
- end
-
- def teardown
- Validatee.instance_variable_set(:@validate_callbacks, CallbackChain.new)
- end
-
- test "validates_presence_of" do
- Validatee.class_eval { validates_presence_of :string }
- assert !Validatee.new.valid?
- assert Validatee.new(:string => 'foo').valid?
- end
-
- test "validates_confirmation_of" do
- Validatee.class_eval { validates_confirmation_of :string }
- assert !Validatee.new(:string => 'foo', :string_confirmation => 'bar').valid?
- assert Validatee.new(:string => 'foo', :string_confirmation => 'foo').valid?
- end
-
- test "validates_acceptance_of" do
- Validatee.class_eval { validates_acceptance_of :string, :accept => '1' }
- assert !Validatee.new(:string => '0').valid?
- assert Validatee.new(:string => '1').valid?
- end
-
- test "validates_length_of (:is)" do
- Validatee.class_eval { validates_length_of :string, :is => 1 }
- assert !Validatee.new(:string => 'aa').valid?
- assert Validatee.new(:string => 'a').valid?
- end
-
- test "validates_format_of" do
- Validatee.class_eval { validates_format_of :string, :with => /^\d+$/ }
- assert !Validatee.new(:string => 'a').valid?
- assert Validatee.new(:string => '1').valid?
- end
-
- test "validates_inclusion_of" do
- Validatee.class_eval { validates_inclusion_of :string, :in => %(a) }
- assert !Validatee.new(:string => 'b').valid?
- assert Validatee.new(:string => 'a').valid?
- end
-
- test "validates_exclusion_of" do
- Validatee.class_eval { validates_exclusion_of :string, :in => %(b) }
- assert !Validatee.new(:string => 'b').valid?
- assert Validatee.new(:string => 'a').valid?
- end
-
- test "validates_numericality_of" do
- Validatee.class_eval { validates_numericality_of :string }
- assert !Validatee.new(:string => 'a').valid?
- assert Validatee.new(:string => '1').valid?
- end
-
- # This doesn't pass and Rails' validates_uniqueness_of implementation doesn't
- # seem to be extensible easily. One can work around that by either defining
- # a custom validation on the Validatee model itself, or by using validates_uniqueness_of
- # on Validatee::Translation.
- #
- # test "validates_uniqueness_of" do
- # Validatee.class_eval { validates_uniqueness_of :string }
- # Validatee.create!(:string => 'a')
- # assert !Validatee.new(:string => 'a').valid?
- # assert Validatee.new(:string => 'b').valid?
- # end
-
- # test "validates_associated" do
- # end
-end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/active_record_test.rb b/vendor/plugins/globalize2/test/active_record_test.rb
deleted file mode 100644
index 38e247e17..000000000
--- a/vendor/plugins/globalize2/test/active_record_test.rb
+++ /dev/null
@@ -1,467 +0,0 @@
-require File.expand_path(File.dirname(__FILE__) + '/test_helper')
-require File.expand_path(File.dirname(__FILE__) + '/data/models')
-
-# Higher level tests.
-
-class ActiveRecordTest < ActiveSupport::TestCase
- def setup
- I18n.locale = :en
- reset_db!
- ActiveRecord::Base.locale = nil
- end
-
- def assert_translated(locale, record, names, expected)
- I18n.locale = locale
- assert_equal Array(expected), Array(names).map { |name| record.send(name) }
- end
-
- test "a translated record has translations" do
- assert_equal [], Post.new.translations
- end
-
- test "saves a translated version of the record for each locale" do
- post = Post.create(:subject => 'title')
- I18n.locale = :de
- post.update_attributes(:subject => 'Titel')
-
- assert_equal 2, post.translations.size
- assert_equal %w(de en), post.translations.map(&:locale).map(&:to_s).sort
- assert_equal %w(Titel title), post.translations.map(&:subject).sort
- end
-
- test "a translated record has German translations" do
- I18n.locale = :de
- post = Post.create(:subject => 'foo')
- assert_equal 1, post.translations.size
- assert_equal [:de], post.translations.map { |t| t.locale }
- end
-
- test "modifiying translated fields while switching locales" do
- post = Post.create(:subject => 'title', :content => 'content')
- assert_equal %w(title content), [post.subject, post.content]
-
- I18n.locale = :de
- post.subject, post.content = 'Titel', 'Inhalt'
-
- assert_translated(:de, post, [:subject, :content], %w(Titel Inhalt))
- assert_translated(:en, post, [:subject, :content], %w(title content))
- assert_translated(:de, post, [:subject, :content], %w(Titel Inhalt))
-
- post.save
- post.reload
-
- assert_translated(:en, post, [:subject, :content], %w(title content))
- assert_translated(:de, post, [:subject, :content], %w(Titel Inhalt))
- end
-
- test "attribute writers do return their argument" do
- value = Post.new.subject = 'foo'
- assert_equal 'foo', value
- end
-
- test "update_attribute succeeds with valid values" do
- post = Post.create(:subject => 'foo', :content => 'bar')
- post.update_attribute(:subject, 'baz')
- assert_equal 'baz', Post.first.subject
- end
-
- test "update_attributes fails with invalid values" do
- post = Post.create(:subject => 'foo', :content => 'bar')
- assert !post.update_attributes(:subject => '')
- assert_not_nil post.reload.attributes['subject']
- assert_equal 'foo', post.subject
- end
-
- test "passing the locale to create uses the given locale" do
- post = Post.create(:subject => 'Titel', :content => 'Inhalt', :locale => :de)
- assert_equal :en, I18n.locale
- assert_nil ActiveRecord::Base.locale
-
- I18n.locale = :de
- assert_equal 'Titel', post.subject
- end
-
- test "passing the locale to attributes= uses the given locale" do
- post = Post.create(:subject => 'title', :content => 'content')
- post.update_attributes(:subject => 'Titel', :content => 'Inhalt', :locale => :de)
- post.reload
-
- assert_equal :en, I18n.locale
- assert_nil ActiveRecord::Base.locale
-
- assert_equal 'title', post.subject
- I18n.locale = :de
- assert_equal 'Titel', post.subject
- end
-
- test 'reload works' do
- post = Post.create(:subject => 'foo', :content => 'bar')
- post.subject = 'baz'
- post.reload
- assert_equal 'foo', post.subject
- end
-
- test "returns nil if no translations are found (unsaved record)" do
- post = Post.new(:subject => 'foo')
- assert_equal 'foo', post.subject
- assert_nil post.content
- end
-
- test "returns nil if no translations are found (saved record)" do
- post = Post.create(:subject => 'foo')
- post.reload
- assert_equal 'foo', post.subject
- assert_nil post.content
- end
-
- test "finds a German post" do
- post = Post.create(:subject => 'foo (en)', :content => 'bar')
- I18n.locale = :de
- post = Post.first
- post.subject = 'baz (de)'
- post.save
- assert_equal 'baz (de)', Post.first.subject
- I18n.locale = :en
- assert_equal 'foo (en)', Post.first.subject
- end
-
- test "saves an English post and loads correctly" do
- post = Post.create(:subject => 'foo', :content => 'bar')
- assert post.save
- post = Post.first
- assert_equal 'foo', post.subject
- assert_equal 'bar', post.content
- end
-
- test "returns the value for the correct locale, after locale switching" do
- post = Post.create(:subject => 'foo')
- I18n.locale = :de
- post.subject = 'bar'
- post.save
- I18n.locale = :en
- post = Post.first
- assert_equal 'foo', post.subject
- I18n.locale = :de
- assert_equal 'bar', post.subject
- end
-
- test "returns the value for the correct locale, after locale switching, without saving" do
- post = Post.create :subject => 'foo'
- I18n.locale = :de
- post.subject = 'bar'
- I18n.locale = :en
- assert_equal 'foo', post.subject
- I18n.locale = :de
- assert_equal 'bar', post.subject
- end
-
- test "saves all locales, even after locale switching" do
- post = Post.new :subject => 'foo'
- I18n.locale = :de
- post.subject = 'bar'
- I18n.locale = :he
- post.subject = 'baz'
- post.save
- I18n.locale = :en
- post = Post.first
- assert_equal 'foo', post.subject
- I18n.locale = :de
- assert_equal 'bar', post.subject
- I18n.locale = :he
- assert_equal 'baz', post.subject
- end
-
- test "works with associations" do
- blog = Blog.create
- post1 = blog.posts.create(:subject => 'foo')
-
- I18n.locale = :de
- post2 = blog.posts.create(:subject => 'bar')
- assert_equal 2, blog.posts.size
-
- I18n.locale = :en
- assert_equal 'foo', blog.posts.first.subject
- assert_nil blog.posts.last.subject
-
- I18n.locale = :de
- assert_equal 'bar', blog.posts.last.subject
- end
-
- test "works with simple dynamic finders" do
- foo = Post.create(:subject => 'foo')
- Post.create(:subject => 'bar')
- post = Post.find_by_subject('foo')
- assert_equal foo, post
- end
-
- test 'change attribute on globalized model' do
- post = Post.create(:subject => 'foo', :content => 'bar')
- assert_equal [], post.changed
- post.subject = 'baz'
- assert_equal ['subject'], post.changed
- post.content = 'quux'
- assert_member 'subject', post.changed
- assert_member 'content', post.changed
- end
-
- test 'change attribute on globalized model after locale switching' do
- post = Post.create(:subject => 'foo', :content => 'bar')
- assert_equal [], post.changed
- post.subject = 'baz'
- I18n.locale = :de
- assert_equal ['subject'], post.changed
- end
-
- test 'complex writing and stashing' do
- post = Post.create(:subject => 'foo', :content => 'bar')
- post.subject = nil
- assert_nil post.subject
- assert !post.valid?
- post.subject = 'stashed_foo'
- assert_equal 'stashed_foo', post.subject
- end
-
- test 'translated class locale setting' do
- assert ActiveRecord::Base.respond_to?(:locale)
- assert_equal :en, I18n.locale
- assert_nil ActiveRecord::Base.locale
-
- I18n.locale = :de
- assert_equal :de, I18n.locale
- assert_nil ActiveRecord::Base.locale
-
- ActiveRecord::Base.locale = :es
- assert_equal :de, I18n.locale
- assert_equal :es, ActiveRecord::Base.locale
-
- I18n.locale = :fr
- assert_equal :fr, I18n.locale
- assert_equal :es, ActiveRecord::Base.locale
- end
-
- test "untranslated class responds to locale" do
- assert Blog.respond_to?(:locale)
- end
-
- test "to ensure locales in different classes are the same" do
- ActiveRecord::Base.locale = :de
- assert_equal :de, ActiveRecord::Base.locale
- assert_equal :de, Parent.locale
-
- Parent.locale = :es
- assert_equal :es, ActiveRecord::Base.locale
- assert_equal :es, Parent.locale
- end
-
- test "attribute saving goes by content locale and not global locale" do
- ActiveRecord::Base.locale = :de
- assert_equal :en, I18n.locale
- Post.create :subject => 'foo'
- assert_equal :de, Post.first.translations.first.locale
- end
-
- test "attribute loading goes by content locale and not global locale" do
- post = Post.create(:subject => 'foo')
- assert_nil ActiveRecord::Base.locale
-
- ActiveRecord::Base.locale = :de
- assert_equal :en, I18n.locale
- post.update_attribute(:subject, 'foo [de]')
- assert_equal 'foo [de]', Post.first.subject
-
- ActiveRecord::Base.locale = :en
- assert_equal 'foo', Post.first.subject
- end
-
- test "access content locale before setting" do
- Globalize::ActiveRecord::ActMacro.class_eval "remove_class_variable(:@@locale)"
- assert_nothing_raised { ActiveRecord::Base.locale }
- end
-
- test "available_locales" do
- Post.locale = :de
- post = Post.create(:subject => 'foo')
- Post.locale = :es
- post.update_attribute(:subject, 'bar')
- Post.locale = :fr
- post.update_attribute(:subject, 'baz')
- assert_equal [:de, :es, :fr], post.available_locales
- assert_equal [:de, :es, :fr], Post.first.available_locales
- end
-
- test "saving record correctly after post-save reload" do
- reloader = Reloader.create(:content => 'foo')
- assert_equal 'foo', reloader.content
- end
-
- test "including translations" do
- I18n.locale = :de
- Post.create(:subject => "Foo1", :content => "Bar1")
- Post.create(:subject => "Foo2", :content => "Bar2")
-
- class << Post
- def translations_included
- self.all(:include => :translations)
- end
- end
-
- default = Post.all.map { |x| [x.subject, x.content] }
- with_include = Post.translations_included.map { |x| [x.subject, x.content] }
- assert_equal default, with_include
- end
-
- test "setting multiple translations at once with options hash" do
- Post.locale = :de
- post = Post.create(:subject => "foo1", :content => "foo1")
- Post.locale = :en
- post.update_attributes(:subject => "bar1", :content => "bar1")
-
- options = { :de => {:subject => "foo2", :content => "foo2"},
- :en => {:subject => "bar2", :content => "bar2"} }
- post.set_translations options
- post.reload
-
- assert ["bar2", "bar2"], [post.subject, post.content]
- Post.locale = :de
- assert ["foo2", "foo2"], [post.subject, post.content]
- end
-
- test "setting only one translation with set_translations" do
- Post.locale = :de
- post = Post.create(:subject => "foo1", :content => "foo1")
- Post.locale = :en
- post.update_attributes(:subject => "bar1", :content => "bar1")
-
- options = { :en => { :subject => "bar2", :content => "bar2" } }
- post.set_translations options
- post.reload
-
- assert ["bar2", "bar2"], [post.subject, post.content]
- Post.locale = :de
- assert ["foo1", "foo1"], [post.subject, post.content]
- end
-
- test "setting only selected attributes with set_translations" do
- Post.locale = :de
- post = Post.create(:subject => "foo1", :content => "foo1")
- Post.locale = :en
- post.update_attributes(:subject => "bar1", :content => "bar1")
-
- options = { :de => { :content => "foo2" }, :en => { :subject => "bar2" } }
- post.set_translations options
- post.reload
-
- assert ["bar2", "bar1"], [post.subject, post.content]
- Post.locale = :de
- assert ["foo1", "foo2"], [post.subject, post.content]
- end
-
- test "setting invalid attributes raises ArgumentError" do
- Post.locale = :de
- post = Post.create(:subject => "foo1", :content => "foo1")
- Post.locale = :en
- post.update_attributes(:subject => "bar1", :content => "bar1")
-
- options = { :de => {:fake => "foo2"} }
- exception = assert_raise(ActiveRecord::UnknownAttributeError) do
- post.set_translations options
- end
- assert_equal "unknown attribute: fake", exception.message
- end
-
- test "reload accepting find options" do
- p = Post.create(:subject => "Foo", :content => "Bar")
- assert p.reload(:readonly => true, :lock => true)
- assert_raise(ArgumentError) { p.reload(:foo => :bar) }
- end
-
- test "dependent destroy of translation" do
- p = Post.create(:subject => "Foo", :content => "Bar")
- assert_equal 1, PostTranslation.count
- p.destroy
- assert_equal 0, PostTranslation.count
- end
-
- test "translating subclass of untranslated comment model" do
- translated_comment = TranslatedComment.create(:post => @post)
- assert_nothing_raised { translated_comment.translations }
- end
-
- test "modifiying translated comments works as expected" do
- I18n.locale = :en
- translated_comment = TranslatedComment.create(:post => @post, :content => 'foo')
- assert_equal 'foo', translated_comment.content
-
- I18n.locale = :de
- translated_comment.content = 'bar'
- assert translated_comment.save
- assert_equal 'bar', translated_comment.content
-
- I18n.locale = :en
- assert_equal 'foo', translated_comment.content
-
- assert_equal 2, translated_comment.translations.size
- end
-
- test "can create a proxy class for a namespaced model" do
- assert_nothing_raised do
- module Foo
- module Bar
- class Baz < ActiveRecord::Base
- translates :bumm
- end
- end
- end
- end
- end
-
- test "attribute translated before type cast" do
- Post.locale = :en
- post = Post.create(:subject => 'foo', :content => 'bar')
- Post.locale = :de
- post.update_attribute(:subject, "German foo")
- assert_equal 'German foo', post.subject_before_type_cast
- Post.locale = :en
- assert_equal 'foo', post.subject_before_type_cast
- end
-
- test "don't override existing translation class" do
- assert PostTranslation.new.respond_to?(:existing_method)
- end
-
- test "has_many and named scopes work with globalize" do
- blog = Blog.create
- assert_nothing_raised { blog.posts.foobar }
- end
-
- test "required_attribuets don't include non-translated attributes" do
- validations = [
- stub(:name => :name, :macro => :validates_presence_of),
- stub(:name => :email, :macro => :validates_presence_of)
- ]
- User.expects(:reflect_on_all_validations => validations)
- assert_equal [:name], User.required_attributes
- end
-
- test "attribute_names returns translated and regular attribute names" do
- Post.create :subject => "foo", :content => "bar"
- assert_equal Post.last.attribute_names.sort, %w[blog_id content id subject]
- end
-
- test "attributes returns translated and regular attributes" do
- Post.create :subject => "foo", :content => "bar"
- assert_equal Post.last.attributes.keys.sort, %w[blog_id content id subject]
- end
-
- test "to_xml includes translated fields" do
- Post.create :subject => "foo", :content => "bar"
- assert Post.last.to_xml =~ /subject/
- assert Post.last.to_xml =~ /content/
- end
-end
-
-# TODO error checking for fields that exist in main table, don't exist in
-# proxy table, aren't strings or text
-#
-# TODO allow finding by translated attributes in conditions?
-# TODO generate advanced dynamic finders?
diff --git a/vendor/plugins/globalize2/test/all.rb b/vendor/plugins/globalize2/test/all.rb
deleted file mode 100644
index ff467a176..000000000
--- a/vendor/plugins/globalize2/test/all.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-files = Dir[File.dirname(__FILE__) + '/**/*_test.rb']
-files.each { |file| require file } \ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/data/models.rb b/vendor/plugins/globalize2/test/data/models.rb
deleted file mode 100644
index 5408d6e23..000000000
--- a/vendor/plugins/globalize2/test/data/models.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-#require 'ruby2ruby'
-#require 'parse_tree'
-#require 'parse_tree_extensions'
-#require 'pp'
-
-class PostTranslation < ActiveRecord::Base
- def existing_method ; end
-end
-
-class Post < ActiveRecord::Base
- translates :subject, :content
- validates_presence_of :subject
- named_scope :foobar, :conditions => { :title => "foobar" }
-end
-
-class Blog < ActiveRecord::Base
- has_many :posts, :order => 'id ASC'
-end
-
-class Parent < ActiveRecord::Base
- translates :content
-end
-
-class Child < Parent
-end
-
-class Comment < ActiveRecord::Base
- validates_presence_of :content
- belongs_to :post
-end
-
-class TranslatedComment < Comment
- translates :content
-end
-
-class UltraLongModelNameWithoutProper < ActiveRecord::Base
- translates :subject, :content
- validates_presence_of :subject
-end
-
-class Reloader < Parent
- after_create :do_reload
-
- def do_reload
- reload
- end
-end
-
-class Validatee < ActiveRecord::Base
- translates :string
-end
-
-class User < ActiveRecord::Base
- translates :name
- validates_presence_of :name, :email
-end
diff --git a/vendor/plugins/globalize2/test/data/no_globalize_schema.rb b/vendor/plugins/globalize2/test/data/no_globalize_schema.rb
deleted file mode 100644
index 379455ddb..000000000
--- a/vendor/plugins/globalize2/test/data/no_globalize_schema.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# This schema creates tables without columns for the translated fields
-ActiveRecord::Schema.define do
- create_table :blogs, :force => true do |t|
- t.string :name
- end
-
- create_table :posts, :force => true do |t|
- t.references :blog
- end
-end
-
diff --git a/vendor/plugins/globalize2/test/data/schema.rb b/vendor/plugins/globalize2/test/data/schema.rb
deleted file mode 100644
index 910dd0855..000000000
--- a/vendor/plugins/globalize2/test/data/schema.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-ActiveRecord::Schema.define do
- create_table :blogs, :force => true do |t|
- t.string :description
- end
-
- create_table :posts, :force => true do |t|
- t.references :blog
- end
-
- create_table :post_translations, :force => true do |t|
- t.string :locale
- t.references :post
- t.string :subject
- t.text :content
- end
-
- create_table :parents, :force => true do |t|
- end
-
- create_table :parent_translations, :force => true do |t|
- t.string :locale
- t.references :parent
- t.text :content
- t.string :type
- end
-
- create_table :comments, :force => true do |t|
- t.references :post
- end
-
- create_table :comment_translations, :force => true do |t|
- t.string :locale
- t.references :comment
- t.string :subject
- t.text :content
- end
-
- create_table :validatees, :force => true do |t|
- end
-
- create_table :validatee_translations, :force => true do |t|
- t.string :locale
- t.references :validatee
- t.string :string
- end
-
- create_table :users, :force => true do |t|
- t.string :email
- end
-
- create_table :users_translations, :force => true do |t|
- t.references :user
- t.string :name
- end
-end
diff --git a/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb b/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb
deleted file mode 100644
index 5d0ecd6fc..000000000
--- a/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-require 'i18n/missing_translations_log_handler'
-
-class MissingTranslationsTest < ActiveSupport::TestCase
- test "defines I18n.missing_translations_logger accessor" do
- assert I18n.respond_to?(:missing_translations_logger)
- end
-
- test "defines I18n.missing_translations_logger= writer" do
- assert I18n.respond_to?(:missing_translations_logger=)
- end
-end
-
-class TestLogger < String
- def warn(msg) self.concat msg; end
-end
-
-class LogMissingTranslationsTest < ActiveSupport::TestCase
- def setup
- @locale, @key, @options = :en, :foo, {}
- @exception = I18n::MissingTranslationData.new(@locale, @key, @options)
-
- @logger = TestLogger.new
- I18n.missing_translations_logger = @logger
- end
-
- test "still returns the exception message for MissingTranslationData exceptions" do
- result = I18n.send(:missing_translations_log_handler, @exception, @locale, @key, @options)
- assert_equal 'translation missing: en, foo', result
- end
-
- test "logs the missing translation to I18n.missing_translations_logger" do
- I18n.send(:missing_translations_log_handler, @exception, @locale, @key, @options)
- assert_equal 'translation missing: en, foo', @logger
- end
-end
diff --git a/vendor/plugins/globalize2/test/test_helper.rb b/vendor/plugins/globalize2/test/test_helper.rb
deleted file mode 100644
index 99a5d3950..000000000
--- a/vendor/plugins/globalize2/test/test_helper.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-$LOAD_PATH << File.expand_path( File.dirname(__FILE__) + '/../lib' )
-
-require 'rubygems'
-require 'test/unit'
-require 'active_record'
-require 'active_support'
-require 'active_support/test_case'
-require 'mocha'
-require 'globalize'
-# require 'validation_reflection'
-
-config = { :adapter => 'sqlite3', :database => ':memory:' }
-ActiveRecord::Base.establish_connection(config)
-
-class ActiveSupport::TestCase
- def reset_db!(schema_path = nil)
- schema_path ||= File.expand_path(File.dirname(__FILE__) + '/data/schema.rb')
- ActiveRecord::Migration.verbose = false
- ActiveRecord::Base.silence { load(schema_path) }
- end
-
- def assert_member(item, array)
- assert_block "Item #{item} is not in array #{array}" do
- array.member?(item)
- end
- end
-
- def assert_belongs_to(model, associated)
- assert model.reflect_on_all_associations(:belongs_to).detect { |association|
- association.name.to_s == associated.to_s
- }
- end
-
- def assert_has_many(model, associated)
- assert model.reflect_on_all_associations(:has_many).detect { |association|
- association.name.to_s == associated.to_s
- }
- end
-end
-
-module ActiveRecord
- module ConnectionAdapters
- class AbstractAdapter
- def index_exists?(table_name, column_name)
- indexes(table_name).any? { |index| index.name == index_name(table_name, column_name) }
- end
- end
- end
-end
-
-# module ActiveRecord
-# class BaseWithoutTable < Base
-# self.abstract_class = true
-#
-# def create_or_update
-# errors.empty?
-# end
-#
-# class << self
-# def columns()
-# @columns ||= []
-# end
-#
-# def column(name, sql_type = nil, default = nil, null = true)
-# columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
-# reset_column_information
-# end
-#
-# # Do not reset @columns
-# def reset_column_information
-# read_methods.each { |name| undef_method(name) }
-# @column_names = @columns_hash = @content_columns = @dynamic_methods_hash = @read_methods = nil
-# end
-# end
-# end
-# end \ No newline at end of file
diff --git a/vendor/plugins/has_tag_string/lib/has_tag_string.rb b/vendor/plugins/has_tag_string/lib/has_tag_string.rb
index b982bc3a0..4022faaac 100644
--- a/vendor/plugins/has_tag_string/lib/has_tag_string.rb
+++ b/vendor/plugins/has_tag_string/lib/has_tag_string.rb
@@ -4,7 +4,7 @@
# followed by a colon - e.g. url:http://www.flourish.org
#
# Copyright (c) 2010 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
+# Email: hello@mysociety.org; WWW: http://www.mysociety.org/
module HasTagString
# Represents one tag of one model.
diff --git a/vendor/plugins/rails_xss/MIT-LICENSE b/vendor/plugins/rails_xss/MIT-LICENSE
deleted file mode 100644
index ed44a7bde..000000000
--- a/vendor/plugins/rails_xss/MIT-LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2009 Koziarski Software Ltd.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/plugins/rails_xss/README.markdown b/vendor/plugins/rails_xss/README.markdown
deleted file mode 100644
index 1222ef38d..000000000
--- a/vendor/plugins/rails_xss/README.markdown
+++ /dev/null
@@ -1,91 +0,0 @@
-RailsXss
-========
-
-This plugin replaces the default ERB template handlers with erubis, and switches the behaviour to escape by default rather than requiring you to escape. This is consistent with the behaviour in Rails 3.0.
-
-Strings now have a notion of "html safe", which is false by default. Whenever rails copies a string into the response body it checks whether or not the string is safe, safe strings are copied verbatim into the response body, but unsafe strings are escaped first.
-
-All the XSS-proof helpers like link_to and form_tag now return safe strings, and will continue to work unmodified. If you have your own helpers which return strings you *know* are safe, you will need to explicitly tell rails that they're safe. For an example, take the following helper.
-
-
- def some_helper
- (1..5).map do |i|
- "<li>#{i}</li>"
- end.join("\n")
- end
-
-With this plugin installed, the html will be escaped. So you will need to do one of the following:
-
-1) Use the raw helper in your template. raw will ensure that your string is copied verbatim into the response body.
-
- <%= raw some_helper %>
-
-2) Mark the string as safe in the helper itself:
-
- def some_helper
- (1..5).map do |i|
- "<li>#{i}</li>"
- end.join("\n").html_safe
- end
-
-3) Use the `safe_helper` meta programming method (WARNING: This is not supported by Rails 3, so if you're planning to
-eventually upgrade your app this alternative is not recommended):
-
- module ApplicationHelper
- def some_helper
- #...
- end
- safe_helper :some_helper # not supported by Rails 3
- end
-
-Example
--------
-
-BEFORE:
-
- <%= params[:own_me] %> => XSS attack
- <%=h params[:own_me] %> => No XSS
- <%= @blog_post.content %> => Displays the HTML
-
-AFTER:
-
- <%= params[:own_me] %> => No XSS
- <%=h params[:own_me] %> => No XSS (same result)
- <%= @blog_post.content %> => *escapes* the HTML
- <%= raw @blog_post.content %> => Displays the HTML
-
-
-Gotchas
----
-
-#### textilize and simple_format do *not* return safe strings
-
-Both these methods support arbitrary HTML and are *not* safe to embed directly in your document. You'll need to do something like:
-
- <%= sanitize(textilize(@blog_post.content_textile)) %>
-
-#### Safe strings aren't magic.
-
-Once a string has been marked as safe, the only operations which will maintain that HTML safety are String#<<, String#concat and String#+. All other operations are safety ignorant so it's still probably possible to break your app if you're doing something like
-
- value = something_safe
- value.gsub!(/a/, params[:own_me])
-
-Don't do that.
-
-#### String interpolation won't be safe, even when it 'should' be
-
- value = "#{something_safe}#{something_else_safe}"
- value.html_safe? # => false
-
-This is intended functionality and can't be fixed.
-
-Getting Started
-===============
-
-1. Install rails 2.3.8 or higher, or freeze rails from 2-3-stable.
-2. Install erubis (gem install erubis)
-3. Install this plugin (ruby script/plugin install git://github.com/rails/rails_xss.git)
-4. Report anything that breaks.
-
-Copyright (c) 2009 Koziarski Software Ltd, released under the MIT license. For full details see MIT-LICENSE included in this distribution.
diff --git a/vendor/plugins/rails_xss/Rakefile b/vendor/plugins/rails_xss/Rakefile
deleted file mode 100644
index 929ecbb81..000000000
--- a/vendor/plugins/rails_xss/Rakefile
+++ /dev/null
@@ -1,23 +0,0 @@
-require 'rake'
-require 'rake/testtask'
-require 'rake/rdoctask'
-
-desc 'Default: run unit tests.'
-task :default => :test
-
-desc 'Test the rails_xss plugin.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.libs << 'test'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
-end
-
-desc 'Generate documentation for the rails_xss plugin.'
-Rake::RDocTask.new(:rdoc) do |rdoc|
- rdoc.rdoc_dir = 'rdoc'
- rdoc.title = 'RailsXss'
- rdoc.options << '--line-numbers' << '--inline-source'
- rdoc.rdoc_files.include('README')
- rdoc.rdoc_files.include('lib/**/*.rb')
-end
diff --git a/vendor/plugins/rails_xss/init.rb b/vendor/plugins/rails_xss/init.rb
deleted file mode 100644
index 533eb1f36..000000000
--- a/vendor/plugins/rails_xss/init.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-unless $gems_rake_task
- if Rails::VERSION::MAJOR >= 3
- $stderr.puts "You don't need to install rails_xss as a plugin for Rails 3 and after."
- elsif Rails::VERSION::MAJOR <= 2 && Rails::VERSION::MINOR <= 3 && Rails::VERSION::TINY <= 7
- $stderr.puts "rails_xss requires Rails 2.3.8 or later. Please upgrade to enable automatic HTML safety."
- else
- require 'rails_xss'
- end
-end
diff --git a/vendor/plugins/rails_xss/lib/rails_xss.rb b/vendor/plugins/rails_xss/lib/rails_xss.rb
deleted file mode 100644
index 46d1b9a4a..000000000
--- a/vendor/plugins/rails_xss/lib/rails_xss.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-require 'rails_xss/erubis'
-require 'rails_xss/action_view'
-require 'rails_xss/string_ext'
diff --git a/vendor/plugins/rails_xss/lib/rails_xss/action_view.rb b/vendor/plugins/rails_xss/lib/rails_xss/action_view.rb
deleted file mode 100644
index c3f5e47df..000000000
--- a/vendor/plugins/rails_xss/lib/rails_xss/action_view.rb
+++ /dev/null
@@ -1,111 +0,0 @@
-module ActionView
- class Base
- def self.xss_safe?
- true
- end
-
- module WithSafeOutputBuffer
- # Rails version of with_output_buffer uses '' as the default buf
- def with_output_buffer(buf = ActiveSupport::SafeBuffer.new) #:nodoc:
- super buf
- end
- end
-
- include WithSafeOutputBuffer
- end
-
- module Helpers
- module CaptureHelper
- def content_for(name, content = nil, &block)
- ivar = "@content_for_#{name}"
- content = capture(&block) if block_given?
- instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{ERB::Util.h(content)}".html_safe)
- nil
- end
- end
-
- module TextHelper
- def concat(string, unused_binding = nil)
- if unused_binding
- ActiveSupport::Deprecation.warn("The binding argument of #concat is no longer needed. Please remove it from your views and helpers.", caller)
- end
-
- output_buffer.concat(string)
- end
-
- def simple_format(text, html_options={})
- start_tag = tag('p', html_options, true)
- text = ERB::Util.h(text).to_str.dup
- text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
- text.gsub!(/\n\n+/, "</p>\n\n#{start_tag}") # 2+ newline -> paragraph
- text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
- text.insert 0, start_tag
- text.html_safe.safe_concat("</p>")
- end
- end
-
- module TagHelper
- private
- def content_tag_string_with_escaping(name, content, options, escape = true)
- content_tag_string_without_escaping(name, escape ? ERB::Util.h(content) : content, options, escape)
- end
- alias_method_chain :content_tag_string, :escaping
- end
-
- module UrlHelper
- def link_to(*args, &block)
- if block_given?
- options = args.first || {}
- html_options = args.second
- concat(link_to(capture(&block), options, html_options))
- else
- name = args.first
- options = args.second || {}
- html_options = args.third
-
- url = url_for(options)
-
- if html_options
- html_options = html_options.stringify_keys
- href = html_options['href']
- convert_options_to_javascript!(html_options, url)
- tag_options = tag_options(html_options)
- else
- tag_options = nil
- end
-
- href_attr = "href=\"#{url}\"" unless href
- "<a #{href_attr}#{tag_options}>#{ERB::Util.h(name || url)}</a>".html_safe
- end
- end
- end
-
- module JavaScriptHelper
- def escape_javascript(javascript)
- if javascript
- javascript.gsub(/(\\|<\/|\r\n|[\n\r"'])/) {|match| JS_ESCAPE_MAP[match] }
- else
- ''
- end
- end
- end
- end
-end
-
-module RailsXss
- module SafeHelpers
- def safe_helper(*names)
- names.each do |helper_method_name|
- aliased_target, punctuation = helper_method_name.to_s.sub(/([?!=])$/, ''), $1
- module_eval <<-END
- def #{aliased_target}_with_xss_safety#{punctuation}(*args, &block)
- raw(#{aliased_target}_without_xss_safety#{punctuation}(*args, &block))
- end
- END
- alias_method_chain helper_method_name, :xss_safety
- end
- end
- end
-end
-
-Module.class_eval { include RailsXss::SafeHelpers }
diff --git a/vendor/plugins/rails_xss/lib/rails_xss/erubis.rb b/vendor/plugins/rails_xss/lib/rails_xss/erubis.rb
deleted file mode 100644
index b8a239483..000000000
--- a/vendor/plugins/rails_xss/lib/rails_xss/erubis.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# stop erubis from printing it's version number all the time
-old_stdout = $stdout
-File.open("/dev/null", "w") do |f|
- $stdout = f
- require 'erubis/helpers/rails_helper'
- $stdout = old_stdout
-end
-
-module RailsXss
- class Erubis < ::Erubis::Eruby
- def add_preamble(src)
- src << "@output_buffer = ActiveSupport::SafeBuffer.new;"
- end
-
- def add_text(src, text)
- return if text.empty?
- src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
- end
-
- BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
-
- def add_expr_literal(src, code)
- if code =~ BLOCK_EXPR
- src << "@output_buffer.safe_concat((" << $1 << ").to_s);"
- else
- src << '@output_buffer << ((' << code << ').to_s);'
- end
- end
-
- def add_expr_escaped(src, code)
- src << '@output_buffer << ' << escaped_expr(code) << ';'
- end
-
- def add_postamble(src)
- src << '@output_buffer.to_s'
- end
- end
-end
-
-Erubis::Helpers::RailsHelper.engine_class = RailsXss::Erubis
-Erubis::Helpers::RailsHelper.show_src = false
diff --git a/vendor/plugins/rails_xss/lib/rails_xss/string_ext.rb b/vendor/plugins/rails_xss/lib/rails_xss/string_ext.rb
deleted file mode 100644
index ee32e47c8..000000000
--- a/vendor/plugins/rails_xss/lib/rails_xss/string_ext.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-require 'active_support/deprecation'
-
-ActiveSupport::SafeBuffer.class_eval do
- def concat(value)
- if value.html_safe?
- super(value)
- else
- super(ERB::Util.h(value))
- end
- end
- alias << concat
- UNSAFE_STRING_METHODS = ["capitalize", "chomp", "chop", "delete", "downcase", "gsub", "lstrip", "next", "reverse", "rstrip", "slice", "squeeze", "strip", "sub", "succ", "swapcase", "tr", "tr_s", "upcase"].freeze
-
- for unsafe_method in UNSAFE_STRING_METHODS
- class_eval <<-EOT, __FILE__, __LINE__ + 1
- def #{unsafe_method}(*args)
- super.to_str
- end
-
- def #{unsafe_method}!(*args)
- raise TypeError, "Cannot modify SafeBuffer in place"
- end
- EOT
- end
-end
-
-class String
- def html_safe?
- defined?(@_rails_html_safe)
- end
-
- def html_safe!
- ActiveSupport::Deprecation.warn("Use html_safe with your strings instead of html_safe! See http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/ for the full story.", caller)
- @_rails_html_safe = true
- self
- end
-
- def add_with_safety(other)
- result = add_without_safety(other)
- if html_safe? && also_html_safe?(other)
- result.html_safe!
- else
- result
- end
- end
- alias_method :add_without_safety, :+
- alias_method :+, :add_with_safety
-
- def concat_with_safety(other_or_fixnum)
- result = concat_without_safety(other_or_fixnum)
- unless html_safe? && also_html_safe?(other_or_fixnum)
- remove_instance_variable(:@_rails_html_safe) if defined?(@_rails_html_safe)
- end
- result
- end
-
- alias_method_chain :concat, :safety
- undef_method :<<
- alias_method :<<, :concat_with_safety
-
- private
- def also_html_safe?(other)
- other.respond_to?(:html_safe?) && other.html_safe?
- end
-end
diff --git a/vendor/plugins/rails_xss/lib/tasks/rails_xss_tasks.rake b/vendor/plugins/rails_xss/lib/tasks/rails_xss_tasks.rake
deleted file mode 100644
index b8659f089..000000000
--- a/vendor/plugins/rails_xss/lib/tasks/rails_xss_tasks.rake
+++ /dev/null
@@ -1,4 +0,0 @@
-# desc "Explaining what the task does"
-# task :rails_xss do
-# # Task goes here
-# end
diff --git a/vendor/plugins/rails_xss/test/active_record_helper_test.rb b/vendor/plugins/rails_xss/test/active_record_helper_test.rb
deleted file mode 100644
index 728ec0ac6..000000000
--- a/vendor/plugins/rails_xss/test/active_record_helper_test.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-require 'test_helper'
-
-class ActiveRecordHelperTest < ActionView::TestCase
- silence_warnings do
- Post = Struct.new("Post", :title, :author_name, :body, :secret, :written_on)
- Post.class_eval do
- alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
- alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
- alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
- end
- end
-
- def setup_post
- @post = Post.new
- def @post.errors
- Class.new {
- def on(field)
- case field.to_s
- when "author_name"
- "can't be empty"
- when "body"
- true
- else
- false
- end
- end
- def empty?() false end
- def count() 1 end
- def full_messages() [ "Author name can't be empty" ] end
- }.new
- end
-
- def @post.new_record?() true end
- def @post.to_param() nil end
-
- def @post.column_for_attribute(attr_name)
- Post.content_columns.select { |column| column.name == attr_name }.first
- end
-
- silence_warnings do
- def Post.content_columns() [ Column.new(:string, "title", "Title"), Column.new(:text, "body", "Body") ] end
- end
-
- @post.title = "Hello World"
- @post.author_name = ""
- @post.body = "Back to the hill and over it again!"
- @post.secret = 1
- @post.written_on = Date.new(2004, 6, 15)
- end
-
- def setup
- setup_post
-
- @response = ActionController::TestResponse.new
-
- @controller = Object.new
- def @controller.url_for(options)
- options = options.symbolize_keys
-
- [options[:action], options[:id].to_param].compact.join('/')
- end
- end
-
- def test_text_field_with_errors_is_safe
- assert text_field("post", "author_name").html_safe?
- end
-
- def test_text_field_with_errors
- assert_dom_equal(
- %(<div class="fieldWithErrors"><input id="post_author_name" name="post[author_name]" size="30" type="text" value="" /></div>),
- text_field("post", "author_name")
- )
- end
-end
diff --git a/vendor/plugins/rails_xss/test/asset_tag_helper_test.rb b/vendor/plugins/rails_xss/test/asset_tag_helper_test.rb
deleted file mode 100644
index f58feda3d..000000000
--- a/vendor/plugins/rails_xss/test/asset_tag_helper_test.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'test_helper'
-
-class AssetTagHelperTest < ActionView::TestCase
- def setup
- @controller = Class.new do
- attr_accessor :request
- def url_for(*args) "http://www.example.com" end
- end.new
- end
-
- def test_auto_discovery_link_tag
- assert_dom_equal(%(<link href="http://www.example.com" rel="Not so alternate" title="ATOM" type="application/atom+xml" />),
- auto_discovery_link_tag(:atom, {}, {:rel => "Not so alternate"}))
- end
-
- def test_javascript_include_tag_with_blank_asset_id
- ENV["RAILS_ASSET_ID"] = ""
- assert_dom_equal(%(<script src="/javascripts/test.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
- javascript_include_tag("test", :defaults))
- end
-
- def test_javascript_include_tag_with_given_asset_id
- ENV["RAILS_ASSET_ID"] = "1"
- assert_dom_equal(%(<script src="/javascripts/prototype.js?1" type="text/javascript"></script>\n<script src="/javascripts/effects.js?1" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js?1" type="text/javascript"></script>\n<script src="/javascripts/controls.js?1" type="text/javascript"></script>\n<script src="/javascripts/application.js?1" type="text/javascript"></script>),
- javascript_include_tag(:defaults))
- ENV["RAILS_ASSET_ID"] = ""
- end
-
- def test_javascript_include_tag_is_html_safe
- assert javascript_include_tag(:defaults).html_safe?
- assert javascript_include_tag("prototype").html_safe?
- end
-
- def test_stylesheet_link_tag
- assert_dom_equal(%(<link href="http://www.example.com/styles/style.css" media="screen" rel="stylesheet" type="text/css" />),
- stylesheet_link_tag("http://www.example.com/styles/style"))
- end
-
- def test_stylesheet_link_tag_is_html_safe
- assert stylesheet_link_tag('dir/file').html_safe?
- assert stylesheet_link_tag('dir/other/file', 'dir/file2').html_safe?
- assert stylesheet_tag('dir/file', {}).html_safe?
- end
-
- def test_image_tag
- assert_dom_equal(%(<img alt="Mouse" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" src="/images/mouse.png" />),
- image_tag("mouse.png", :mouseover => image_path("mouse_over.png")))
- end
-end
diff --git a/vendor/plugins/rails_xss/test/caching_test.rb b/vendor/plugins/rails_xss/test/caching_test.rb
deleted file mode 100644
index 3ea41e8b5..000000000
--- a/vendor/plugins/rails_xss/test/caching_test.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-require 'test_helper'
-
-CACHE_DIR = 'test_cache'
-# Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
-FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
-ActionController::Base.page_cache_directory = FILE_STORE_PATH
-ActionController::Base.cache_store = :file_store, FILE_STORE_PATH
-
-class FragmentCachingTestController < ActionController::Base
- def some_action; end;
-end
-
-class FragmentCachingTest < ActionController::TestCase
- def setup
- ActionController::Base.perform_caching = true
- @store = ActiveSupport::Cache::MemoryStore.new
- ActionController::Base.cache_store = @store
- @controller = FragmentCachingTestController.new
- @params = {:controller => 'posts', :action => 'index'}
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- @controller.params = @params
- @controller.request = @request
- @controller.response = @response
- @controller.send(:initialize_current_url)
- @controller.send(:initialize_template_class, @response)
- @controller.send(:assign_shortcuts, @request, @response)
- end
-
- def test_fragment_for
- @store.write('views/expensive', 'fragment content')
- fragment_computed = false
-
- buffer = 'generated till now -> '.html_safe
- @controller.fragment_for(buffer, 'expensive') { fragment_computed = true }
-
- assert !fragment_computed
- assert_equal 'generated till now -> fragment content', buffer
- end
-
- def test_html_safety
- assert_nil @store.read('views/name')
- content = 'value'.html_safe
- assert_equal content, @controller.write_fragment('name', content)
-
- cached = @store.read('views/name')
- assert_equal content, cached
- assert_equal String, cached.class
-
- html_safe = @controller.read_fragment('name')
- assert_equal content, html_safe
- assert html_safe.html_safe?
- end
-end
diff --git a/vendor/plugins/rails_xss/test/content_for_test.rb b/vendor/plugins/rails_xss/test/content_for_test.rb
deleted file mode 100644
index 45ba6762c..000000000
--- a/vendor/plugins/rails_xss/test/content_for_test.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-require 'test_helper'
-
-class ContentForTest < ActionView::TestCase
-
- def test_content_for_should_yield_html_safe_string
- content_for(:testing, "Some <p>html</p>")
- content = instance_variable_get(:"@content_for_testing")
- assert content.html_safe?
- end
-
- def test_content_for_should_escape_content
- content_for(:testing, "Some <p>html</p>")
- content = instance_variable_get(:"@content_for_testing")
- expected = %{Some &lt;p&gt;html&lt;/p&gt;}
- assert_dom_equal expected, content
- end
-
- def test_content_for_should_not_escape_html_safe_content
- content_for(:testing, "Some <p>html</p>".html_safe)
- content = instance_variable_get(:"@content_for_testing")
- expected = %{Some <p>html</p>}
- assert_dom_equal expected, content
- end
-
- def test_content_for_should_escape_content_from_block
- content_for(:testing){ "Some <p>html</p>" }
- content = instance_variable_get(:"@content_for_testing")
- expected = %{Some &lt;p&gt;html&lt;/p&gt;}
- assert_dom_equal expected, content
- end
-
- def test_content_for_should_not_escape_html_safe_content_from_block
- content_for(:testing){ "Some <p>html</p>".html_safe }
- content = instance_variable_get(:"@content_for_testing")
- expected = %{Some <p>html</p>}
- assert_dom_equal expected, content
- end
-
-end
diff --git a/vendor/plugins/rails_xss/test/date_helper_test.rb b/vendor/plugins/rails_xss/test/date_helper_test.rb
deleted file mode 100644
index daf010274..000000000
--- a/vendor/plugins/rails_xss/test/date_helper_test.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-require 'test_helper'
-
-class DateHelperTest < ActionView::TestCase
- silence_warnings do
- Post = Struct.new("Post", :id, :written_on, :updated_at)
- end
-
- def test_select_html_safety
- assert select_day(16).html_safe?
- assert select_month(8).html_safe?
- assert select_year(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe?
- assert select_minute(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe?
- assert select_second(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe?
-
- assert select_minute(8, :use_hidden => true).html_safe?
- assert select_month(8, :prompt => 'Choose month').html_safe?
-
- assert select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, :class => 'selector').html_safe?
- assert select_date(Time.mktime(2003, 8, 16), :date_separator => " / ", :start_year => 2003, :end_year => 2005, :prefix => "date[first]").html_safe?
- end
-
- def test_object_select_html_safety
- @post = Post.new
- @post.written_on = Date.new(2004, 6, 15)
-
- assert date_select("post", "written_on", :default => Time.local(2006, 9, 19, 15, 16, 35), :include_blank => true).html_safe?
- assert time_select("post", "written_on", :ignore_date => true).html_safe?
- end
-end
diff --git a/vendor/plugins/rails_xss/test/deprecated_output_safety_test.rb b/vendor/plugins/rails_xss/test/deprecated_output_safety_test.rb
deleted file mode 100644
index e16f7ce0d..000000000
--- a/vendor/plugins/rails_xss/test/deprecated_output_safety_test.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-require 'test_helper'
-
-class DeprecatedOutputSafetyTest < ActiveSupport::TestCase
- def setup
- @string = "hello"
- end
-
- test "A string can be marked safe using html_safe!" do
- assert_deprecated do
- @string.html_safe!
- assert @string.html_safe?
- end
- end
-
- test "Marking a string safe returns the string using html_safe!" do
- assert_deprecated do
- assert_equal @string, @string.html_safe!
- end
- end
-
- test "Adding a safe string to another safe string returns a safe string using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- @string.html_safe!
- @combination = @other_string + @string
-
- assert_equal "otherhello", @combination
- assert @combination.html_safe?
- end
- end
-
- test "Adding an unsafe string to a safe string returns an unsafe string using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- @combination = @other_string + "<foo>"
- @other_combination = @string + "<foo>"
-
- assert_equal "other<foo>", @combination
- assert_equal "hello<foo>", @other_combination
-
- assert !@combination.html_safe?
- assert !@other_combination.html_safe?
- end
- end
-
- test "Concatting safe onto unsafe yields unsafe using html_safe!" do
- assert_deprecated do
- @other_string = "other"
- @string.html_safe!
-
- @other_string.concat(@string)
- assert !@other_string.html_safe?
- end
- end
-
- test "Concatting unsafe onto safe yields unsafe using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- string = @other_string.concat("<foo>")
- assert_equal "other<foo>", string
- assert !string.html_safe?
- end
- end
-
- test "Concatting safe onto safe yields safe using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- @string.html_safe!
-
- @other_string.concat(@string)
- assert @other_string.html_safe?
- end
- end
-
- test "Concatting safe onto unsafe with << yields unsafe using html_safe!" do
- assert_deprecated do
- @other_string = "other"
- @string.html_safe!
-
- @other_string << @string
- assert !@other_string.html_safe?
- end
- end
-
- test "Concatting unsafe onto safe with << yields unsafe using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- string = @other_string << "<foo>"
- assert_equal "other<foo>", string
- assert !string.html_safe?
- end
- end
-
- test "Concatting safe onto safe with << yields safe using html_safe!" do
- assert_deprecated do
- @other_string = "other".html_safe!
- @string.html_safe!
-
- @other_string << @string
- assert @other_string.html_safe?
- end
- end
-
- test "Concatting a fixnum to safe always yields safe using html_safe!" do
- assert_deprecated do
- @string.html_safe!
- @string.concat(13)
- assert_equal "hello".concat(13), @string
- assert @string.html_safe?
- end
- end
-end
diff --git a/vendor/plugins/rails_xss/test/erb_util_test.rb b/vendor/plugins/rails_xss/test/erb_util_test.rb
deleted file mode 100644
index 9a04d38e6..000000000
--- a/vendor/plugins/rails_xss/test/erb_util_test.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-require 'test_helper'
-
-class ErbUtilTest < Test::Unit::TestCase
- include ERB::Util
-
- ERB::Util::HTML_ESCAPE.each do |given, expected|
- define_method "test_html_escape_#{expected.gsub(/\W/, '')}" do
- assert_equal expected, html_escape(given)
- end
-
- unless given == '"'
- define_method "test_json_escape_#{expected.gsub(/\W/, '')}" do
- assert_equal ERB::Util::JSON_ESCAPE[given], json_escape(given)
- end
- end
- end
-
- def test_html_escape_is_html_safe
- escaped = h("<p>")
- assert_equal "&lt;p&gt;", escaped
- assert escaped.html_safe?
- end
-
- def test_html_escape_passes_html_escpe_unmodified
- escaped = h("<p>".html_safe)
- assert_equal "<p>", escaped
- assert escaped.html_safe?
- end
-
- def test_rest_in_ascii
- (0..127).to_a.map {|int| int.chr }.each do |chr|
- next if %w(& " < >).include?(chr)
- assert_equal chr, html_escape(chr)
- end
- end
-end
diff --git a/vendor/plugins/rails_xss/test/form_helper_test.rb b/vendor/plugins/rails_xss/test/form_helper_test.rb
deleted file mode 100644
index e5580d26c..000000000
--- a/vendor/plugins/rails_xss/test/form_helper_test.rb
+++ /dev/null
@@ -1,1447 +0,0 @@
-require 'test_helper'
-
-silence_warnings do
- Post = Struct.new(:title, :author_name, :body, :secret, :written_on, :cost)
- Post.class_eval do
- alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
- alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
- alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
- alias_method :secret?, :secret
-
- def new_record=(boolean)
- @new_record = boolean
- end
-
- def new_record?
- @new_record
- end
-
- attr_accessor :author
- def author_attributes=(attributes); end
-
- attr_accessor :comments
- def comments_attributes=(attributes); end
-
- attr_accessor :tags
- def tags_attributes=(attributes); end
- end
-
- class Comment
- attr_reader :id
- attr_reader :post_id
- def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
- def save; @id = 1; @post_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def name
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
-
- attr_accessor :relevances
- def relevances_attributes=(attributes); end
-
- end
-
- class Tag
- attr_reader :id
- attr_reader :post_id
- def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
- def save; @id = 1; @post_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def value
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
-
- attr_accessor :relevances
- def relevances_attributes=(attributes); end
-
- end
-
- class CommentRelevance
- attr_reader :id
- attr_reader :comment_id
- def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end
- def save; @id = 1; @comment_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def value
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
- end
-
- class TagRelevance
- attr_reader :id
- attr_reader :tag_id
- def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end
- def save; @id = 1; @tag_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def value
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
- end
-
- class Author < Comment
- attr_accessor :post
- def post_attributes=(attributes); end
- end
-end
-
-class FormHelperTest < ActionView::TestCase
- tests ActionView::Helpers::FormHelper
-
- def setup
- super
-
- # Create "label" locale for testing I18n label helpers
- I18n.backend.store_translations 'label', {
- :helpers => {
- :label => {
- :post => {
- :body => "Write entire text here"
- }
- }
- }
- }
-
- @post = Post.new
- @comment = Comment.new
- def @post.errors()
- Class.new{
- def on(field); "can't be empty" if field == "author_name"; end
- def empty?() false end
- def count() 1 end
- def full_messages() [ "Author name can't be empty" ] end
- }.new
- end
- def @post.id; 123; end
- def @post.id_before_type_cast; 123; end
- def @post.to_param; '123'; end
-
- @post.title = "Hello World"
- @post.author_name = ""
- @post.body = "Back to the hill and over it again!"
- @post.secret = 1
- @post.written_on = Date.new(2004, 6, 15)
-
- def Post.human_attribute_name(attribute)
- attribute.to_s == "cost" ? "Total cost" : attribute.to_s.humanize
- end
-
- @controller = Class.new do
- attr_reader :url_for_options
- def url_for(options)
- @url_for_options = options
- "http://www.example.com"
- end
- end
- @controller = @controller.new
- end
-
- def test_label
- assert_dom_equal('<label for="post_title">Title</label>', label("post", "title"))
- assert_dom_equal('<label for="post_title">The title goes here</label>', label("post", "title", "The title goes here"))
- assert_dom_equal(
- '<label class="title_label" for="post_title">Title</label>',
- label("post", "title", nil, :class => 'title_label')
- )
- assert_dom_equal('<label for="post_secret">Secret?</label>', label("post", "secret?"))
- end
-
- def test_label_with_symbols
- assert_dom_equal('<label for="post_title">Title</label>', label(:post, :title))
- assert_dom_equal('<label for="post_secret">Secret?</label>', label(:post, :secret?))
- end
-
- def test_label_with_locales_strings
- old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_body">Write entire text here</label>', label("post", "body"))
- ensure
- I18n.locale = old_locale
- end
-
- def test_label_with_human_attribute_name
- old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_cost">Total cost</label>', label(:post, :cost))
- ensure
- I18n.locale = old_locale
- end
-
- def test_label_with_locales_symbols
- old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_body">Write entire text here</label>', label(:post, :body))
- ensure
- I18n.locale = old_locale
- end
-
- def test_label_with_for_attribute_as_symbol
- assert_dom_equal('<label for="my_for">Title</label>', label(:post, :title, nil, :for => "my_for"))
- end
-
- def test_label_with_for_attribute_as_string
- assert_dom_equal('<label for="my_for">Title</label>', label(:post, :title, nil, "for" => "my_for"))
- end
-
- def test_label_with_id_attribute_as_symbol
- assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, :id => "my_id"))
- end
-
- def test_label_with_id_attribute_as_string
- assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, "id" => "my_id"))
- end
-
- def test_label_with_for_and_id_attributes_as_symbol
- assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, :for => "my_for", :id => "my_id"))
- end
-
- def test_label_with_for_and_id_attributes_as_string
- assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, "for" => "my_for", "id" => "my_id"))
- end
-
- def test_label_for_radio_buttons_with_value
- assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great_title"))
- assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great title"))
- end
-
- def test_text_field
- assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
- )
- assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title")
- )
- assert_dom_equal(
- '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name")
- )
- end
-
- def test_text_field_with_escapes
- @post.title = "<b>Hello World</b>"
- assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="text" value="&lt;b&gt;Hello World&lt;/b&gt;" />', text_field("post", "title")
- )
- end
-
- def test_text_field_with_html_entities
- @post.title = "The HTML Entity for & is &amp;"
- assert_dom_equal(
- '<input id="post_title" name="post[title]" size="30" type="text" value="The HTML Entity for &amp; is &amp;amp;" />',
- text_field("post", "title")
- )
- end
-
- def test_text_field_with_options
- expected = '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />'
- assert_dom_equal expected, text_field("post", "title", "size" => 35)
- assert_dom_equal expected, text_field("post", "title", :size => 35)
- end
-
- def test_text_field_assuming_size
- expected = '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />'
- assert_dom_equal expected, text_field("post", "title", "maxlength" => 35)
- assert_dom_equal expected, text_field("post", "title", :maxlength => 35)
- end
-
- def test_text_field_removing_size
- expected = '<input id="post_title" maxlength="35" name="post[title]" type="text" value="Hello World" />'
- assert_dom_equal expected, text_field("post", "title", "maxlength" => 35, "size" => nil)
- assert_dom_equal expected, text_field("post", "title", :maxlength => 35, :size => nil)
- end
-
- def test_text_field_doesnt_change_param_values
- object_name = 'post[]'
- expected = '<input id="post_123_title" name="post[123][title]" size="30" type="text" value="Hello World" />'
- assert_equal expected, text_field(object_name, "title")
- assert_equal object_name, "post[]"
- end
-
- def test_hidden_field
- assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
- hidden_field("post", "title")
- assert_dom_equal '<input id="post_secret" name="post[secret]" type="hidden" value="1" />',
- hidden_field("post", "secret?")
- end
-
- def test_hidden_field_with_escapes
- @post.title = "<b>Hello World</b>"
- assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="&lt;b&gt;Hello World&lt;/b&gt;" />',
- hidden_field("post", "title")
- end
-
- def test_hidden_field_with_options
- assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Something Else" />',
- hidden_field("post", "title", :value => "Something Else")
- end
-
- def test_check_box
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret")
- )
- @post.secret = 0
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret")
- )
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret" ,{"checked"=>"checked"})
- )
- @post.secret = true
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret")
- )
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret?")
- )
-
- @post.secret = ['0']
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret")
- )
- @post.secret = ['1']
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret")
- )
- end
-
- def test_check_box_with_explicit_checked_and_unchecked_values
- @post.secret = "on"
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="off" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" />',
- check_box("post", "secret", {}, "on", "off")
- )
- end
-
- def test_checkbox_disabled_still_submits_checked_value
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret", { :disabled => :true })
- )
- end
-
- def test_radio_button
- assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
- radio_button("post", "title", "Hello World")
- )
- assert_dom_equal('<input id="post_title_goodbye_world" name="post[title]" type="radio" value="Goodbye World" />',
- radio_button("post", "title", "Goodbye World")
- )
- assert_dom_equal('<input id="item_subobject_title_inside_world" name="item[subobject][title]" type="radio" value="inside world"/>',
- radio_button("item[subobject]", "title", "inside world")
- )
- end
-
- def test_radio_button_is_checked_with_integers
- assert_dom_equal('<input checked="checked" id="post_secret_1" name="post[secret]" type="radio" value="1" />',
- radio_button("post", "secret", "1")
- )
- end
-
- def test_radio_button_respects_passed_in_id
- assert_dom_equal('<input checked="checked" id="foo" name="post[secret]" type="radio" value="1" />',
- radio_button("post", "secret", "1", :id=>"foo")
- )
- end
-
- def test_radio_button_with_booleans
- assert_dom_equal('<input id="post_secret_true" name="post[secret]" type="radio" value="true" />',
- radio_button("post", "secret", true)
- )
-
- assert_dom_equal('<input id="post_secret_false" name="post[secret]" type="radio" value="false" />',
- radio_button("post", "secret", false)
- )
- end
-
- def test_text_area
- assert_dom_equal(
- '<textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
- text_area("post", "body")
- )
- end
-
- def test_text_area_with_escapes
- @post.body = "Back to <i>the</i> hill and over it again!"
- assert_dom_equal(
- '<textarea cols="40" id="post_body" name="post[body]" rows="20">Back to &lt;i&gt;the&lt;/i&gt; hill and over it again!</textarea>',
- text_area("post", "body")
- )
- end
-
- def test_text_area_with_alternate_value
- assert_dom_equal(
- '<textarea cols="40" id="post_body" name="post[body]" rows="20">Testing alternate values.</textarea>',
- text_area("post", "body", :value => 'Testing alternate values.')
- )
- end
-
- def test_text_area_with_html_entities
- @post.body = "The HTML Entity for & is &amp;"
- assert_dom_equal(
- '<textarea cols="40" id="post_body" name="post[body]" rows="20">The HTML Entity for &amp; is &amp;amp;</textarea>',
- text_area("post", "body")
- )
- end
-
- def test_text_area_with_size_option
- assert_dom_equal(
- '<textarea cols="183" id="post_body" name="post[body]" rows="820">Back to the hill and over it again!</textarea>',
- text_area("post", "body", :size => "183x820")
- )
- end
-
- def test_explicit_name
- assert_dom_equal(
- '<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
- )
- assert_dom_equal(
- '<textarea cols="40" id="post_body" name="really!" rows="20">Back to the hill and over it again!</textarea>',
- text_area("post", "body", "name" => "really!")
- )
- assert_dom_equal(
- '<input name="i mean it" type="hidden" value="0" /><input checked="checked" id="post_secret" name="i mean it" type="checkbox" value="1" />',
- check_box("post", "secret", "name" => "i mean it")
- )
- assert_dom_equal text_field("post", "title", "name" => "dont guess"),
- text_field("post", "title", :name => "dont guess")
- assert_dom_equal text_area("post", "body", "name" => "really!"),
- text_area("post", "body", :name => "really!")
- assert_dom_equal check_box("post", "secret", "name" => "i mean it"),
- check_box("post", "secret", :name => "i mean it")
- end
-
- def test_explicit_id
- assert_dom_equal(
- '<input id="dont guess" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
- )
- assert_dom_equal(
- '<textarea cols="40" id="really!" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
- text_area("post", "body", "id" => "really!")
- )
- assert_dom_equal(
- '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="i mean it" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret", "id" => "i mean it")
- )
- assert_dom_equal text_field("post", "title", "id" => "dont guess"),
- text_field("post", "title", :id => "dont guess")
- assert_dom_equal text_area("post", "body", "id" => "really!"),
- text_area("post", "body", :id => "really!")
- assert_dom_equal check_box("post", "secret", "id" => "i mean it"),
- check_box("post", "secret", :id => "i mean it")
- end
-
- def test_auto_index
- pid = @post.id
- assert_dom_equal(
- "<label for=\"post_#{pid}_title\">Title</label>",
- label("post[]", "title")
- )
- assert_dom_equal(
- "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
- )
- assert_dom_equal(
- "<textarea cols=\"40\" id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\" rows=\"20\">Back to the hill and over it again!</textarea>",
- text_area("post[]", "body")
- )
- assert_dom_equal(
- "<input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" /><input checked=\"checked\" id=\"post_#{pid}_secret\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" />",
- check_box("post[]", "secret")
- )
- assert_dom_equal(
-"<input checked=\"checked\" id=\"post_#{pid}_title_hello_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
- radio_button("post[]", "title", "Hello World")
- )
- assert_dom_equal("<input id=\"post_#{pid}_title_goodbye_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
- radio_button("post[]", "title", "Goodbye World")
- )
- end
-
- def test_form_for
- form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
- concat f.label(:title)
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- concat f.submit('Create post')
- end
-
- expected =
- "<form action='http://www.example.com' id='create-post' method='post'>" +
- "<label for='post_title'>Title</label>" +
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
- "<input name='commit' id='post_submit' type='submit' value='Create post' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_method
- form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' id='create-post' method='post'>" +
- "<div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>" +
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_without_object
- form_for(:post, :html => { :id => 'create-post' }) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' id='create-post' method='post'>" +
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_index
- form_for("post[]", @post) do |f|
- concat f.label(:title)
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' method='post'>" +
- "<label for=\"post_123_title\">Title</label>" +
- "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
- "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[123][secret]' type='hidden' value='0' />" +
- "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_nil_index_option_override
- form_for("post[]", @post, :index => nil) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' method='post'>" +
- "<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
- "<textarea name='post[][body]' id='post__body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[][secret]' type='hidden' value='0' />" +
- "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for
- form_for(:post, @post) do |f|
- f.fields_for(:comment, @post) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[comment][title]' size='30' type='text' id='post_comment_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_nested_collections
- form_for('post[]', @post) do |f|
- concat f.text_field(:title)
- f.fields_for('comment[]', @comment) do |c|
- concat c.text_field(:name)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
- "<input name='post[123][comment][][name]' size='30' type='text' id='post_123_comment__name' value='new comment' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_index_and_parent_fields
- form_for('post', @post, :index => 1) do |c|
- concat c.text_field(:title)
- c.fields_for('comment', @comment, :index => 1) do |r|
- concat r.text_field(:name)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[1][title]' size='30' type='text' id='post_1_title' value='Hello World' />" +
- "<input name='post[1][comment][1][name]' size='30' type='text' id='post_1_comment_1_name' value='new comment' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_index_and_nested_fields_for
- form_for(:post, @post, :index => 1) do |f|
- f.fields_for(:comment, @post) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[1][comment][title]' size='30' type='text' id='post_1_comment_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_index_on_both
- form_for(:post, @post, :index => 1) do |f|
- f.fields_for(:comment, @post, :index => 5) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[1][comment][5][title]' size='30' type='text' id='post_1_comment_5_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_auto_index
- form_for("post[]", @post) do |f|
- f.fields_for(:comment, @post) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[123][comment][title]' size='30' type='text' id='post_123_comment_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_index_radio_button
- form_for(:post, @post) do |f|
- f.fields_for(:comment, @post, :index => 5) do |c|
- concat c.radio_button(:title, "hello")
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[comment][5][title]' type='radio' id='post_comment_5_title_hello' value='hello' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_auto_index_on_both
- form_for("post[]", @post) do |f|
- f.fields_for("comment[]", @post) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[123][comment][123][title]' size='30' type='text' id='post_123_comment_123_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_index_and_auto_index
- form_for("post[]", @post) do |f|
- f.fields_for(:comment, @post, :index => 5) do |c|
- concat c.text_field(:title)
- end
- end
-
- form_for(:post, @post, :index => 1) do |f|
- f.fields_for("comment[]", @post) do |c|
- concat c.text_field(:title)
- end
- end
-
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[123][comment][5][title]' size='30' type='text' id='post_123_comment_5_title' value='Hello World' />" +
- "</form>" +
- "<form action='http://www.example.com' method='post'>" +
- "<input name='post[1][comment][123][title]' size='30' type='text' id='post_1_comment_123_title' value='Hello World' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_a_new_record_on_a_nested_attributes_one_to_one_association
- @post.author = Author.new
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:author) do |af|
- concat af.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="new author" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_explicitly_passed_object_on_a_nested_attributes_one_to_one_association
- form_for(:post, @post) do |f|
- f.fields_for(:author, Author.new(123)) do |af|
- assert_not_nil af.object
- assert_equal 123, af.object.id
- end
- end
- end
-
- def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association
- @post.author = Author.new(321)
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:author) do |af|
- concat af.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
- '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_existing_records_on_a_nested_attributes_one_to_one_association_with_explicit_hidden_field_placement
- @post.author = Author.new(321)
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:author) do |af|
- concat af.hidden_field(:id)
- concat af.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
- '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association
- @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- f.fields_for(:comments, comment) do |cf|
- concat cf.text_field(:name)
- end
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
- '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_explicit_hidden_field_placement
- @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- f.fields_for(:comments, comment) do |cf|
- concat cf.hidden_field(:id)
- concat cf.text_field(:name)
- end
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
- '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_new_records_on_a_nested_attributes_collection_association
- @post.comments = [Comment.new, Comment.new]
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- f.fields_for(:comments, comment) do |cf|
- concat cf.text_field(:name)
- end
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="new comment" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_existing_and_new_records_on_a_nested_attributes_collection_association
- @post.comments = [Comment.new(321), Comment.new]
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- f.fields_for(:comments, comment) do |cf|
- concat cf.text_field(:name)
- end
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_an_empty_supplied_attributes_collection
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:comments, []) do |cf|
- concat cf.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection
- @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:comments, @post.comments) do |cf|
- concat cf.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
- '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_only_builder
- @post.comments = [Comment.new(321), Comment.new]
- yielded_comments = []
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:comments) do |cf|
- concat cf.text_field(:name)
- yielded_comments << cf.object
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
- '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- assert_equal yielded_comments, @post.comments
- end
-
- def test_nested_fields_for_with_child_index_option_override_on_a_nested_attributes_collection_association
- @post.comments = []
-
- form_for(:post, @post) do |f|
- f.fields_for(:comments, Comment.new(321), :child_index => 'abc') do |cf|
- concat cf.text_field(:name)
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" size="30" type="text" value="comment #321" />' +
- '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_nested_fields_uses_unique_indices_for_different_collection_associations
- @post.comments = [Comment.new(321)]
- @post.tags = [Tag.new(123), Tag.new(456)]
- @post.comments[0].relevances = []
- @post.tags[0].relevances = []
- @post.tags[1].relevances = []
- form_for(:post, @post) do |f|
- f.fields_for(:comments, @post.comments[0]) do |cf|
- concat cf.text_field(:name)
- cf.fields_for(:relevances, CommentRelevance.new(314)) do |crf|
- concat crf.text_field(:value)
- end
- end
- f.fields_for(:tags, @post.tags[0]) do |tf|
- concat tf.text_field(:value)
- tf.fields_for(:relevances, TagRelevance.new(3141)) do |trf|
- concat trf.text_field(:value)
- end
- end
- f.fields_for('tags', @post.tags[1]) do |tf|
- concat tf.text_field(:value)
- tf.fields_for(:relevances, TagRelevance.new(31415)) do |trf|
- concat trf.text_field(:value)
- end
- end
- end
-
- expected = '<form action="http://www.example.com" method="post">' +
- '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
- '<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="commentrelevance #314" />' +
- '<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
- '<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" size="30" type="text" value="tag #123" />' +
- '<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #3141" />' +
- '<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' +
- '<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' +
- '<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" size="30" type="text" value="tag #456" />' +
- '<input id="post_tags_attributes_1_relevances_attributes_0_value" name="post[tags_attributes][1][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #31415" />' +
- '<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' +
- '<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />' +
- '</form>'
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for
- fields_for(:post, @post) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_with_index
- fields_for("post[]", @post) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
- "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[123][secret]' type='hidden' value='0' />" +
- "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_with_nil_index_option_override
- fields_for("post[]", @post, :index => nil) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
- "<textarea name='post[][body]' id='post__body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[][secret]' type='hidden' value='0' />" +
- "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_with_index_option_override
- fields_for("post[]", @post, :index => "abc") do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[abc][title]' size='30' type='text' id='post_abc_title' value='Hello World' />" +
- "<textarea name='post[abc][body]' id='post_abc_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[abc][secret]' type='hidden' value='0' />" +
- "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_without_object
- fields_for(:post) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_with_only_object
- fields_for(@post) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[secret]' type='hidden' value='0' />" +
- "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_object_with_bracketed_name
- fields_for("author[post]", @post) do |f|
- concat f.label(:title)
- concat f.text_field(:title)
- end
-
- assert_dom_equal "<label for=\"author_post_title\">Title</label>" +
- "<input name='author[post][title]' size='30' type='text' id='author_post_title' value='Hello World' />",
- output_buffer
- end
-
- def test_fields_for_object_with_bracketed_name_and_index
- fields_for("author[post]", @post, :index => 1) do |f|
- concat f.label(:title)
- concat f.text_field(:title)
- end
-
- assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" +
- "<input name='author[post][1][title]' size='30' type='text' id='author_post_1_title' value='Hello World' />",
- output_buffer
- end
-
- def test_form_builder_does_not_have_form_for_method
- assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
- end
-
- def test_form_for_and_fields_for
- form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
- concat post_form.text_field(:title)
- concat post_form.text_area(:body)
-
- fields_for(:parent_post, @post) do |parent_fields|
- concat parent_fields.check_box(:secret)
- end
- end
-
- expected =
- "<form action='http://www.example.com' id='create-post' method='post'>" +
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='parent_post[secret]' type='hidden' value='0' />" +
- "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_and_fields_for_with_object
- form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
- concat post_form.text_field(:title)
- concat post_form.text_area(:body)
-
- post_form.fields_for(@comment) do |comment_fields|
- concat comment_fields.text_field(:name)
- end
- end
-
- expected =
- "<form action='http://www.example.com' id='create-post' method='post'>" +
- "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
- "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
- "<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- class LabelledFormBuilder < ActionView::Helpers::FormBuilder
- (field_helpers - %w(hidden_field)).each do |selector|
- src, line = <<-END_SRC, __LINE__ + 1
- def #{selector}(field, *args, &proc)
- ("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe
- end
- END_SRC
- class_eval src, __FILE__, line
- end
- end
-
- def test_form_for_with_labelled_builder
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' method='post'>" +
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
- "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_default_form_builder
- old_default_form_builder, ActionView::Base.default_form_builder =
- ActionView::Base.default_form_builder, LabelledFormBuilder
-
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<form action='http://www.example.com' method='post'>" +
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
- "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- ensure
- ActionView::Base.default_form_builder = old_default_form_builder
- end
-
- def test_default_form_builder_with_active_record_helpers
- form_for(:post, @post) do |f|
- concat f.error_message_on('author_name')
- concat f.error_messages
- end
-
- expected = %(<form action='http://www.example.com' method='post'>) +
- %(<div class='formError'>can't be empty</div>) +
- %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
- %(</form>)
-
- assert_dom_equal expected, output_buffer
-
- end
-
- def test_default_form_builder_no_instance_variable
- post = @post
- @post = nil
-
- form_for(:post, post) do |f|
- concat f.error_message_on('author_name')
- concat f.error_messages
- end
-
- expected = %(<form action='http://www.example.com' method='post'>) +
- %(<div class='formError'>can't be empty</div>) +
- %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
- %(</form>)
-
- assert_dom_equal expected, output_buffer
-
- end
-
- def test_default_form_builder_without_object
-
- form_for(:post) do |f|
- concat f.error_message_on('author_name')
- concat f.error_messages
- end
-
- expected = %(<form action='http://www.example.com' method='post'>) +
- %(<div class='formError'>can't be empty</div>) +
- %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
- %(</form>)
-
- assert_dom_equal expected, output_buffer
-
- end
-
- # Perhaps this test should be moved to prototype helper tests.
- def test_remote_form_for_with_labelled_builder
- self.extend ActionView::Helpers::PrototypeHelper
-
- remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- %(<form action="http://www.example.com" onsubmit="new Ajax.Request('http://www.example.com', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" method="post">) +
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
- "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
- "</form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_fields_for_with_labelled_builder
- fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- end
-
- expected =
- "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
- "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
- "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_labelled_builder_with_nested_fields_for_without_options_hash
- klass = nil
-
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- f.fields_for(:comments, Comment.new) do |nested_fields|
- klass = nested_fields.class
- ''
- end
- end
-
- assert_equal LabelledFormBuilder, klass
- end
-
- def test_form_for_with_labelled_builder_with_nested_fields_for_with_options_hash
- klass = nil
-
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- f.fields_for(:comments, Comment.new, :index => 'foo') do |nested_fields|
- klass = nested_fields.class
- ''
- end
- end
-
- assert_equal LabelledFormBuilder, klass
- end
-
- class LabelledFormBuilderSubclass < LabelledFormBuilder; end
-
- def test_form_for_with_labelled_builder_with_nested_fields_for_with_custom_builder
- klass = nil
-
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- f.fields_for(:comments, Comment.new, :builder => LabelledFormBuilderSubclass) do |nested_fields|
- klass = nested_fields.class
- ''
- end
- end
-
- assert_equal LabelledFormBuilderSubclass, klass
- end
-
- def test_form_for_with_html_options_adds_options_to_form_tag
- form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
- expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\"></form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_string_url_option
- form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end
-
- assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
- end
-
- def test_form_for_with_hash_url_option
- form_for(:post, @post, :url => {:controller => 'controller', :action => 'action'}) do |f| end
-
- assert_equal 'controller', @controller.url_for_options[:controller]
- assert_equal 'action', @controller.url_for_options[:action]
- end
-
- def test_form_for_with_record_url_option
- form_for(:post, @post, :url => @post) do |f| end
-
- expected = "<form action=\"/posts/123\" method=\"post\"></form>"
- assert_equal expected, output_buffer
- end
-
- def test_form_for_with_existing_object
- form_for(@post) do |f| end
-
- expected = "<form action=\"/posts/123\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
- assert_equal expected, output_buffer
- end
-
- def test_form_for_with_new_object
- post = Post.new
- post.new_record = true
- def post.id() nil end
-
- form_for(post) do |f| end
-
- expected = "<form action=\"/posts\" class=\"new_post\" id=\"new_post\" method=\"post\"></form>"
- assert_equal expected, output_buffer
- end
-
- def test_form_for_with_existing_object_in_list
- @post.new_record = false
- @comment.save
-
- form_for([@post, @comment]) {}
-
- expected = %(<form action="#{comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0;display:inline"><input name="_method" type="hidden" value="put" /></div></form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_new_object_in_list
- @post.new_record = false
-
- form_for([@post, @comment]) {}
-
- expected = %(<form action="#{comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_existing_object_and_namespace_in_list
- @post.new_record = false
- @comment.save
-
- form_for([:admin, @post, @comment]) {}
-
- expected = %(<form action="#{admin_comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0;display:inline"><input name="_method" type="hidden" value="put" /></div></form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_new_object_and_namespace_in_list
- @post.new_record = false
-
- form_for([:admin, @post, @comment]) {}
-
- expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_for_with_existing_object_and_custom_url
- form_for(@post, :url => "/super_posts") do |f| end
-
- expected = "<form action=\"/super_posts\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
- assert_equal expected, output_buffer
- end
-
- def test_remote_form_for_with_html_options_adds_options_to_form_tag
- self.extend ActionView::Helpers::PrototypeHelper
-
- remote_form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
- expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\" onsubmit=\"new Ajax.Request('http://www.example.com', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\"></form>"
-
- assert_dom_equal expected, output_buffer
- end
-
- protected
- def comments_path(post)
- "/posts/#{post.id}/comments"
- end
- alias_method :post_comments_path, :comments_path
-
- def comment_path(post, comment)
- "/posts/#{post.id}/comments/#{comment.id}"
- end
- alias_method :post_comment_path, :comment_path
-
- def admin_comments_path(post)
- "/admin/posts/#{post.id}/comments"
- end
- alias_method :admin_post_comments_path, :admin_comments_path
-
- def admin_comment_path(post, comment)
- "/admin/posts/#{post.id}/comments/#{comment.id}"
- end
- alias_method :admin_post_comment_path, :admin_comment_path
-
- def posts_path
- "/posts"
- end
-
- def post_path(post)
- "/posts/#{post.id}"
- end
-
- def protect_against_forgery?
- false
- end
-end
diff --git a/vendor/plugins/rails_xss/test/form_tag_helper_test.rb b/vendor/plugins/rails_xss/test/form_tag_helper_test.rb
deleted file mode 100644
index 41eeceeb3..000000000
--- a/vendor/plugins/rails_xss/test/form_tag_helper_test.rb
+++ /dev/null
@@ -1,354 +0,0 @@
-require 'test_helper'
-
-class FormTagHelperTest < ActionView::TestCase
- def setup
- @controller = Class.new do
- def url_for(options)
- "http://www.example.com"
- end
- end
- @controller = @controller.new
- end
-
- VALID_HTML_ID = /^[A-Za-z][-_:.A-Za-z0-9]*$/ # see http://www.w3.org/TR/html4/types.html#type-name
-
- def test_check_box_tag
- actual = check_box_tag "admin"
- expected = %(<input id="admin" name="admin" type="checkbox" value="1" />)
- assert_dom_equal expected, actual
- end
-
- def test_check_box_tag_id_sanitized
- label_elem = root_elem(check_box_tag("project[2][admin]"))
- assert_match VALID_HTML_ID, label_elem['id']
- end
-
- def test_form_tag
- actual = form_tag
- expected = %(<form action="http://www.example.com" method="post">)
- assert_dom_equal expected, actual
- end
-
- def test_form_tag_multipart
- actual = form_tag({}, { 'multipart' => true })
- expected = %(<form action="http://www.example.com" enctype="multipart/form-data" method="post">)
- assert_dom_equal expected, actual
- end
-
- def test_form_tag_with_method_put
- actual = form_tag({}, { :method => :put })
- expected = %(<form action="http://www.example.com" method="post"><div style='margin:0;padding:0;display:inline'><input type="hidden" name="_method" value="put" /></div>)
- assert_dom_equal expected, actual
- end
-
- def test_form_tag_with_method_delete
- actual = form_tag({}, { :method => :delete })
- expected = %(<form action="http://www.example.com" method="post"><div style='margin:0;padding:0;display:inline'><input type="hidden" name="_method" value="delete" /></div>)
- assert_dom_equal expected, actual
- end
-
- def test_form_tag_with_block_in_erb
- __in_erb_template = ''
- form_tag("http://example.com") { concat "Hello world!" }
-
- expected = %(<form action="http://example.com" method="post">Hello world!</form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_form_tag_with_block_and_method_in_erb
- __in_erb_template = ''
- form_tag("http://example.com", :method => :put) { concat "Hello world!" }
-
- expected = %(<form action="http://example.com" method="post"><div style='margin:0;padding:0;display:inline'><input type="hidden" name="_method" value="put" /></div>Hello world!</form>)
- assert_dom_equal expected, output_buffer
- end
-
- def test_hidden_field_tag
- actual = hidden_field_tag "id", 3
- expected = %(<input id="id" name="id" type="hidden" value="3" />)
- assert_dom_equal expected, actual
- end
-
- def test_hidden_field_tag_id_sanitized
- input_elem = root_elem(hidden_field_tag("item[][title]"))
- assert_match VALID_HTML_ID, input_elem['id']
- end
-
- def test_file_field_tag
- assert_dom_equal "<input name=\"picsplz\" type=\"file\" id=\"picsplz\" />", file_field_tag("picsplz")
- end
-
- def test_file_field_tag_with_options
- assert_dom_equal "<input name=\"picsplz\" type=\"file\" id=\"picsplz\" class=\"pix\"/>", file_field_tag("picsplz", :class => "pix")
- end
-
- def test_password_field_tag
- actual = password_field_tag
- expected = %(<input id="password" name="password" type="password" />)
- assert_dom_equal expected, actual
- end
-
- def test_radio_button_tag
- actual = radio_button_tag "people", "david"
- expected = %(<input id="people_david" name="people" type="radio" value="david" />)
- assert_dom_equal expected, actual
-
- actual = radio_button_tag("num_people", 5)
- expected = %(<input id="num_people_5" name="num_people" type="radio" value="5" />)
- assert_dom_equal expected, actual
-
- actual = radio_button_tag("gender", "m") + radio_button_tag("gender", "f")
- expected = %(<input id="gender_m" name="gender" type="radio" value="m" /><input id="gender_f" name="gender" type="radio" value="f" />)
- assert_dom_equal expected, actual
-
- actual = radio_button_tag("opinion", "-1") + radio_button_tag("opinion", "1")
- expected = %(<input id="opinion_-1" name="opinion" type="radio" value="-1" /><input id="opinion_1" name="opinion" type="radio" value="1" />)
- assert_dom_equal expected, actual
-
- actual = radio_button_tag("person[gender]", "m")
- expected = %(<input id="person_gender_m" name="person[gender]" type="radio" value="m" />)
- assert_dom_equal expected, actual
- end
-
- def test_select_tag
- actual = select_tag "people", "<option>david</option>".html_safe
- expected = %(<select id="people" name="people"><option>david</option></select>)
- assert_dom_equal expected, actual
- end
-
- def test_select_tag_with_multiple
- actual = select_tag "colors", "<option>Red</option><option>Blue</option><option>Green</option>".html_safe, :multiple => :true
- expected = %(<select id="colors" multiple="multiple" name="colors"><option>Red</option><option>Blue</option><option>Green</option></select>)
- assert_dom_equal expected, actual
- end
-
- def test_select_tag_disabled
- actual = select_tag "places", "<option>Home</option><option>Work</option><option>Pub</option>".html_safe, :disabled => :true
- expected = %(<select id="places" disabled="disabled" name="places"><option>Home</option><option>Work</option><option>Pub</option></select>)
- assert_dom_equal expected, actual
- end
-
- def test_select_tag_id_sanitized
- input_elem = root_elem(select_tag("project[1]people", "<option>david</option>"))
- assert_match VALID_HTML_ID, input_elem['id']
- end
-
- def test_select_tag_with_array_options
- assert_deprecated /array/ do
- select_tag "people", ["<option>david</option>"]
- end
- end
-
- def test_text_area_tag_size_string
- actual = text_area_tag "body", "hello world", "size" => "20x40"
- expected = %(<textarea cols="20" id="body" name="body" rows="40">hello world</textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_area_tag_size_symbol
- actual = text_area_tag "body", "hello world", :size => "20x40"
- expected = %(<textarea cols="20" id="body" name="body" rows="40">hello world</textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_area_tag_should_disregard_size_if_its_given_as_an_integer
- actual = text_area_tag "body", "hello world", :size => 20
- expected = %(<textarea id="body" name="body">hello world</textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_area_tag_id_sanitized
- input_elem = root_elem(text_area_tag("item[][description]"))
- assert_match VALID_HTML_ID, input_elem['id']
- end
-
- def test_text_area_tag_escape_content
- actual = text_area_tag "body", "<b>hello world</b>", :size => "20x40"
- expected = %(<textarea cols="20" id="body" name="body" rows="40">&lt;b&gt;hello world&lt;/b&gt;</textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_area_tag_unescaped_content
- actual = text_area_tag "body", "<b>hello world</b>", :size => "20x40", :escape => false
- expected = %(<textarea cols="20" id="body" name="body" rows="40"><b>hello world</b></textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_area_tag_unescaped_nil_content
- actual = text_area_tag "body", nil, :escape => false
- expected = %(<textarea id="body" name="body"></textarea>)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag
- actual = text_field_tag "title", "Hello!"
- expected = %(<input id="title" name="title" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_class_string
- actual = text_field_tag "title", "Hello!", "class" => "admin"
- expected = %(<input class="admin" id="title" name="title" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_size_symbol
- actual = text_field_tag "title", "Hello!", :size => 75
- expected = %(<input id="title" name="title" size="75" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_size_string
- actual = text_field_tag "title", "Hello!", "size" => "75"
- expected = %(<input id="title" name="title" size="75" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_maxlength_symbol
- actual = text_field_tag "title", "Hello!", :maxlength => 75
- expected = %(<input id="title" name="title" maxlength="75" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_maxlength_string
- actual = text_field_tag "title", "Hello!", "maxlength" => "75"
- expected = %(<input id="title" name="title" maxlength="75" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_disabled
- actual = text_field_tag "title", "Hello!", :disabled => :true
- expected = %(<input id="title" name="title" disabled="disabled" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_with_multiple_options
- actual = text_field_tag "title", "Hello!", :size => 70, :maxlength => 80
- expected = %(<input id="title" name="title" size="70" maxlength="80" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_text_field_tag_id_sanitized
- input_elem = root_elem(text_field_tag("item[][title]"))
- assert_match VALID_HTML_ID, input_elem['id']
- end
-
- def test_label_tag_without_text
- actual = label_tag "title"
- expected = %(<label for="title">Title</label>)
- assert_dom_equal expected, actual
- end
-
- def test_label_tag_with_symbol
- actual = label_tag :title
- expected = %(<label for="title">Title</label>)
- assert_dom_equal expected, actual
- end
-
- def test_label_tag_with_text
- actual = label_tag "title", "My Title"
- expected = %(<label for="title">My Title</label>)
- assert_dom_equal expected, actual
- end
-
- def test_label_tag_class_string
- actual = label_tag "title", "My Title", "class" => "small_label"
- expected = %(<label for="title" class="small_label">My Title</label>)
- assert_dom_equal expected, actual
- end
-
- def test_label_tag_id_sanitized
- label_elem = root_elem(label_tag("item[title]"))
- assert_match VALID_HTML_ID, label_elem['for']
- end
-
- def test_boolean_options
- assert_dom_equal %(<input checked="checked" disabled="disabled" id="admin" name="admin" readonly="readonly" type="checkbox" value="1" />), check_box_tag("admin", 1, true, 'disabled' => true, :readonly => "yes")
- assert_dom_equal %(<input checked="checked" id="admin" name="admin" type="checkbox" value="1" />), check_box_tag("admin", 1, true, :disabled => false, :readonly => nil)
- assert_dom_equal %(<input type="checkbox" />), tag(:input, :type => "checkbox", :checked => false)
- assert_dom_equal %(<select id="people" multiple="multiple" name="people[]"><option>david</option></select>), select_tag("people", "<option>david</option>".html_safe, :multiple => true)
- assert_dom_equal %(<select id="people_" multiple="multiple" name="people[]"><option>david</option></select>), select_tag("people[]", "<option>david</option>".html_safe, :multiple => true)
- assert_dom_equal %(<select id="people" name="people"><option>david</option></select>), select_tag("people", "<option>david</option>".html_safe, :multiple => nil)
- end
-
- def test_stringify_symbol_keys
- actual = text_field_tag "title", "Hello!", :id => "admin"
- expected = %(<input id="admin" name="title" type="text" value="Hello!" />)
- assert_dom_equal expected, actual
- end
-
- def test_submit_tag
- assert_dom_equal(
- %(<input name='commit' onclick="if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';alert('hello!');result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" type="submit" value="Save" />),
- submit_tag("Save", :disable_with => "Saving...", :onclick => "alert('hello!')")
- )
- end
-
- def test_submit_tag_with_no_onclick_options
- assert_dom_equal(
- %(<input name='commit' onclick="if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" type="submit" value="Save" />),
- submit_tag("Save", :disable_with => "Saving...")
- )
- end
-
- def test_submit_tag_with_confirmation
- assert_dom_equal(
- %(<input name='commit' type='submit' value='Save' onclick="if (!confirm('Are you sure?')) return false; return true;"/>),
- submit_tag("Save", :confirm => "Are you sure?")
- )
- end
-
- def test_submit_tag_with_confirmation_and_with_disable_with
- assert_dom_equal(
- %(<input name="commit" onclick="if (!confirm('Are you sure?')) return false; if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" type="submit" value="Save" />),
- submit_tag("Save", :disable_with => "Saving...", :confirm => "Are you sure?")
- )
- end
-
- def test_image_submit_tag_with_confirmation
- assert_dom_equal(
- %(<input type="image" src="/images/save.gif" onclick="return confirm('Are you sure?');"/>),
- image_submit_tag("save.gif", :confirm => "Are you sure?")
- )
- end
-
- def test_pass
- assert_equal 1, 1
- end
-
- def test_field_set_tag_in_erb
- __in_erb_template = ''
- field_set_tag("Your details") { concat "Hello world!" }
-
- expected = %(<fieldset><legend>Your details</legend>Hello world!</fieldset>)
- assert_dom_equal expected, output_buffer
-
- self.output_buffer = ''.html_safe
- field_set_tag { concat "Hello world!" }
-
- expected = %(<fieldset>Hello world!</fieldset>)
- assert_dom_equal expected, output_buffer
-
- self.output_buffer = ''.html_safe
- field_set_tag('') { concat "Hello world!" }
-
- expected = %(<fieldset>Hello world!</fieldset>)
- assert_dom_equal expected, output_buffer
-
- self.output_buffer = ''.html_safe
- field_set_tag('', :class => 'format') { concat "Hello world!" }
-
- expected = %(<fieldset class="format">Hello world!</fieldset>)
- assert_dom_equal expected, output_buffer
- end
-
- def protect_against_forgery?
- false
- end
-
- private
-
- def root_elem(rendered_content)
- HTML::Document.new(rendered_content).root.children[0]
- end
-end
diff --git a/vendor/plugins/rails_xss/test/javascript_helper_test.rb b/vendor/plugins/rails_xss/test/javascript_helper_test.rb
deleted file mode 100644
index 691d97a15..000000000
--- a/vendor/plugins/rails_xss/test/javascript_helper_test.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require 'test_helper'
-
-class JavascriptHelperTest < ActionView::TestCase
- def test_escape_javascript_with_safebuffer
- given = %('quoted' "double-quoted" new-line:\n </closed>)
- expect = %(\\'quoted\\' \\"double-quoted\\" new-line:\\n <\\/closed>)
- assert_equal expect, escape_javascript(given)
- assert_equal expect, escape_javascript(ActiveSupport::SafeBuffer.new(given))
- end
-end
diff --git a/vendor/plugins/rails_xss/test/output_escaping_test.rb b/vendor/plugins/rails_xss/test/output_escaping_test.rb
deleted file mode 100644
index 8b6f8b83c..000000000
--- a/vendor/plugins/rails_xss/test/output_escaping_test.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require 'test_helper'
-
-class OutputEscapingTest < ActiveSupport::TestCase
-
- test "escape_html shouldn't die when passed nil" do
- assert ERB::Util.h(nil).blank?
- end
-
- test "escapeHTML should escape strings" do
- assert_equal "&lt;&gt;&quot;", ERB::Util.h("<>\"")
- end
-
- test "escapeHTML shouldn't touch explicitly safe strings" do
- # TODO this seems easier to compose and reason about, but
- # this should be verified
- assert_equal "<", ERB::Util.h("<".html_safe)
- end
-
-end
diff --git a/vendor/plugins/rails_xss/test/output_safety_test.rb b/vendor/plugins/rails_xss/test/output_safety_test.rb
deleted file mode 100644
index 2e376477d..000000000
--- a/vendor/plugins/rails_xss/test/output_safety_test.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-require 'test_helper'
-
-class OutputSafetyTest < ActiveSupport::TestCase
- def setup
- @string = "hello"
- @object = Class.new(Object) do
- def to_s
- "other"
- end
- end.new
- end
-
- test "A string is unsafe by default" do
- assert !@string.html_safe?
- end
-
- test "A string can be marked safe" do
- string = @string.html_safe
- assert string.html_safe?
- end
-
- test "Marking a string safe returns the string" do
- assert_equal @string, @string.html_safe
- end
-
- test "A fixnum is safe by default" do
- assert 5.html_safe?
- end
-
- test "An object is unsafe by default" do
- assert !@object.html_safe?
- end
-
- test "Adding an object to a safe string returns a safe string" do
- string = @string.html_safe
- string << @object
-
- assert_equal "helloother", string
- assert string.html_safe?
- end
-
- test "Adding a safe string to another safe string returns a safe string" do
- @other_string = "other".html_safe
- string = @string.html_safe
- @combination = @other_string + string
-
- assert_equal "otherhello", @combination
- assert @combination.html_safe?
- end
-
- test "Adding an unsafe string to a safe string escapes it and returns a safe string" do
- @other_string = "other".html_safe
- @combination = @other_string + "<foo>"
- @other_combination = @string + "<foo>"
-
- assert_equal "other&lt;foo&gt;", @combination
- assert_equal "hello<foo>", @other_combination
-
- assert @combination.html_safe?
- assert !@other_combination.html_safe?
- end
-
- test "Concatting safe onto unsafe yields unsafe" do
- @other_string = "other"
-
- string = @string.html_safe
- @other_string.concat(string)
- assert !@other_string.html_safe?
- end
-
- test "Concatting unsafe onto safe yields escaped safe" do
- @other_string = "other".html_safe
- string = @other_string.concat("<foo>")
- assert_equal "other&lt;foo&gt;", string
- assert string.html_safe?
- end
-
- test "Concatting safe onto safe yields safe" do
- @other_string = "other".html_safe
- string = @string.html_safe
-
- @other_string.concat(string)
- assert @other_string.html_safe?
- end
-
- test "Concatting safe onto unsafe with << yields unsafe" do
- @other_string = "other"
- string = @string.html_safe
-
- @other_string << string
- assert !@other_string.html_safe?
- end
-
- test "Concatting unsafe onto safe with << yields escaped safe" do
- @other_string = "other".html_safe
- string = @other_string << "<foo>"
- assert_equal "other&lt;foo&gt;", string
- assert string.html_safe?
- end
-
- test "Concatting safe onto safe with << yields safe" do
- @other_string = "other".html_safe
- string = @string.html_safe
-
- @other_string << string
- assert @other_string.html_safe?
- end
-
- test "Concatting a fixnum to safe always yields safe" do
- string = @string.html_safe
- string = string.concat(13)
- assert_equal "hello".concat(13), string
- assert string.html_safe?
- end
-end
diff --git a/vendor/plugins/rails_xss/test/rails_xss_test.rb b/vendor/plugins/rails_xss/test/rails_xss_test.rb
deleted file mode 100644
index b6268bafd..000000000
--- a/vendor/plugins/rails_xss/test/rails_xss_test.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-require 'test_helper'
-
-class RailsXssTest < ActiveSupport::TestCase
- test "ERB::Util.h should mark its return value as safe and escape it" do
- escaped = ERB::Util.h("<p>")
- assert_equal "&lt;p&gt;", escaped
- assert escaped.html_safe?
- end
-
- test "ERB::Util.h should leave previously safe strings alone " do
- # TODO this seems easier to compose and reason about, but
- # this should be verified
- escaped = ERB::Util.h("<p>".html_safe)
- assert_equal "<p>", escaped
- assert escaped.html_safe?
- end
-
- test "ERB::Util.h should not implode when passed a non-string" do
- assert_nothing_raised do
- assert_equal "1", ERB::Util.h(1)
- end
- end
-end
diff --git a/vendor/plugins/rails_xss/test/raw_output_helper_test.rb b/vendor/plugins/rails_xss/test/raw_output_helper_test.rb
deleted file mode 100644
index 2a67f976e..000000000
--- a/vendor/plugins/rails_xss/test/raw_output_helper_test.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require 'test_helper'
-
-class RawOutputHelperTest < ActionView::TestCase
-
- def setup
- @string = "hello"
- end
-
- test "raw returns the safe string" do
- result = raw(@string)
- assert_equal @string, result
- assert result.html_safe?
- end
-
- test "raw handles nil values correctly" do
- assert_equal "", raw(nil)
- end
-end
diff --git a/vendor/plugins/rails_xss/test/safe_buffer_test.rb b/vendor/plugins/rails_xss/test/safe_buffer_test.rb
deleted file mode 100644
index a0a2eccee..000000000
--- a/vendor/plugins/rails_xss/test/safe_buffer_test.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-require 'test_helper'
-
-class SafeBufferTest < ActiveSupport::TestCase
- def setup
- @buffer = ActiveSupport::SafeBuffer.new
- end
-
- test "Should look like a string" do
- assert @buffer.is_a?(String)
- assert_equal "", @buffer
- end
-
- test "Should escape a raw string which is passed to them" do
- @buffer << "<script>"
- assert_equal "&lt;script&gt;", @buffer
- end
-
- test "Should NOT escape a safe value passed to it" do
- @buffer << "<script>".html_safe
- assert_equal "<script>", @buffer
- end
-
- test "Should not mess with an innocuous string" do
- @buffer << "Hello"
- assert_equal "Hello", @buffer
- end
-
- test "Should not mess with a previously escape test" do
- @buffer << ERB::Util.html_escape("<script>")
- assert_equal "&lt;script&gt;", @buffer
- end
-
- test "Should be considered safe" do
- assert @buffer.html_safe?
- end
-
- test "Should return a safe buffer when calling to_s" do
- new_buffer = @buffer.to_s
- assert_equal ActiveSupport::SafeBuffer, new_buffer.class
- end
-
- test "Should not return a safe buffer when using sub" do
- assert !@buffer.sub('', "asdf").html_safe?
- end
-
- test "Should raise argument error when using sub!" do
- assert_raise TypeError do
- @buffer.sub!('', "asdf")
- end
- end
-end
diff --git a/vendor/plugins/rails_xss/test/tag_helper_test.rb b/vendor/plugins/rails_xss/test/tag_helper_test.rb
deleted file mode 100644
index 2a4280943..000000000
--- a/vendor/plugins/rails_xss/test/tag_helper_test.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require 'test_helper'
-
-class TagHelperTest < ActionView::TestCase
-
- def test_content_tag
- assert_equal "<a href=\"create\">Create</a>", content_tag("a", "Create", "href" => "create")
- assert content_tag("a", "Create", "href" => "create").html_safe?
- assert_equal content_tag("a", "Create", "href" => "create"),
- content_tag("a", "Create", :href => "create")
- assert_equal "<p>&lt;script&gt;evil_js&lt;/script&gt;</p>",
- content_tag(:p, '<script>evil_js</script>')
- assert_equal "<p><script>evil_js</script></p>",
- content_tag(:p, '<script>evil_js</script>', nil, false)
- end
-
- def test_tag_honors_html_safe_for_param_values
- ['1&amp;2', '1 &lt; 2', '&#8220;test&#8220;'].each do |escaped|
- assert_equal %(<a href="#{escaped}" />), tag('a', :href => escaped.html_safe)
- end
- end
-end
diff --git a/vendor/plugins/rails_xss/test/test_helper.rb b/vendor/plugins/rails_xss/test/test_helper.rb
deleted file mode 100644
index d9594e446..000000000
--- a/vendor/plugins/rails_xss/test/test_helper.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-abort 'RAILS_ROOT=/path/to/rails/2.3/app rake test' unless ENV['RAILS_ROOT']
-require File.expand_path('config/environment', ENV['RAILS_ROOT'])
-require File.expand_path('../../init', __FILE__)
-require 'active_support/test_case'
-require 'action_view/test_case'
-require 'test/unit'
diff --git a/vendor/plugins/rails_xss/test/text_helper_test.rb b/vendor/plugins/rails_xss/test/text_helper_test.rb
deleted file mode 100644
index b74ae547c..000000000
--- a/vendor/plugins/rails_xss/test/text_helper_test.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require 'test_helper'
-
-class TextHelperTest < ActionView::TestCase
-
- def setup
- @controller = Class.new do
- attr_accessor :request
- def url_for(*args) "http://www.example.com" end
- end.new
- end
-
- def test_simple_format_with_escaping_html_options
- assert_dom_equal(%(<p class="intro">It's nice to have options.</p>),
- simple_format("It's nice to have options.", :class=>"intro"))
- end
-
- def test_simple_format_should_not_escape_safe_content
- assert_dom_equal(%(<p>This is <script>safe_js</script>.</p>),
- simple_format('This is <script>safe_js</script>.'.html_safe))
- end
-
- def test_simple_format_escapes_unsafe_content
- assert_dom_equal(%(<p>This is &lt;script&gt;evil_js&lt;/script&gt;.</p>),
- simple_format('This is <script>evil_js</script>.'))
- end
-
- def test_truncate_should_not_be_html_safe
- assert !truncate("Hello World!", :length => 12).html_safe?
- end
-end
diff --git a/vendor/plugins/rails_xss/test/url_for_test.rb b/vendor/plugins/rails_xss/test/url_for_test.rb
deleted file mode 100644
index b13451bfb..000000000
--- a/vendor/plugins/rails_xss/test/url_for_test.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-require 'test_helper'
-
-class UrlHelperTest < ActionView::TestCase
-
- def abcd(hash = {})
- hash_for(:a => :b, :c => :d).merge(hash)
- end
-
- def hash_for(opts = {})
- {:controller => "foo", :action => "bar"}.merge(opts)
- end
-
- def test_url_for_does_not_escape_urls_if_explicitly_stated
- assert_equal "/foo/bar?a=b&c=d", url_for(abcd(:escape => false))
- end
-
- def test_link_tag_with_img
- link = link_to("<img src='/favicon.jpg' />".html_safe, "/")
- expected = %{<a href="/"><img src='/favicon.jpg' /></a>}
- assert_dom_equal expected, link
- end
-
- def test_link_to_should_not_escape_content_for_html_safe
- link = link_to("Some <p>html</p>".html_safe, "/")
- expected = %{<a href="/">Some <p>html</p></a>}
- assert_dom_equal link, expected
- end
-
- def test_link_to_escapes_content_for_non_safe
- link = link_to("Some <p>html</p>", "/")
- expected = %{<a href="/">Some &lt;p&gt;html&lt;/p&gt;</a>}
- assert_dom_equal link, expected
- end
-
- def test_url_for_escaping_is_safety_aware
- assert url_for(abcd(:escape => true)).html_safe?, "escaped urls should be html_safe?"
- assert !url_for(abcd(:escape => false)).html_safe?, "non-escaped urls should not be html_safe?"
- end
-end
diff --git a/vendor/plugins/strip_attributes/lib/strip_attributes.rb b/vendor/plugins/strip_attributes/lib/strip_attributes.rb
index 70f414654..bb93aa9a7 100644
--- a/vendor/plugins/strip_attributes/lib/strip_attributes.rb
+++ b/vendor/plugins/strip_attributes/lib/strip_attributes.rb
@@ -3,10 +3,12 @@ module StripAttributes
# XXX this differs from official StripAttributes, as it doesn't make blank cells null.
def strip_attributes!(options = nil)
before_validation do |record|
- attributes = StripAttributes.narrow(record.attributes, options)
- attributes.each do |attr, value|
+ attribute_names = StripAttributes.narrow(record.attribute_names, options)
+
+ attribute_names.each do |attribute_name|
+ value = record[attribute_name]
if value.respond_to?(:strip)
- record[attr] = (value.nil?) ? nil : value.strip
+ record[attribute_name] = (value.nil?) ? nil : value.strip
end
end
end
@@ -14,16 +16,16 @@ module StripAttributes
# Necessary because Rails has removed the narrowing of attributes using :only
# and :except on Base#attributes
- def self.narrow(attributes, options)
+ def self.narrow(attribute_names, options)
if options.nil?
- attributes
+ attribute_names
else
if except = options[:except]
except = Array(except).collect { |attribute| attribute.to_s }
- attributes.except(*except)
+ attribute_names - except
elsif only = options[:only]
only = Array(only).collect { |attribute| attribute.to_s }
- attributes.slice(*only)
+ attribute_names & only
else
raise ArgumentError, "Options does not specify :except or :only (#{options.keys.inspect})"
end
diff --git a/vendor/plugins/strip_attributes/test/strip_attributes_test.rb b/vendor/plugins/strip_attributes/test/strip_attributes_test.rb
index 95754fca7..8158dc664 100644
--- a/vendor/plugins/strip_attributes/test/strip_attributes_test.rb
+++ b/vendor/plugins/strip_attributes/test/strip_attributes_test.rb
@@ -49,7 +49,7 @@ class StripAttributesTest < Test::Unit::TestCase
assert_equal "foo", record.foo
assert_equal "bar", record.bar
assert_equal "biz", record.biz
- assert_nil record.baz
+ assert_equal "", record.baz
end
def test_should_strip_only_one_field
@@ -76,7 +76,7 @@ class StripAttributesTest < Test::Unit::TestCase
assert_equal "\tfoo", record.foo
assert_equal "bar", record.bar
assert_equal "biz", record.biz
- assert_nil record.baz
+ assert_equal "", record.baz
end
def test_should_strip_all_except_three_fields
@@ -85,6 +85,6 @@ class StripAttributesTest < Test::Unit::TestCase
assert_equal "\tfoo", record.foo
assert_equal "bar \t ", record.bar
assert_equal "\tbiz ", record.biz
- assert_nil record.baz
+ assert_equal "", record.baz
end
end