Commit 11dfb86bf56dd6ce8784ab13682b46a96f9efc2f
Exists in
master
and in
29 other branches
Merge branch 'master' of gitlab.com:noosfero/noosfero
Showing
174 changed files
with
2162 additions
and
2196 deletions
Show diff stats
Gemfile
... | ... | @@ -11,7 +11,6 @@ gem 'will_paginate', '~> 3.0.3' |
11 | 11 | gem 'ruby-feedparser', '~> 0.7' |
12 | 12 | gem 'daemons', '~> 1.1.5' |
13 | 13 | gem 'thin', '~> 1.3.1' |
14 | -gem 'hpricot', '~> 0.8.6' | |
15 | 14 | gem 'nokogiri', '~> 1.5.5' |
16 | 15 | gem 'rake', :require => false |
17 | 16 | gem 'rest-client', '~> 1.6.7' |
... | ... | @@ -41,9 +40,12 @@ group :cucumber do |
41 | 40 | gem 'selenium-webdriver', '~> 2.39.0' |
42 | 41 | end |
43 | 42 | |
43 | +# Requires custom dependencies | |
44 | +eval(File.read('config/Gemfile'), binding) rescue nil | |
45 | + | |
44 | 46 | # include gemfiles from enabled plugins |
45 | 47 | # plugins in baseplugins/ are not included on purpose. They should not have any |
46 | 48 | # dependencies. |
47 | 49 | Dir.glob('config/plugins/*/Gemfile').each do |gemfile| |
48 | 50 | eval File.read(gemfile) |
49 | 51 | -end |
52 | +end | |
50 | 53 | \ No newline at end of file | ... | ... |
INSTALL.md
... | ... | @@ -21,7 +21,7 @@ Noosfero is written in Ruby with the "[Rails framework](http://www.rubyonrails.o |
21 | 21 | You need to install some packages Noosfero depends on. On Debian GNU/Linux or Debian-based systems, all of these packages are available through the Debian archive. You can install them with the following command: |
22 | 22 | |
23 | 23 | # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby1.8 \ |
24 | - libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libhpricot-ruby \ | |
24 | + libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby \ | |
25 | 25 | libwill-paginate-ruby iso-codes libfeedparser-ruby libdaemons-ruby thin \ |
26 | 26 | tango-icon-theme |
27 | 27 | |
... | ... | @@ -40,7 +40,6 @@ On other systems, they may or may not be available through your regular package |
40 | 40 | * Daemons - http://daemons.rubyforge.org |
41 | 41 | * Thin: http://code.macournoyer.com/thin |
42 | 42 | * tango-icon-theme: http://tango.freedesktop.org/Tango_Icon_Library |
43 | -* Hpricot: http://hpricot.com | |
44 | 43 | |
45 | 44 | If you manage to install Noosfero successfully on other systems than Debian, |
46 | 45 | please feel free to contact the Noosfero development mailing with the | ... | ... |
INSTALL.multitenancy.md
... | ... | @@ -26,7 +26,7 @@ The file config/database.yml must follow a structure in order to achieve multite |
26 | 26 | |
27 | 27 | Each "hosted" environment must have an entry like this: |
28 | 28 | |
29 | - env1_production: | |
29 | + env1_production: &DEFAULT | |
30 | 30 | adapter: postgresql |
31 | 31 | encoding: unicode |
32 | 32 | database: noosfero |
... | ... | @@ -61,7 +61,7 @@ The "hosted" environments define, besides the `schema_search_path`, a list of do |
61 | 61 | You must also tell the application which is the default environment. |
62 | 62 | |
63 | 63 | production: |
64 | - env1_production | |
64 | + <<: *DEFAULT | |
65 | 65 | |
66 | 66 | On the example above there are only three hosted environments, but it can be more than three. The schemas `env2` and `env3` must already exist in the same database of the hosting environment. As postgres user, you can create them typing: |
67 | 67 | ... | ... |
app/controllers/application_controller.rb
... | ... | @@ -28,6 +28,7 @@ class ApplicationController < ActionController::Base |
28 | 28 | unless environment.access_control_allow_methods.blank? |
29 | 29 | response.headers["Access-Control-Allow-Methods"] = environment.access_control_allow_methods |
30 | 30 | end |
31 | + response.headers["Access-Control-Allow-Credentials"] = 'true' | |
31 | 32 | elsif environment.restrict_to_access_control_origins |
32 | 33 | render_access_denied _('Origin not in allowed.') |
33 | 34 | end | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -8,11 +8,7 @@ module ApplicationHelper |
8 | 8 | |
9 | 9 | include PermissionNameHelper |
10 | 10 | |
11 | - include LightboxHelper | |
12 | - | |
13 | - include ThickboxHelper | |
14 | - | |
15 | - include ColorboxHelper | |
11 | + include ModalHelper | |
16 | 12 | |
17 | 13 | include BoxesHelper |
18 | 14 | |
... | ... | @@ -651,8 +647,8 @@ module ApplicationHelper |
651 | 647 | ' onfocus="if(this.value==\''+s+'\'){this.value=\'\'} this.form.className=\'focus-in\'"'+ |
652 | 648 | ' onblur="if(/^\s*$/.test(this.value)){this.value=\''+s+'\'} this.form.className=\'focus-out\'">'+ |
653 | 649 | '</form>' |
654 | - else #opt == 'lightbox_link' is default | |
655 | - lightbox_link_to '<span class="icon-menu-search"></span>'+ _('Search'), { | |
650 | + else | |
651 | + modal_link_to '<span class="icon-menu-search"></span>'+ _('Search'), { | |
656 | 652 | :controller => 'search', |
657 | 653 | :action => 'popup', |
658 | 654 | :category_path => (@category ? @category.explode_path : nil)}, |
... | ... | @@ -1050,7 +1046,7 @@ module ApplicationHelper |
1050 | 1046 | {s_('contents|Most commented') => {:href => url_for({:controller => 'search', :action => 'contents', :filter => 'more_comments'})}} |
1051 | 1047 | ] |
1052 | 1048 | if logged_in? |
1053 | - links.push(_('New content') => colorbox_options({:href => url_for({:controller => 'cms', :action => 'new', :profile => current_user.login, :cms => true})})) | |
1049 | + links.push(_('New content') => modal_options({:href => url_for({:controller => 'cms', :action => 'new', :profile => current_user.login, :cms => true})})) | |
1054 | 1050 | end |
1055 | 1051 | |
1056 | 1052 | link_to(content_tag(:span, _('Contents'), :class => 'icon-menu-articles'), {:controller => "search", :action => 'contents', :category_path => nil}, :id => 'submenu-contents') + |
... | ... | @@ -1398,16 +1394,16 @@ module ApplicationHelper |
1398 | 1394 | end |
1399 | 1395 | |
1400 | 1396 | def convert_macro(html, source) |
1401 | - doc = Hpricot(html) | |
1397 | + doc = Nokogiri::HTML.fragment html | |
1402 | 1398 | #TODO This way is more efficient but do not support macro inside of |
1403 | 1399 | # macro. You must parse them from the inside-out in order to enable |
1404 | 1400 | # that. |
1405 | - doc.search('.macro').each do |macro| | |
1401 | + doc.css('.macro').each do |macro| | |
1406 | 1402 | macro_name = macro['data-macro'] |
1407 | 1403 | result = @plugins.parse_macro(macro_name, macro, source) |
1408 | 1404 | macro.inner_html = result.kind_of?(Proc) ? self.instance_exec(&result) : result |
1409 | 1405 | end |
1410 | - doc.html | |
1406 | + doc.to_html | |
1411 | 1407 | end |
1412 | 1408 | |
1413 | 1409 | def default_folder_for_image_upload(profile) | ... | ... |
app/helpers/boxes_helper.rb
... | ... | @@ -231,7 +231,7 @@ module BoxesHelper |
231 | 231 | end |
232 | 232 | |
233 | 233 | if block.editable? |
234 | - buttons << colorbox_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id }) | |
234 | + buttons << modal_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id }) | |
235 | 235 | end |
236 | 236 | |
237 | 237 | if !block.main? |
... | ... | @@ -241,7 +241,7 @@ module BoxesHelper |
241 | 241 | end |
242 | 242 | |
243 | 243 | if block.respond_to?(:help) |
244 | - buttons << thickbox_inline_popup_icon(:help, _('Help on this block'), {}, "help-on-box-#{block.id}") << content_tag('div', content_tag('h2', _('Help')) + content_tag('div', block.help, :style => 'margin-bottom: 1em;') + thickbox_close_button(_('Close')), :style => 'display: none;', :id => "help-on-box-#{block.id}") | |
244 | + buttons << modal_inline_icon(:help, _('Help on this block'), {}, "#help-on-box-#{block.id}") << content_tag('div', content_tag('h2', _('Help')) + content_tag('div', block.help, :style => 'margin-bottom: 1em;') + modal_close_button(_('Close')), :style => 'display: none;', :id => "help-on-box-#{block.id}") | |
245 | 245 | end |
246 | 246 | |
247 | 247 | if block.embedable? | ... | ... |
app/helpers/colorbox_helper.rb
... | ... | @@ -1,25 +0,0 @@ |
1 | -module ColorboxHelper | |
2 | - | |
3 | - def colorbox_close_button(text, options = {}) | |
4 | - button(:close, text, '#', colorbox_options(options, :close)) | |
5 | - end | |
6 | - | |
7 | - def colorbox_button(type, label, url, options = {}) | |
8 | - button(type, label, url, colorbox_options(options)) | |
9 | - end | |
10 | - | |
11 | - def colorbox_icon_button(type, label, url, options = {}) | |
12 | - icon_button(type, label, url, colorbox_options(options)) | |
13 | - end | |
14 | - | |
15 | - # options must be an HTML options hash as passed to link_to etc. | |
16 | - # | |
17 | - # returns a new hash with colorbox class added. Keeps existing classes. | |
18 | - def colorbox_options(options, type=nil) | |
19 | - the_class = 'colorbox' | |
20 | - the_class += "-#{type.to_s}" unless type.nil? | |
21 | - the_class << " #{options[:class]}" if options.has_key?(:class) | |
22 | - options.merge(:class => the_class) | |
23 | - end | |
24 | - | |
25 | -end |
app/helpers/comment_helper.rb
... | ... | @@ -65,7 +65,7 @@ module CommentHelper |
65 | 65 | |
66 | 66 | def link_for_edit(comment) |
67 | 67 | if comment.can_be_updated_by?(user) |
68 | - {:link => expirable_comment_link(comment, :edit, _('Edit'), url_for(:profile => profile.identifier, :controller => :comment, :action => :edit, :id => comment.id),:class => 'colorbox')} | |
68 | + {:link => expirable_comment_link(comment, :edit, _('Edit'), url_for(:profile => profile.identifier, :controller => :comment, :action => :edit, :id => comment.id),:class => 'modal')} | |
69 | 69 | end |
70 | 70 | end |
71 | 71 | ... | ... |
app/helpers/layout_helper.rb
app/helpers/lightbox_helper.rb
... | ... | @@ -1,36 +0,0 @@ |
1 | -module LightboxHelper | |
2 | - | |
3 | - def lightbox_link_to(text, url, options = {}) | |
4 | - link_to(text, url, lightbox_options(options)) | |
5 | - end | |
6 | - | |
7 | - def lightbox_close_button(text, options = {}) | |
8 | - button(:close, text, '#', lightbox_options(options, 'lbAction').merge(:rel => 'deactivate')) | |
9 | - end | |
10 | - | |
11 | - def lightbox_button(type, label, url, options = {}) | |
12 | - button(type, label, url, lightbox_options(options)) | |
13 | - end | |
14 | - | |
15 | - def lightbox_icon_button(type, label, url, options = {}) | |
16 | - icon_button(type, label, url, lightbox_options(options)) | |
17 | - end | |
18 | - | |
19 | - # options must be an HTML options hash as passed to link_to etc. | |
20 | - # | |
21 | - # returns a new hash with lightbox class added. Keeps existing classes. | |
22 | - def lightbox_options(options, lightbox_type = 'lbOn') | |
23 | - the_class = lightbox_type | |
24 | - the_class << " #{options[:class]}" if options.has_key?(:class) | |
25 | - options.merge(:class => the_class) | |
26 | - end | |
27 | - | |
28 | - def lightbox? | |
29 | - request.xhr? | |
30 | - end | |
31 | - | |
32 | - def lightbox_remote_button(type, label, url, options = {}) | |
33 | - button(type, label, url, lightbox_options(options, 'remote-lbOn')) | |
34 | - end | |
35 | - | |
36 | -end |
... | ... | @@ -0,0 +1,46 @@ |
1 | +module ModalHelper | |
2 | + | |
3 | + def modal_inline_link_to title, url, selector, options = {} | |
4 | + link_to title, url, modal_options(options.merge(:inline => selector)) | |
5 | + end | |
6 | + | |
7 | + def modal_inline_icon type, title, url, selector, options = {} | |
8 | + icon_button type, title, url, modal_options(options.merge(:inline => selector)) | |
9 | + end | |
10 | + | |
11 | + def modal_link_to title, url, options = {} | |
12 | + link_to title, url, modal_options(options) | |
13 | + end | |
14 | + | |
15 | + def modal_close_link text, options = {} | |
16 | + link_to text, '#', modal_options(options, :close) | |
17 | + end | |
18 | + | |
19 | + def modal_close_button(text, options = {}) | |
20 | + button :close, text, '#', modal_options(options, :close).merge(:rel => 'deactivate') | |
21 | + end | |
22 | + | |
23 | + def modal_button(type, label, url, options = {}) | |
24 | + button type, label, url, modal_options(options) | |
25 | + end | |
26 | + | |
27 | + def modal_icon_button(type, label, url, options = {}) | |
28 | + icon_button type, label, url, modal_options(options) | |
29 | + end | |
30 | + | |
31 | + # options must be an HTML options hash as passed to link_to etc. | |
32 | + # | |
33 | + # returns a new hash with modal class added. Keeps existing classes. | |
34 | + def modal_options(options, type=nil) | |
35 | + inline_selector = options.delete :inline | |
36 | + options[:onclick] = "return noosfero.modal.inline('#{inline_selector}')" if inline_selector | |
37 | + | |
38 | + classes = if inline_selector then '' else 'modal-toggle' end | |
39 | + classes += " modal-#{type.to_s}" if type.present? | |
40 | + classes << " #{options[:class]}" if options.has_key? :class | |
41 | + options.merge!(:class => classes) | |
42 | + | |
43 | + options | |
44 | + end | |
45 | + | |
46 | +end | ... | ... |
app/helpers/thickbox_helper.rb
... | ... | @@ -1,11 +0,0 @@ |
1 | -module ThickboxHelper | |
2 | - def thickbox_inline_popup_link(title, url, id, options = {}) | |
3 | - link_to(title, url_for(url) + "#TB_inline?height=300&width=500&inlineId=#{id}&modal=true", {:class => 'thickbox'}.merge(options)) | |
4 | - end | |
5 | - def thickbox_inline_popup_icon(type, title, url, id, options = {}) | |
6 | - icon_button(type, title, url_for(url) + "#TB_inline?height=300&width=500&inlineId=#{id}&modal=true", {:class => "thickbox"}.merge(options)) | |
7 | - end | |
8 | - def thickbox_close_button(title) | |
9 | - button_to_function(:close, title, 'tb_remove();') | |
10 | - end | |
11 | -end |
app/models/article.rb
1 | -require 'hpricot' | |
2 | 1 | |
3 | 2 | class Article < ActiveRecord::Base |
4 | 3 | |
... | ... | @@ -707,7 +706,7 @@ class Article < ActiveRecord::Base |
707 | 706 | end |
708 | 707 | |
709 | 708 | def first_paragraph |
710 | - paragraphs = Hpricot(to_html).search('p') | |
709 | + paragraphs = Nokogiri::HTML.fragment(to_html).css('p') | |
711 | 710 | paragraphs.empty? ? '' : paragraphs.first.to_html |
712 | 711 | end |
713 | 712 | |
... | ... | @@ -729,8 +728,8 @@ class Article < ActiveRecord::Base |
729 | 728 | |
730 | 729 | def body_images_paths |
731 | 730 | require 'uri' |
732 | - Hpricot(self.body.to_s).search('img[@src]').collect do |i| | |
733 | - (self.profile && self.profile.environment) ? URI.join(self.profile.environment.top_url, URI.escape(i.attributes['src'])).to_s : i.attributes['src'] | |
731 | + Nokogiri::HTML.fragment(self.body.to_s).css('img[src]').collect do |i| | |
732 | + (self.profile && self.profile.environment) ? URI.join(self.profile.environment.top_url, URI.escape(i['src'])).to_s : i['src'] | |
734 | 733 | end |
735 | 734 | end |
736 | 735 | |
... | ... | @@ -767,8 +766,8 @@ class Article < ActiveRecord::Base |
767 | 766 | end |
768 | 767 | |
769 | 768 | def first_image |
770 | - img = Hpricot(self.lead.to_s).search('img[@src]').first || Hpricot(self.body.to_s).search('img').first | |
771 | - img.nil? ? '' : img.attributes['src'] | |
769 | + img = Nokogiri::HTML.fragment(self.lead.to_s).css('img[src]').first || Nokogiri::HTML.fragment(self.body.to_s).search('img').first | |
770 | + img.nil? ? '' : img['src'] | |
772 | 771 | end |
773 | 772 | |
774 | 773 | delegate :lat, :lng, :region, :region_id, :environment, :environment_id, :to => :profile, :allow_nil => true | ... | ... |
app/models/enterprise.rb
... | ... | @@ -19,7 +19,8 @@ class Enterprise < Organization |
19 | 19 | has_many :inputs, :through => :products |
20 | 20 | has_many :production_costs, :as => :owner |
21 | 21 | |
22 | - has_and_belongs_to_many :fans, :class_name => 'Person', :join_table => 'favorite_enteprises_people' | |
22 | + has_many :favorite_enterprise_people | |
23 | + has_many :fans, through: :favorite_enterprise_people, source: :person | |
23 | 24 | |
24 | 25 | def product_categories |
25 | 26 | ProductCategory.by_enterprise(self) | ... | ... |
app/models/environment.rb
... | ... | @@ -273,6 +273,7 @@ class Environment < ActiveRecord::Base |
273 | 273 | settings_items :help_message_to_add_enterprise, :type => String, :default => '' |
274 | 274 | settings_items :tip_message_enterprise_activation_question, :type => String, :default => '' |
275 | 275 | |
276 | + settings_items :currency_iso_unit, :type => String, :default => 'USD' | |
276 | 277 | settings_items :currency_unit, :type => String, :default => '$' |
277 | 278 | settings_items :currency_separator, :type => String, :default => '.' |
278 | 279 | settings_items :currency_delimiter, :type => String, :default => ',' | ... | ... |
app/models/external_feed.rb
... | ... | @@ -14,9 +14,9 @@ class ExternalFeed < ActiveRecord::Base |
14 | 14 | |
15 | 15 | def add_item(title, link, date, content) |
16 | 16 | return if content.blank? |
17 | - doc = Hpricot(content) | |
18 | - doc.search('*').each do |p| | |
19 | - if p.instance_of? Hpricot::Elem | |
17 | + doc = Nokogiri::HTML.fragment content | |
18 | + doc.css('*').each do |p| | |
19 | + if p.instance_of? Nokogiri::XML::Element | |
20 | 20 | p.remove_attribute 'style' |
21 | 21 | p.remove_attribute 'class' |
22 | 22 | end |
... | ... | @@ -26,10 +26,10 @@ class ExternalFeed < ActiveRecord::Base |
26 | 26 | article = TinyMceArticle.new |
27 | 27 | article.name = title |
28 | 28 | article.profile = blog.profile |
29 | - article.body = content | |
30 | - article.published_at = date | |
31 | - article.source = link | |
32 | - article.profile = blog.profile | |
29 | + article.body = content | |
30 | + article.published_at = date | |
31 | + article.source = link | |
32 | + article.profile = blog.profile | |
33 | 33 | article.parent = blog |
34 | 34 | article.author_name = self.feed_title |
35 | 35 | unless blog.children.exists?(:slug => article.slug) | ... | ... |
app/models/forum.rb
app/models/input.rb
1 | 1 | class Input < ActiveRecord::Base |
2 | 2 | |
3 | - attr_accessible :product, :product_category, :product_category_id, :amount_used, :unit_id, :price_per_unit, :relevant_to_price | |
3 | + attr_accessible :product, :product_id, :product_category, :product_category_id, | |
4 | + :amount_used, :unit_id, :price_per_unit, :relevant_to_price, :is_from_solidarity_economy | |
4 | 5 | |
5 | 6 | belongs_to :product |
6 | 7 | belongs_to :product_category | ... | ... |
app/models/person_notifier.rb
... | ... | @@ -22,12 +22,17 @@ class PersonNotifier |
22 | 22 | schedule_next_notification_mail |
23 | 23 | end |
24 | 24 | |
25 | + def notify_from | |
26 | + @person.last_notification || DateTime.now - @person.notification_time.hours | |
27 | + end | |
28 | + | |
25 | 29 | def notify |
26 | 30 | if @person.notification_time && @person.notification_time > 0 |
27 | - from = @person.last_notification || DateTime.now - @person.notification_time.hours | |
28 | - notifications = @person.tracked_notifications.find(:all, :conditions => ["created_at > ?", from]) | |
31 | + notifications = @person.tracked_notifications.find(:all, :conditions => ["created_at > ?", notify_from]) | |
32 | + tasks = Task.to(@person).without_spam.pending.where("created_at > ?", notify_from).order_by('created_at', 'asc') | |
33 | + | |
29 | 34 | Noosfero.with_locale @person.environment.default_language do |
30 | - Mailer::content_summary(@person, notifications).deliver unless notifications.empty? | |
35 | + Mailer::content_summary(@person, notifications, tasks).deliver unless notifications.empty? && tasks.empty? | |
31 | 36 | end |
32 | 37 | @person.settings[:last_notification] = DateTime.now |
33 | 38 | @person.save! |
... | ... | @@ -59,8 +64,12 @@ class PersonNotifier |
59 | 64 | end |
60 | 65 | |
61 | 66 | def failure(job) |
62 | - person = Person.find(person_id) | |
63 | - person.notifier.dispatch_notification_mail | |
67 | + begin | |
68 | + person = Person.find(person_id) | |
69 | + person.notifier.dispatch_notification_mail | |
70 | + rescue | |
71 | + Rails.logger.error "PersonNotifier::NotifyJob: Cannot recover from failure" | |
72 | + end | |
64 | 73 | end |
65 | 74 | |
66 | 75 | end |
... | ... | @@ -73,18 +82,24 @@ class PersonNotifier |
73 | 82 | {:theme => nil} |
74 | 83 | end |
75 | 84 | |
76 | - def content_summary(person, notifications) | |
85 | + def content_summary(person, notifications, tasks) | |
86 | + if person.environment | |
87 | + ActionMailer::Base.asset_host = person.environment.top_url | |
88 | + ActionMailer::Base.default_url_options[:host] = person.environment.default_hostname | |
89 | + end | |
90 | + | |
77 | 91 | @current_theme = 'default' |
78 | 92 | @profile = person |
79 | 93 | @recipient = @profile.nickname || @profile.name |
80 | 94 | @notifications = notifications |
95 | + @tasks = tasks | |
81 | 96 | @environment = @profile.environment.name |
82 | 97 | @url = @profile.environment.top_url |
83 | 98 | mail( |
84 | 99 | content_type: "text/html", |
85 | 100 | from: "#{@profile.environment.name} <#{@profile.environment.noreply_email}>", |
86 | 101 | to: @profile.email, |
87 | - subject: _("[%s] Network Activity") % [@profile.environment.name] | |
102 | + subject: _("[%s] Notifications") % [@profile.environment.name] | |
88 | 103 | ) |
89 | 104 | end |
90 | 105 | end | ... | ... |
app/models/product.rb
... | ... | @@ -10,7 +10,8 @@ class Product < ActiveRecord::Base |
10 | 10 | :display => %w[full map] |
11 | 11 | } |
12 | 12 | |
13 | - attr_accessible :name, :product_category, :highlighted, :price, :enterprise, :image_builder, :description, :available, :qualifiers, :unit_id, :discount, :inputs, :qualifiers_list | |
13 | + attr_accessible :name, :product_category, :profile, :profile_id, :enterprise, | |
14 | + :highlighted, :price, :image_builder, :description, :available, :qualifiers, :unit_id, :discount, :inputs, :qualifiers_list | |
14 | 15 | |
15 | 16 | def self.default_search_display |
16 | 17 | 'full' | ... | ... |
app/models/text_article.rb
1 | 1 | require 'noosfero/translatable_content' |
2 | 2 | |
3 | -# a base class for all text article types. | |
3 | +# a base class for all text article types. | |
4 | 4 | class TextArticle < Article |
5 | 5 | |
6 | 6 | xss_terminate :only => [ :name ], :on => 'validation' |
... | ... | @@ -26,10 +26,10 @@ class TextArticle < Article |
26 | 26 | before_save :set_relative_path |
27 | 27 | |
28 | 28 | def set_relative_path |
29 | - parsed = Hpricot(self.body.to_s) | |
30 | - parsed.search('img[@src]').map { |i| change_element_path(i, 'src') } | |
31 | - parsed.search('a[@href]').map { |i| change_element_path(i, 'href') } | |
32 | - self.body = parsed.to_s | |
29 | + parsed = Nokogiri::HTML.fragment(self.body.to_s) | |
30 | + parsed.css('img[src]').each { |i| change_element_path(i, 'src') } | |
31 | + parsed.css('a[href]').each { |i| change_element_path(i, 'href') } | |
32 | + self.body = parsed.to_html | |
33 | 33 | end |
34 | 34 | |
35 | 35 | def change_element_path(el, attribute) | ... | ... |
app/models/user.rb
... | ... | @@ -54,7 +54,7 @@ class User < ActiveRecord::Base |
54 | 54 | |
55 | 55 | user.person = p |
56 | 56 | end |
57 | - if user.environment.enabled?('skip_new_user_email_confirmation') | |
57 | + if user.environment.enabled?('skip_new_user_email_confirmation') | |
58 | 58 | if user.environment.enabled?('admin_must_approve_new_users') |
59 | 59 | create_moderate_task |
60 | 60 | else |
... | ... | @@ -102,6 +102,7 @@ class User < ActiveRecord::Base |
102 | 102 | validates_length_of :email, :within => 3..100, :if => (lambda {|user| !user.email.blank?}) |
103 | 103 | validates_uniqueness_of :login, :email, :case_sensitive => false, :scope => :environment_id |
104 | 104 | before_save :encrypt_password |
105 | + before_save :normalize_email, if: proc{ |u| u.email.present? } | |
105 | 106 | validates_format_of :email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda {|user| !user.email.blank?}) |
106 | 107 | |
107 | 108 | validates_inclusion_of :terms_accepted, :in => [ '1' ], :if => lambda { |u| ! u.terms_of_use.blank? }, :message => N_('{fn} must be checked in order to signup.').fix_i18n |
... | ... | @@ -114,6 +115,10 @@ class User < ActiveRecord::Base |
114 | 115 | u && u.authenticated?(password) ? u : nil |
115 | 116 | end |
116 | 117 | |
118 | + def register_login | |
119 | + self.update_attribute :last_login_at, Time.now | |
120 | + end | |
121 | + | |
117 | 122 | # Activates the user in the database. |
118 | 123 | def activate |
119 | 124 | return false unless self.person |
... | ... | @@ -332,6 +337,11 @@ class User < ActiveRecord::Base |
332 | 337 | end |
333 | 338 | |
334 | 339 | protected |
340 | + | |
341 | + def normalize_email | |
342 | + self.email = self.email.squish.downcase | |
343 | + end | |
344 | + | |
335 | 345 | # before filter |
336 | 346 | def encrypt_password |
337 | 347 | return if password.blank? |
... | ... | @@ -359,6 +369,6 @@ class User < ActiveRecord::Base |
359 | 369 | |
360 | 370 | def delay_activation_check |
361 | 371 | return if person.is_template? |
362 | - Delayed::Job.enqueue(UserActivationJob.new(self.id), {:priority => 0, :run_at => 72.hours.from_now}) | |
372 | + Delayed::Job.enqueue(UserActivationJob.new(self.id), {:priority => 0, :run_at => (NOOSFERO_CONF['hours_until_user_activation_check'] || 72).hours.from_now}) | |
363 | 373 | end |
364 | 374 | end | ... | ... |
app/views/account/_login_form.html.erb
1 | 1 | <%= labelled_form_for :user, |
2 | 2 | :url => { :controller => 'account', :action => (params[:enterprise_code] ? 'activate_enterprise' : 'login') } do |f| %> |
3 | 3 | |
4 | -<%= f.text_field :login, | |
5 | - :id => ( lightbox? ? 'lightbox_' : '' ) + 'user_login', | |
6 | - :onchange => 'this.value = convToValidLogin( this.value )' %> | |
4 | +<%= f.text_field :login, :id => 'user_login', :onchange => 'this.value = convToValidLogin( this.value )' %> | |
7 | 5 | |
8 | -<%= f.password_field :password, | |
9 | - :id => ( lightbox? ? 'lightbox_' : '' ) + 'user_password' %> | |
6 | +<%= f.password_field :password, :id => 'user_password' %> | |
10 | 7 | |
11 | 8 | <% if params[:enterprise_code] %> |
12 | 9 | <%= hidden_field_tag :enterprise_code, params[:enterprise_code] %> |
... | ... | @@ -16,7 +13,7 @@ |
16 | 13 | |
17 | 14 | <% button_bar do %> |
18 | 15 | <%= submit_button( 'login', _('Log in') )%> |
19 | - <%= lightbox_close_button(_('Cancel')) if lightbox? %> | |
16 | + <%= modal_close_button _('Cancel') if request.xhr? %> | |
20 | 17 | <% end %> |
21 | 18 | |
22 | 19 | <% end %> | ... | ... |
app/views/account/_signup_form.html.erb
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | <input type="hidden" id="signup_time_key" name="signup_time_key" /> |
17 | 17 | <script type="text/javascript"> |
18 | 18 | jQuery.ajax({ |
19 | - type: "POST", | |
19 | + type: "GET", | |
20 | 20 | url: "<%= url_for :controller=>'account', :action=>'signup_time' %>", |
21 | 21 | dataType: 'json', |
22 | 22 | success: function(data) { | ... | ... |
app/views/account/index_anonymous.html.erb
1 | 1 | <h1><%= _('Identify yourself') %></h1> |
2 | 2 | |
3 | 3 | <p> |
4 | -<%= lightbox_link_to _('Login.'), { :controller => 'account', :action => 'login_popup' } %> | |
4 | +<%= modal_link_to _('Login.'), { :controller => 'account', :action => 'login_popup' } %> | |
5 | 5 | |
6 | 6 | <%= _('You need to login to be able to use all the features in this environment.') %> |
7 | 7 | </p> | ... | ... |
app/views/account/login.html.erb
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | <h2><%= _('Login') %></h2> |
4 | 4 | |
5 | 5 | <% @user ||= User.new %> |
6 | -<% is_thickbox ||= false %> | |
6 | +<% is_popin ||= false %> | |
7 | 7 | |
8 | 8 | <%= @message %> |
9 | 9 | |
... | ... | @@ -17,8 +17,8 @@ |
17 | 17 | |
18 | 18 | <% button_bar do %> |
19 | 19 | <%= submit_button( 'login', _('Log in') )%> |
20 | - <% if is_thickbox %> | |
21 | - <%= thickbox_close_button(_('Cancel')) %> | |
20 | + <% if is_popin %> | |
21 | + <%= modal_close_button(_('Cancel')) %> | |
22 | 22 | <% end %> |
23 | 23 | <% end %> |
24 | 24 | ... | ... |
app/views/account/logout_popup.html.erb
app/views/box_organizer/add_block.html.erb
app/views/box_organizer/edit.html.erb
app/views/box_organizer/index.html.erb
1 | 1 | <h1><%= _('Editing sideboxes')%></h1> |
2 | 2 | |
3 | 3 | <% button_bar :class=>'design-menu' do %> |
4 | - <%= colorbox_button('add', _('Add a block'), { :action => 'add_block' }) %> | |
4 | + <%= modal_button('add', _('Add a block'), { :action => 'add_block' }) %> | |
5 | 5 | <%= button(:back, _('Back to control panel'), :controller => (profile.nil? ? 'admin_panel': 'profile_editor')) %> |
6 | 6 | <% end %> | ... | ... |
app/views/cms/edit.html.erb
... | ... | @@ -28,7 +28,7 @@ |
28 | 28 | <% end %> |
29 | 29 | |
30 | 30 | <div style='float: right'> |
31 | - <%= lightbox_button :help, _('Why categorize?'), :action => 'why_categorize' %> | |
31 | + <%= modal_button :help, _('Why categorize?'), :action => 'why_categorize' %> | |
32 | 32 | </div> |
33 | 33 | |
34 | 34 | <%= select_categories(:article, _('Categorize your article')) %> | ... | ... |
app/views/cms/select_article_type.html.erb
app/views/cms/view.html.erb
... | ... | @@ -17,7 +17,7 @@ |
17 | 17 | <% button_bar(:style => 'margin-bottom: 1em;') do %> |
18 | 18 | <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %> |
19 | 19 | |
20 | - <%= colorbox_button('new', _('New content'), :action => 'new', :parent_id => parent_id, :cms => true) %> | |
20 | + <%= modal_button('new', _('New content'), :action => 'new', :parent_id => parent_id, :cms => true) %> | |
21 | 21 | <%= button(:back, _('Back to control panel'), :controller => 'profile_editor', :action => "index") %> |
22 | 22 | <% end %> |
23 | 23 | ... | ... |
app/views/cms/why_categorize.html.erb
app/views/comment/_comment_form.html.erb
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | <%= recaptcha_tags(:display => { :theme => 'clean' }, :ajax => true) %> |
11 | 11 | <% button_bar do %> |
12 | 12 | <%= button_to_function :add, _('Confirm'), "return false", :id => "confirm-captcha" %> |
13 | - <%= button_to_function :cancel, _('Cancel'), "jQuery.colorbox.close()" %> | |
13 | + <%= button_to_function :cancel, _('Cancel'), "noosfero.modal.close()" %> | |
14 | 14 | <% end %> |
15 | 15 | </div> |
16 | 16 | |
... | ... | @@ -31,10 +31,10 @@ function check_captcha(button, confirm_action) { |
31 | 31 | return true; |
32 | 32 | <% else %> |
33 | 33 | jQuery('#recaptcha-container').show(); |
34 | - jQuery.colorbox({ html: jQuery('#recaptcha-container').html(), maxWidth : '600px', maxHeight : '300px' }); | |
34 | + noosfero.modal.inline('#recaptcha-container', {maxWidth :'600px', maxHeight : '300px' }); | |
35 | 35 | jQuery('#confirm-captcha').unbind('click'); |
36 | 36 | jQuery('#confirm-captcha').bind('click', function() { |
37 | - jQuery.colorbox.close(); | |
37 | + noosfero.modal.close(); | |
38 | 38 | button.form.recaptcha_response_field.value = jQuery('#recaptcha_response_field').val(); |
39 | 39 | button.form.recaptcha_challenge_field.value = jQuery('#recaptcha_challenge_field').val(); |
40 | 40 | button.form.confirm.value = 'true'; |
... | ... | @@ -88,7 +88,7 @@ function check_captcha(button, confirm_action) { |
88 | 88 | <% if !edition_mode %> |
89 | 89 | <%= button :cancel, _('Cancel'), '', :id => 'cancel-comment' %> |
90 | 90 | <% else %> |
91 | - <%= button :cancel, _('Cancel'), '#', :onclick => "jQuery.colorbox.close();" %> | |
91 | + <%= button :cancel, _('Cancel'), '#', :onclick => "noosfero.modal.close();" %> | |
92 | 92 | <% end %> |
93 | 93 | <% end %> |
94 | 94 | <% end %> | ... | ... |
app/views/content_viewer/_article_toolbar.html.erb
... | ... | @@ -28,14 +28,14 @@ |
28 | 28 | <%= expirable_button @page, :locale, content, url %> |
29 | 29 | <% end %> |
30 | 30 | |
31 | - <%= colorbox_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) unless remove_content_button(:new, @page) %> | |
31 | + <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) unless remove_content_button(:new, @page) %> | |
32 | 32 | <% end %> |
33 | 33 | |
34 | 34 | <% if @page.accept_uploads? && @page.allow_create?(user) %> |
35 | 35 | <%= button('upload-file', _('Upload files'), profile.admin_url.merge(:controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:upload, @page)%> |
36 | 36 | <% end %> |
37 | 37 | |
38 | - <% if !@page.allow_create?(user) && profile.community? && (@page.blog? || @page.parent && @page.parent.blog?) && !remove_content_button(:suggest, @page) %> | |
38 | + <% if !@page.allow_create?(user) && profile.organization? && (@page.blog? || @page.parent && @page.parent.blog?) && !remove_content_button(:suggest, @page) %> | |
39 | 39 | <% content = content_tag( 'span', _('Suggest an article') ) %> |
40 | 40 | <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'suggest_an_article'}) %> |
41 | 41 | <% options = {:id => 'suggest-article-link'} %> | ... | ... |
app/views/content_viewer/_comment_form.html.erb
... | ... | @@ -7,10 +7,10 @@ function submit_comment_form(button) { |
7 | 7 | return true; |
8 | 8 | <% else %> |
9 | 9 | jQuery('#recaptcha-container').show(); |
10 | - jQuery.colorbox({ inline : true, href : '#recaptcha-container', maxWidth : '600px', maxHeight : '300px' }); | |
10 | + noosfero.modal.inline('#recaptcha-container', {maxWidth :'600px', maxHeight : '300px' }); | |
11 | 11 | jQuery('#confirm-captcha').unbind('click'); |
12 | 12 | jQuery('#confirm-captcha').bind('click', function() { |
13 | - jQuery.colorbox.close(); | |
13 | + noosfero.modal.close(); | |
14 | 14 | button.form.recaptcha_response_field.value = jQuery('#recaptcha_response_field').val(); |
15 | 15 | button.form.recaptcha_challenge_field.value = jQuery('#recaptcha_challenge_field').val(); |
16 | 16 | button.form.confirm.value = 'true'; |
... | ... | @@ -38,7 +38,7 @@ function submit_comment_form(button) { |
38 | 38 | <%= recaptcha_tags(:display => { :theme => 'clean' }, :ajax => true) %> |
39 | 39 | <% button_bar do %> |
40 | 40 | <%= button_to_function :add, _('Confirm'), "return false", :id => "confirm-captcha" %> |
41 | - <%= button_to_function :cancel, _('Cancel'), "jQuery.colorbox.close()" %> | |
41 | + <%= button_to_function :cancel, _('Cancel'), "noosfero.modal.close()" %> | |
42 | 42 | <% end %> |
43 | 43 | </div> |
44 | 44 | ... | ... |
app/views/layouts/_javascript.html.erb
1 | 1 | <%= javascript_include_tag 'jquery-2.1.1.min', 'jquery-migrate-1.2.1', 'jrails', 'rails.js', |
2 | -'jquery.cycle.all.min.js', 'thickbox.js', 'lightbox', 'colorbox', | |
3 | -'jquery-ui-1.10.4/js/jquery-ui-1.10.4.min', 'jquery.scrollTo', 'jquery.form.js', 'jquery-validation/jquery.validate', | |
4 | -'jquery.cookie', 'jquery.ba-bbq.min.js', 'reflection', 'jquery.tokeninput', 'jquery.typewatch', 'jquery.textchange', | |
5 | -'add-and-join', 'report-abuse', 'catalog', 'manage-products', 'autogrow', 'select-or-die/_src/selectordie', | |
6 | -'jquery-timepicker-addon/dist/jquery-ui-timepicker-addon', 'application.js', 'inputosaurus.js', :cache => 'cache/application' %> | |
2 | + 'jquery.cycle.all.min.js', 'jquery.colorbox-min.js', | |
3 | + 'jquery-ui-1.10.4/js/jquery-ui-1.10.4.min', 'jquery.scrollTo', 'jquery.form.js', 'jquery-validation/jquery.validate', | |
4 | + 'jquery.cookie', 'jquery.ba-bbq.min.js', 'reflection', 'jquery.tokeninput', 'jquery.typewatch', 'jquery.textchange', | |
5 | + 'jquery-timepicker-addon/dist/jquery-ui-timepicker-addon', 'inputosaurus.js', 'select-or-die/_src/selectordie', | |
6 | + # noosfero libraries | |
7 | + 'application.js', 'modal.js', | |
8 | + 'add-and-join', 'report-abuse', 'catalog', 'manage-products', 'autogrow', | |
9 | + :cache => 'cache/application' %> | |
7 | 10 | |
8 | 11 | <% language = FastGettext.locale %> |
9 | 12 | <% %w{messages methods}.each do |type| %> | ... | ... |
app/views/layouts/_user.html.erb
... | ... | @@ -7,11 +7,11 @@ |
7 | 7 | </span> |
8 | 8 | <% else %> |
9 | 9 | <span class='not-logged-in'> |
10 | - <%= _("<span class='login'>%s</span>") % thickbox_inline_popup_link('<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>', login_url, 'inlineLoginBox', :id => 'link_login') %> | |
10 | + <%= _("<span class='login'>%s</span>") % modal_inline_link_to('<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>', login_url, '#inlineLoginBox', :id => 'link_login') %> | |
11 | 11 | <%= @plugins.dispatch(:alternative_authentication_link).collect { |content| instance_exec(&content) }.join("") %> |
12 | 12 | |
13 | 13 | <div id='inlineLoginBox' style='display: none;'> |
14 | - <%= render :file => 'account/login', :locals => { :is_thickbox => true } %> | |
14 | + <%= render :file => 'account/login', :locals => { :is_popin => true } %> | |
15 | 15 | </div> |
16 | 16 | |
17 | 17 | <% unless @plugins.dispatch(:allow_user_registration).include?(false) %> | ... | ... |
app/views/layouts/application-ng.html.erb
... | ... | @@ -18,7 +18,7 @@ |
18 | 18 | <%= yield :head %> |
19 | 19 | <%= |
20 | 20 | @plugins.dispatch(:head_ending).map do |content| |
21 | - if content.respond_to?(:call) then instance_exec(&content).html_safe else content.html_safe end | |
21 | + if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end | |
22 | 22 | end.join("\n") |
23 | 23 | %> |
24 | 24 | |
... | ... | @@ -32,7 +32,7 @@ |
32 | 32 | |
33 | 33 | <%= |
34 | 34 | @plugins.dispatch(:body_beginning).map do |content| |
35 | - if content.respond_to?(:call) then instance_exec(&content).html_safe else content.html_safe end | |
35 | + if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end | |
36 | 36 | end.join("\n") |
37 | 37 | %> |
38 | 38 | ... | ... |
app/views/person_notifier/mailer/_comment.html.erb
... | ... | @@ -19,7 +19,7 @@ |
19 | 19 | <span style="font-size: 12px;"><%= comment.title %></span><br/> |
20 | 20 | <% end %> |
21 | 21 | <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/> |
22 | - <span style="font-size: 8px; color: #444444"><%= time_ago_as_sentence(comment.created_at) %></span> | |
22 | + <span style="font-size: 8px; color: #929292"><%= time_ago_as_sentence(comment.created_at) %></span> | |
23 | 23 | <br style="clear: both;" /> |
24 | 24 | |
25 | 25 | <% unless comment.replies.blank? %> | ... | ... |
app/views/person_notifier/mailer/_create_article.html.erb
1 | -<table> | |
2 | 1 | <tr> |
3 | - <td> | |
2 | + <td style="width: 11%"> | |
4 | 3 | <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> |
5 | 4 | </td> |
6 | 5 | <td> |
7 | - <p style="width:550px"> | |
6 | + <p> | |
8 | 7 | <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span> |
9 | 8 | <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span> |
10 | - <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
9 | + <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
11 | 10 | </p> |
12 | 11 | <p> |
13 | 12 | <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span> |
... | ... | @@ -24,4 +23,3 @@ |
24 | 23 | <%= render :partial => 'profile_comments', :locals => { :activity => activity } %> |
25 | 24 | </td> |
26 | 25 | </tr> |
27 | -</table> | ... | ... |
app/views/person_notifier/mailer/_default_activity.html.erb
1 | -<table> | |
2 | 1 | <tr> |
3 | - <td> | |
2 | + <td style="width: 11%"> | |
4 | 3 | <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> |
5 | 4 | </td> |
6 | 5 | <td> |
7 | - <p style="width:550px"> | |
6 | + <p> | |
8 | 7 | <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> |
9 | - <span style="font-size: 10px; color: #444444; float: right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
8 | + <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
10 | 9 | </p> |
11 | 10 | </td> |
12 | 11 | </tr> |
... | ... | @@ -16,4 +15,3 @@ |
16 | 15 | <%= render :partial => 'profile_comments', :locals => { :activity => activity } %> |
17 | 16 | </td> |
18 | 17 | </tr> |
19 | -</table> | ... | ... |
... | ... | @@ -0,0 +1,20 @@ |
1 | +<div style="border-bottom:1px solid #e2e2e2;padding:15px 0;width:600px"> | |
2 | + <table style="width:100%;"> | |
3 | + <tr> | |
4 | + <td style="width: 11%"> | |
5 | + <%= profile_image(task.requestor, :minor) %> | |
6 | + </td> | |
7 | + <td> | |
8 | + <div> | |
9 | + <strong><%= link_to task.title, url_for(:controller => 'tasks', :profile => @profile.identifier, :action => 'index', :only_path => false) %></strong> | |
10 | + </div> | |
11 | + <div style="font-size: 14px"> | |
12 | + <span style="font-size: 14px"> | |
13 | + <%= task_information(task) %> | |
14 | + </span> | |
15 | + <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_as_sentence(task.created_at) %></span> | |
16 | + </div> | |
17 | + </td> | |
18 | + </tr> | |
19 | + </table> | |
20 | +</div> | ... | ... |
app/views/person_notifier/mailer/_upload_image.html.erb
1 | -<table> | |
2 | 1 | <tr> |
3 | - <td> | |
2 | + <td style="width: 11%"> | |
4 | 3 | <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> |
5 | 4 | </td> |
6 | 5 | <td> |
7 | - <p style="width:550px"> | |
6 | + <p> | |
8 | 7 | <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> |
9 | - <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
8 | + <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
10 | 9 | </p> |
11 | 10 | </td> |
12 | 11 | </tr> |
13 | -</table> | |
14 | 12 | <div title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-newgallery'></div> |
15 | 13 | <br/> | ... | ... |
app/views/person_notifier/mailer/content_summary.html.erb
1 | -<h3><%= _("%s's network activity") % @profile.name %></h3> | |
2 | -<br/> | |
3 | -<div> | |
4 | -<% @notifications.each do |activity| %> | |
5 | - <div style="border-left:none;border-right:none;border-top:1px solid #ccc;border-bottom:none;padding:10px;width:600px"> | |
6 | - <%= render :partial => activity.verb, :locals => { :activity => activity } rescue "cannot render notification for #{activity.verb}" %> | |
7 | - </div> | |
8 | -<% end %> | |
9 | -</div> | |
1 | +<div style="background-color: #EEEEEE"> | |
2 | + <table style="width: 100%;"><tbody><tr><td align="center"> | |
3 | + <div style="display: table; background-color: white; margin: 26px 0;"> | |
4 | + <div style="padding: 25px 20px 20px 20px;text-align: left;"> | |
5 | + <%= link_to @url, :style => "text-decoration: none;" do %> | |
6 | + <span style="font-weight:bold;font-size: 28px;margin: 0;color: white;background-color: #AAAAAA;padding: 5px;"><%= @environment %></span> | |
7 | + <% end %> | |
8 | + <span style="font-weight:bold;color: #333;font-size:19px;margin-left: 8px;"><%= _("%s's Notifications") % @profile.name %></h3> | |
9 | + </div> | |
10 | + <div style="margin: 0 20px 20px 20px;border-top:1px solid #e2e2e2;"> | |
11 | + <% if @tasks.present? %> | |
12 | + <div style="border-top: 1px solid #e2e2e2;"> | |
13 | + <div style="border-bottom: 1px solid #CBCBCB;padding-top: 15px;font-weight: bold;text-align: right;color: #7c7c7c;float: right;min-width: 140px;"> | |
14 | + <%= _('Tasks') %> | |
15 | + </div> | |
16 | + <%= render :partial => 'task', :collection => @tasks %> | |
17 | + </div> | |
18 | + <% end %> | |
19 | + | |
20 | + <% if @notifications.present? %> | |
21 | + <div style="border-top: 1px solid #e2e2e2;"> | |
22 | + <div style="border-bottom: 1px solid #CBCBCB;padding-top: 15px;font-weight: bold;text-align: right;color: #7c7c7c;float: right;min-width: 140px;"> | |
23 | + <%= _('Network Activity') %> | |
24 | + </div> | |
25 | + <% @notifications.each do |activity| %> | |
26 | + <div style="border-bottom:1px solid #e2e2e2;padding:15px 0;width:600px"> | |
27 | + <table style="width:100%;"> | |
28 | + <%= render :partial => activity.verb, :locals => { :activity => activity } rescue "cannot render notification for #{activity.verb}" %> | |
29 | + </table> | |
30 | + </div> | |
31 | + <% end %> | |
32 | + </div> | |
33 | + <% end %> | |
10 | 34 | |
11 | -<div style="color:#444444;font-size:11px;"> | |
12 | -<p><%= _("Greetings,") %></p> | |
13 | -<br/> | |
14 | -<p>--</p> | |
15 | -<p><%= _('%s team.') % @environment %></p> | |
16 | -<p><%= url_for @url %></p> | |
35 | + <div style="color:#444444;font-size:11px;margin-bottom: 20px;"> | |
36 | + <p style="margin:0"><%= _("Greetings,") %></p> | |
37 | + <p style="margin:0"><%= _('%s team.') % @environment %></p> | |
38 | + <p style="margin:0"><%= link_to @url, url_for(@url) %></p> | |
39 | + </div> | |
40 | + </div> | |
41 | + </td></tr></tbody></table> | |
17 | 42 | </div> |
18 | -<br/> | ... | ... |
app/views/profile/join.html.erb
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | <%= hidden_field_tag(:confirmation, 1) %> |
10 | 10 | <%= submit_button(:ok, _("Yes, I want to join.") % profile.name) %> |
11 | 11 | <% if logged_in? && request.xhr? %> |
12 | - <%= lightbox_close_button(_("No, I don't want")) %> | |
12 | + <%= modal_close_button _("No, I don't want") %> | |
13 | 13 | <% else %> |
14 | 14 | <%= button(:cancel, _("No, I don't want."), profile.url) %> |
15 | 15 | <% end %> | ... | ... |
app/views/profile/leave.html.erb
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | <%= hidden_field_tag(:back_to, @back_to) %> |
10 | 10 | <%= submit_button(:ok, _("Yes, I want to leave.") % profile.name) %> |
11 | 11 | <% if logged_in? && request.xhr? %> |
12 | - <%= lightbox_close_button(_("No, I don't want")) %> | |
12 | + <%= modal_close_button _("No, I don't want") %> | |
13 | 13 | <% else %> |
14 | 14 | <%= button(:cancel, _("No, I don't want."), profile.url) %> |
15 | 15 | <% end %> | ... | ... |
app/views/profile/report_abuse.html.erb
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | <% end %> |
10 | 10 | |
11 | 11 | <%= submit_button(:send, _('Report profile'), :style => 'float: left; cursor: pointer;', :id => 'report-abuse-submit-button', :onclick => "jQuery('#form-submit-loading').show()") %> |
12 | - <%= button(:cancel, _('Cancel'), {}, :style => 'float: left; padding-top: 0px; padding-bottom: 0px;', :onclick => 'jQuery.colorbox.close(); return false;')%> | |
12 | + <%= button(:cancel, _('Cancel'), {}, :style => 'float: left; padding-top: 0px; padding-bottom: 0px;', :onclick => 'noosfero.modal.close(); return false;')%> | |
13 | 13 | <div id="form-submit-loading" class="small-loading" style="width: 16px; height: 16px; margin-top: 3px; float: left; display: none;"></div> |
14 | 14 | <% end %> |
15 | 15 | |
... | ... | @@ -30,7 +30,7 @@ |
30 | 30 | success: function(data, status, ajax){ |
31 | 31 | if ( !data.ok ) display_notice(data.error.message); |
32 | 32 | else { |
33 | - $.colorbox.close(); | |
33 | + noosfero.modal.close(); | |
34 | 34 | display_notice(data.message); |
35 | 35 | window.location.reload(); |
36 | 36 | } | ... | ... |
app/views/profile_themes/add_css.html.erb
app/views/profile_themes/edit.html.erb
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | <% end %> |
17 | 17 | </ul> |
18 | 18 | <% button_bar do %> |
19 | - <%= lightbox_button(:add, _('New CSS'), :action => 'add_css', :id => @theme.id) %> | |
19 | + <%= modal_button :add, _('New CSS'), :action => 'add_css', :id => @theme.id %> | |
20 | 20 | <% end %> |
21 | 21 | </div> |
22 | 22 | |
... | ... | @@ -25,10 +25,10 @@ |
25 | 25 | <ul> |
26 | 26 | <% for image in @image_files %> |
27 | 27 | <li><%= image_tag("/user_themes/#{@theme.id}/images/#{image}") %></li> |
28 | - <% end %> | |
28 | + <% end %> | |
29 | 29 | </ul> |
30 | 30 | <% button_bar do %> |
31 | - <%= lightbox_button(:add, _('Add image'), :action => 'add_image', :id => @theme.id) %> | |
31 | + <%= modal_button :add, _('Add image'), :action => 'add_image', :id => @theme.id %> | |
32 | 32 | <% end %> |
33 | 33 | </div> |
34 | 34 | ... | ... |
app/views/profile_themes/index.html.erb
... | ... | @@ -42,7 +42,7 @@ |
42 | 42 | |
43 | 43 | <% button_bar do %> |
44 | 44 | <% if environment.enabled?('user_themes') %> |
45 | - <%= lightbox_button(:add, _('New theme ...'), :action => 'new') %> | |
45 | + <%= modal_button :add, _('New theme ...'), :action => 'new' %> | |
46 | 46 | <% end %> |
47 | 47 | <%= button(:back, _('Back'), :controller => 'profile_editor', :action => 'index') %> |
48 | 48 | <% end %> | ... | ... |
app/views/shared/user_menu.html.erb
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | </li> |
21 | 21 | |
22 | 22 | <li> |
23 | - <%= lightbox_link_to('<span class="icon-new"></span>' + _('New article'), '/myprofile/{login}/cms/new') %> | |
23 | + <%= modal_link_to '<span class="icon-new"></span>' + _('New article'), '/myprofile/{login}/cms/new' %> | |
24 | 24 | </li> |
25 | 25 | |
26 | 26 | <li id='manage-enterprises-link-template' style='display: none'><a href='/myprofile/{identifier}'><span class="icon-menu-enterprise"></span><%= _('Manage %s') % '{name}' %></a></li> |
... | ... | @@ -58,9 +58,9 @@ |
58 | 58 | <% if theme_option( :menu_login ) == 'full_form' %> |
59 | 59 | <%= render :file => 'account/login_block' %> |
60 | 60 | <% else %> |
61 | - <%= thickbox_inline_popup_link('<span class="icon-menu-login"></span>'+ _('Login'), login_url, 'inlineLoginBox', :id => 'link_login') %> | |
61 | + <%= modal_inline_link_to('<span class="icon-menu-login"></span>'+ _('Login'), login_url, '#inlineLoginBox', :id => 'link_login') %> | |
62 | 62 | <div id='inlineLoginBox' style='display: none;'> |
63 | - <%= render :file => 'account/login', :locals => { :is_thickbox => true } %> | |
63 | + <%= render :file => 'account/login', :locals => { :is_popin => true } %> | |
64 | 64 | </div> |
65 | 65 | <% end %> |
66 | 66 | <% end %> | ... | ... |
config/database.yml.multitenancy
1 | 1 | # Refer to INSTALL.multitenancy for more information on Multitenancy support |
2 | -env1_production: | |
2 | +env1_production: &DEFAULT | |
3 | 3 | adapter: postgresql |
4 | 4 | encoding: unicode |
5 | 5 | database: noosfero |
... | ... | @@ -30,4 +30,4 @@ env3_production: |
30 | 30 | - env3.net |
31 | 31 | |
32 | 32 | production: |
33 | - env1_production | |
33 | + <<: *DEFAULT | ... | ... |
config/noosfero.yml.dist
config/schedule.rb
db/schema.rb
... | ... | @@ -733,6 +733,7 @@ ActiveRecord::Schema.define(:version => 20150122165042) do |
733 | 733 | t.string "activation_code", :limit => 40 |
734 | 734 | t.datetime "activated_at" |
735 | 735 | t.string "return_to" |
736 | + t.datetime "last_login_at" | |
736 | 737 | end |
737 | 738 | |
738 | 739 | create_table "validation_infos", :force => true do |t| | ... | ... |
debian/control
lib/authenticated_system.rb
... | ... | @@ -5,22 +5,23 @@ module AuthenticatedSystem |
5 | 5 | def logged_in? |
6 | 6 | current_user != nil |
7 | 7 | end |
8 | - | |
8 | + | |
9 | 9 | # Accesses the current user from the session. |
10 | 10 | def current_user |
11 | 11 | @current_user ||= (session[:user] && User.find_by_id(session[:user])) || nil |
12 | 12 | end |
13 | - | |
13 | + | |
14 | 14 | # Store the given user in the session. |
15 | 15 | def current_user=(new_user) |
16 | 16 | if new_user.nil? |
17 | 17 | session.delete(:user) |
18 | 18 | else |
19 | 19 | session[:user] = new_user.id |
20 | + new_user.register_login | |
20 | 21 | end |
21 | 22 | @current_user = new_user |
22 | 23 | end |
23 | - | |
24 | + | |
24 | 25 | # Check if the user is authorized. |
25 | 26 | # |
26 | 27 | # Override this method in your controllers if you want to restrict access |
... | ... | @@ -62,7 +63,7 @@ module AuthenticatedSystem |
62 | 63 | access_denied |
63 | 64 | end |
64 | 65 | end |
65 | - | |
66 | + | |
66 | 67 | # Redirect as appropriate when an access request fails. |
67 | 68 | # |
68 | 69 | # The default action is to redirect to the login screen. |
... | ... | @@ -88,15 +89,15 @@ module AuthenticatedSystem |
88 | 89 | end |
89 | 90 | end |
90 | 91 | false |
91 | - end | |
92 | - | |
92 | + end | |
93 | + | |
93 | 94 | # Store the URI of the current request in the session. |
94 | 95 | # |
95 | 96 | # We can return to this location by calling #redirect_back_or_default. |
96 | 97 | def store_location(location = request.url) |
97 | 98 | session[:return_to] = location |
98 | 99 | end |
99 | - | |
100 | + | |
100 | 101 | # Redirect to the URI stored by the most recent store_location call or |
101 | 102 | # to the passed default. |
102 | 103 | def redirect_back_or_default(default) |
... | ... | @@ -106,7 +107,7 @@ module AuthenticatedSystem |
106 | 107 | redirect_to(default) |
107 | 108 | end |
108 | 109 | end |
109 | - | |
110 | + | |
110 | 111 | # Inclusion hook to make #current_user and #logged_in? |
111 | 112 | # available as ActionView helper methods. |
112 | 113 | def self.included(base) |
... | ... | @@ -132,6 +133,6 @@ module AuthenticatedSystem |
132 | 133 | def get_auth_data |
133 | 134 | auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) } |
134 | 135 | auth_data = request.env[auth_key].to_s.split unless auth_key.blank? |
135 | - return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil] | |
136 | + return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil] | |
136 | 137 | end |
137 | 138 | end | ... | ... |
lib/noosfero/plugin.rb
... | ... | @@ -24,11 +24,17 @@ class Noosfero::Plugin |
24 | 24 | |
25 | 25 | def initialize! |
26 | 26 | return if !should_load |
27 | - available_plugins.each do |plugin_dir| | |
27 | + | |
28 | + klasses = available_plugins.map do |plugin_dir| | |
28 | 29 | plugin_name = File.basename(plugin_dir) |
29 | - plugin = load_plugin(plugin_name) | |
30 | - load_plugin_extensions(plugin_dir) | |
31 | - load_plugin_filters(plugin) | |
30 | + load_plugin plugin_name | |
31 | + end | |
32 | + available_plugins.each do |plugin_dir| | |
33 | + load_plugin_extensions plugin_dir | |
34 | + end | |
35 | + # filters must be loaded after all extensions | |
36 | + klasses.each do |plugin| | |
37 | + load_plugin_filters plugin | |
32 | 38 | end |
33 | 39 | end |
34 | 40 | |
... | ... | @@ -88,7 +94,7 @@ class Noosfero::Plugin |
88 | 94 | # This is a generic method that initialize any possible filter defined by a |
89 | 95 | # plugin to a specific controller |
90 | 96 | def load_plugin_filters(plugin) |
91 | - Rails.configuration.to_prepare do | |
97 | + ActionDispatch::Reloader.to_prepare do | |
92 | 98 | filters = plugin.new.send 'application_controller_filters' rescue [] |
93 | 99 | Noosfero::Plugin.add_controller_filters ApplicationController, plugin, filters |
94 | 100 | |
... | ... | @@ -116,7 +122,7 @@ class Noosfero::Plugin |
116 | 122 | end |
117 | 123 | |
118 | 124 | def load_plugin_extensions(dir) |
119 | - Rails.configuration.to_prepare do | |
125 | + ActionDispatch::Reloader.to_prepare do | |
120 | 126 | Dir[File.join(dir, 'lib', 'ext', '*.rb')].each {|file| require_dependency file } |
121 | 127 | end |
122 | 128 | end | ... | ... |
lib/noosfero/plugin/macro.rb
... | ... | @@ -35,7 +35,7 @@ class Noosfero::Plugin::Macro |
35 | 35 | def attributes(macro) |
36 | 36 | macro.attributes.to_hash. |
37 | 37 | select {|key, value| key[0..10] == 'data-macro-'}. |
38 | - inject({}){|result, a| result.merge({a[0][11..-1] => a[1]})}. | |
38 | + inject({}){|result, a| result.merge({a[0][11..-1] => a[1].to_s})}. | |
39 | 39 | with_indifferent_access |
40 | 40 | end |
41 | 41 | ... | ... |
lib/noosfero/plugin/routes.rb
1 | 1 | plugins_root = Rails.env.test? ? 'plugins' : '{baseplugins,config/plugins}' |
2 | +prefixes_by_folder = {public: 'plugin', | |
3 | + profile: 'profile/:profile/plugin', | |
4 | + myprofile: 'myprofile/:profile/plugin', | |
5 | + admin: 'admin/plugin'} | |
2 | 6 | |
3 | 7 | Dir.glob(Rails.root.join(plugins_root, '*', 'controllers')) do |controllers_dir| |
4 | - prefixes_by_folder = {'public' => 'plugin', | |
5 | - 'profile' => 'profile/:profile/plugin', | |
6 | - 'myprofile' => 'myprofile/:profile/plugin', | |
7 | - 'admin' => 'admin/plugin'} | |
8 | + plugin_name = File.basename(File.dirname(controllers_dir)) | |
8 | 9 | |
9 | 10 | controllers_by_folder = prefixes_by_folder.keys.inject({}) do |hash, folder| |
10 | - hash.merge!({folder => Dir.glob(File.join(controllers_dir, folder, '*')).map {|full_names| File.basename(full_names).gsub(/_controller.rb$/,'')}}) | |
11 | + path = "#{controllers_dir}/#{folder}/" | |
12 | + hash[folder] = Dir.glob("#{path}{*.rb,#{plugin_name}_plugin/*.rb}").map do |filename| | |
13 | + filename.gsub(path, '').gsub(/_controller.rb$/, '') | |
14 | + end | |
15 | + hash | |
11 | 16 | end |
12 | 17 | |
13 | - plugin_name = File.basename(File.dirname(controllers_dir)) | |
14 | - | |
15 | 18 | controllers_by_folder.each do |folder, controllers| |
16 | 19 | controllers.each do |controller| |
17 | 20 | controller_name = controller.gsub("#{plugin_name}_plugin_",'') | ... | ... |
lib/noosfero/plugin/spammable.rb
lib/tasks/multitenancy.rake
1 | 1 | namespace :multitenancy do |
2 | 2 | |
3 | - task :create do | |
3 | + task :create => :environment do | |
4 | 4 | db_envs = ActiveRecord::Base.configurations.keys.select{ |k| k.match(/_development$|_production$|_test$/) } |
5 | 5 | cd Rails.root.join('config', 'environments'), :verbose => true |
6 | - file_envs = Dir.glob "{*_development.rb,*_prodution.rb,*_test.rb}" | |
6 | + file_envs = Dir.glob "{*_development.rb,*_production.rb,*_test.rb}" | |
7 | 7 | (db_envs.map{ |e| e + '.rb' } - file_envs).each { |env| ln_s env.split('_').last, env } |
8 | 8 | end |
9 | 9 | |
10 | - task :remove do | |
10 | + task :remove => :environment do | |
11 | 11 | db_envs = ActiveRecord::Base.configurations.keys.select{ |k| k.match(/_development$|_production$|_test$/) } |
12 | 12 | cd Rails.root.join('config', 'environments'), :verbose => true |
13 | - file_envs = Dir.glob "{*_development.rb,*_prodution.rb,*_test.rb}" | |
13 | + file_envs = Dir.glob "{*_development.rb,*_production.rb,*_test.rb}" | |
14 | 14 | (file_envs - db_envs.map{ |e| e + '.rb' }).each { |env| safe_unlink env } |
15 | 15 | end |
16 | 16 | ... | ... |
lib/tasks/plugins_tests.rake
... | ... | @@ -106,7 +106,7 @@ def run_test(name, files) |
106 | 106 | files = Array(files) |
107 | 107 | plugin = filename2plugin(files.first) |
108 | 108 | if name == :cucumber || name == :selenium |
109 | - run_cucumber task2_profile(name, plugin), files | |
109 | + run_cucumber task2profile(name, plugin), files | |
110 | 110 | else |
111 | 111 | run_testrb files |
112 | 112 | end |
... | ... | @@ -134,7 +134,11 @@ end |
134 | 134 | |
135 | 135 | def run_tests(name, plugins, run=:all) |
136 | 136 | plugins = Array(plugins) |
137 | - glob = "plugins/{#{plugins.join(',')}}/test/#{task2folder(name)}/**/*.#{task2ext(name)}" | |
137 | + if name == :cucumber || name == :selenium | |
138 | + glob = "plugins/{#{plugins.join(',')}}/#{task2folder(name)}/**/*.#{task2ext(name)}" | |
139 | + else | |
140 | + glob = "plugins/{#{plugins.join(',')}}/test/#{task2folder(name)}/**/*.#{task2ext(name)}" | |
141 | + end | |
138 | 142 | files = Dir.glob(glob) |
139 | 143 | if files.empty? |
140 | 144 | puts "I: no tests to run #{name}" | ... | ... |
plugins/bsc/public/jquery.ui.spinner
... | ... | @@ -1 +0,0 @@ |
1 | -Subproject commit bd879003043b4a93b78cbd4a582b6e0650900bcb |
plugins/comment_classification/features/step_definitions/plugin_steps.rb
1 | 1 | Given /^CommentClassificationPlugin is enabled$/ do |
2 | - step %{I am logged in as admin} | |
3 | - step %{I am on the environment control panel} | |
4 | - step %{I follow "Plugins"} | |
5 | - step %{I check "Comment Classification"} | |
6 | - step %{I press "Save changes"} | |
2 | + steps %Q{ | |
3 | + Given I am logged in as admin | |
4 | + Given I am on the environment control panel | |
5 | + Given I follow "Plugins" | |
6 | + Given I check "Comment Classification" | |
7 | + Given I press "Save changes" | |
8 | + } | |
9 | + | |
7 | 10 | Environment.default.enabled_plugins.should include("CommentClassificationPlugin") |
8 | 11 | end |
9 | 12 | ... | ... |
plugins/comment_classification/lib/ext/comment.rb
plugins/comment_group/lib/ext/article.rb
... | ... | @@ -9,7 +9,7 @@ class Article |
9 | 9 | def not_empty_group_comments_removed |
10 | 10 | if body && body_changed? |
11 | 11 | groups_with_comments = Comment.find(:all, :select => 'distinct group_id', :conditions => {:source_id => self.id}).map(&:group_id).compact |
12 | - groups = Hpricot(body.to_s).search('.macro').collect{|element| element['data-macro-group_id'].to_i} | |
12 | + groups = Nokogiri::HTML.fragment(body.to_s).css('.macro').collect{|element| element['data-macro-group_id'].to_i} | |
13 | 13 | errors[:base] << (N_('Not empty group comment cannot be removed')) unless (groups_with_comments-groups).empty? |
14 | 14 | end |
15 | 15 | end | ... | ... |
plugins/community_track/lib/community_track_plugin/track.rb
... | ... | @@ -59,7 +59,7 @@ class CommunityTrackPlugin::Track < Folder |
59 | 59 | |
60 | 60 | def first_paragraph |
61 | 61 | return '' if body.blank? |
62 | - paragraphs = Hpricot(body).search('p') | |
62 | + paragraphs = Nokogiri::HTML.fragment(body).css('p') | |
63 | 63 | paragraphs.empty? ? '' : paragraphs.first.to_html |
64 | 64 | end |
65 | 65 | ... | ... |
plugins/custom_forms/public/style.css
plugins/custom_forms/views/custom_forms_plugin_myprofile/_edit_select.html.erb
... | ... | @@ -26,7 +26,7 @@ |
26 | 26 | <%= labelled_radio_button 'Multiple Select', "fields[#{counter}][kind]", 'multiple_select', field.multiple && field.list %><br /> |
27 | 27 | |
28 | 28 | <% button_bar do %> |
29 | - <%= button :ok, c_('Ok'), '#', :class => 'colorbox-ok-button', :div_id => elem_id %> | |
29 | + <%= button :ok, _('Ok'), '#', :div_id => elem_id %> | |
30 | 30 | <% end %> |
31 | 31 | </div> |
32 | 32 | ... | ... |
... | ... | @@ -0,0 +1,72 @@ |
1 | +README - Oauth Client Plugin | |
2 | +================================ | |
3 | + | |
4 | +OauthClient is a plugin which allow users to login/signup to noosfero with some oauth providers (for now, google, facebook and noosfero itself). | |
5 | + | |
6 | +Install | |
7 | +======= | |
8 | + | |
9 | +Enable Plugin | |
10 | +------------- | |
11 | + | |
12 | +cd <your_noosfero_dir> | |
13 | +./script/noosfero-plugins enable oauth_client | |
14 | + | |
15 | +Active Plugin | |
16 | +------------- | |
17 | + | |
18 | +As a Noosfero administrator user, go to administrator panel: | |
19 | + | |
20 | +- Click on "Enable/disable plugins" option | |
21 | +- Click on "Oauth Client Plugin" check-box | |
22 | + | |
23 | +Provider Settings | |
24 | +================= | |
25 | + | |
26 | +Goggle | |
27 | +------ | |
28 | + | |
29 | +[Create Google+ application](https://developers.google.com/+/web/signin/javascript-flow) | |
30 | + | |
31 | ||
32 | +-------- | |
33 | + | |
34 | +[Create Facebook application](https://developers.facebook.com/docs/facebook-login/v2.1) | |
35 | + | |
36 | +Varnish Settings | |
37 | +================ | |
38 | +If varnish has been used in your stack, you've to bypass the cache for signup page and prevent cookies to be removed when calling the oauth_client plugin callback. E.g.: | |
39 | + | |
40 | +``` | |
41 | +if (req.url !~ "^/account/*" && req.url !~ "^/plugin/oauth_provider/*" && req.url !~ "^/plugin/oauth_client/*" && req.http.cookie !~ "_noosfero_.*") { | |
42 | + unset req.http.cookie; | |
43 | + return(lookup); | |
44 | +} | |
45 | +``` | |
46 | + | |
47 | +Using Oauth Provider Plugin | |
48 | +=========================== | |
49 | +The oauth_provider plugin may be used as a provider in the same noosfero installation that hosts your oauth_client plugin (this is usefull in a multi environment setup). | |
50 | + | |
51 | +However, you've to use a distinct set of thin processes to handle the authorization requests (to avoid deadlock). | |
52 | + | |
53 | +Apache settings example: | |
54 | +``` | |
55 | +RewriteRule ^/oauth_provider/oauth/(authorize|token).*$ balancer://noosfero-oauth-provider%{REQUEST_URI} [P,QSA,L] | |
56 | +``` | |
57 | + | |
58 | + | |
59 | +Development | |
60 | +=========== | |
61 | + | |
62 | +Running OauthClient tests | |
63 | +-------------------- | |
64 | + | |
65 | +$ rake test:noosfero_plugins:oauth_client | |
66 | + | |
67 | +License | |
68 | +======= | |
69 | + | |
70 | +Copyright (c) The Author developers. | |
71 | + | |
72 | +See Noosfero license. | ... | ... |
plugins/oauth_client/controllers/oauth_client_plugin_admin_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,27 @@ |
1 | +class OauthClientPluginAdminController < AdminController | |
2 | + | |
3 | + def index | |
4 | + end | |
5 | + | |
6 | + def new | |
7 | + @provider = environment.oauth_providers.new | |
8 | + render :file => 'oauth_client_plugin_admin/edit' | |
9 | + end | |
10 | + | |
11 | + def remove | |
12 | + environment.oauth_providers.find(params[:id]).destroy | |
13 | + redirect_to :action => 'index' | |
14 | + end | |
15 | + | |
16 | + def edit | |
17 | + @provider = params[:id] ? environment.oauth_providers.find(params[:id]) : environment.oauth_providers.new | |
18 | + if request.post? | |
19 | + if @provider.update_attributes(params['oauth_client_plugin_provider']) | |
20 | + session[:notice] = _('Saved!') | |
21 | + else | |
22 | + session[:notice] = _('Error!') | |
23 | + end | |
24 | + end | |
25 | + end | |
26 | + | |
27 | +end | ... | ... |
plugins/oauth_client/controllers/public/oauth_client_plugin_public_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,46 @@ |
1 | +class OauthClientPluginPublicController < PublicController | |
2 | + | |
3 | + skip_before_filter :login_required | |
4 | + | |
5 | + def callback | |
6 | + auth = request.env["omniauth.auth"] | |
7 | + user = environment.users.find_by_email(auth.info.email) | |
8 | + user ? login(user) : signup(auth) | |
9 | + end | |
10 | + | |
11 | + def failure | |
12 | + session[:notice] = _('Failed to login') | |
13 | + redirect_to root_url | |
14 | + end | |
15 | + | |
16 | + def destroy | |
17 | + session[:user] = nil | |
18 | + redirect_to root_url | |
19 | + end | |
20 | + | |
21 | + protected | |
22 | + | |
23 | + def login(user) | |
24 | + provider = OauthClientPlugin::Provider.find(session[:provider_id]) | |
25 | + user_provider = user.oauth_user_providers.find_by_provider_id(provider.id) | |
26 | + unless user_provider | |
27 | + user_provider = user.oauth_user_providers.create(:user => user, :provider => provider, :enabled => true) | |
28 | + end | |
29 | + if user_provider.enabled? && provider.enabled? | |
30 | + session[:user] = user.id | |
31 | + else | |
32 | + session[:notice] = _("Can't login with #{provider.name}") | |
33 | + end | |
34 | + | |
35 | + redirect_to :controller => :account, :action => :login | |
36 | + end | |
37 | + | |
38 | + def signup(auth) | |
39 | + login = auth.info.email.split('@').first | |
40 | + session[:oauth_data] = auth | |
41 | + name = auth.info.name | |
42 | + name ||= auth.extra && auth.extra.raw_info ? auth.extra.raw_info.name : '' | |
43 | + redirect_to :controller => :account, :action => :signup, :user => {:login => login, :email => auth.info.email}, :profile_data => {:name => name} | |
44 | + end | |
45 | + | |
46 | +end | ... | ... |
plugins/oauth_client/db/migrate/20141010135314_create_oauth_client_plugin_provider.rb
0 → 100644
... | ... | @@ -0,0 +1,19 @@ |
1 | +class CreateOauthClientPluginProvider < ActiveRecord::Migration | |
2 | + | |
3 | + def self.up | |
4 | + create_table :oauth_client_plugin_providers do |t| | |
5 | + t.integer :environment_id | |
6 | + t.string :strategy | |
7 | + t.string :name | |
8 | + t.text :options | |
9 | + t.boolean :enabled | |
10 | + t.integer :image_id | |
11 | + | |
12 | + t.timestamps | |
13 | + end | |
14 | + end | |
15 | + | |
16 | + def self.down | |
17 | + drop_table :oauth_client_plugin_providers | |
18 | + end | |
19 | +end | ... | ... |
plugins/oauth_client/db/migrate/20141014162710_create_oauth_client_user_providers.rb
0 → 100644
... | ... | @@ -0,0 +1,14 @@ |
1 | +class CreateOauthClientUserProviders < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + create_table :oauth_client_plugin_user_providers do |t| | |
4 | + t.references :user | |
5 | + t.references :provider | |
6 | + t.boolean :enabled | |
7 | + t.timestamps | |
8 | + end | |
9 | + end | |
10 | + | |
11 | + def self.down | |
12 | + drop_table :oauth_client_plugin_user_providers | |
13 | + end | |
14 | +end | ... | ... |
... | ... | @@ -0,0 +1,31 @@ |
1 | +require_dependency 'user' | |
2 | + | |
3 | +class User | |
4 | + | |
5 | + has_many :oauth_user_providers, :class_name => 'OauthClientPlugin::UserProvider' | |
6 | + has_many :oauth_providers, :through => :oauth_user_providers, :source => :provider | |
7 | + | |
8 | + def password_required_with_oauth? | |
9 | + password_required_without_oauth? && oauth_providers.empty? | |
10 | + end | |
11 | + | |
12 | + alias_method_chain :password_required?, :oauth | |
13 | + | |
14 | + after_create :activate_oauth_user | |
15 | + | |
16 | + def activate_oauth_user | |
17 | + unless oauth_providers.empty? | |
18 | + activate | |
19 | + oauth_providers.each do |provider| | |
20 | + OauthClientPlugin::UserProvider.create!(:user => self, :provider => provider, :enabled => true) | |
21 | + end | |
22 | + end | |
23 | + end | |
24 | + | |
25 | + def make_activation_code_with_oauth | |
26 | + oauth_providers.blank? ? make_activation_code_without_oauth : nil | |
27 | + end | |
28 | + | |
29 | + alias_method_chain :make_activation_code, :oauth | |
30 | + | |
31 | +end | ... | ... |
... | ... | @@ -0,0 +1,95 @@ |
1 | +require 'omniauth/strategies/noosfero_oauth2' | |
2 | + | |
3 | +class OauthClientPlugin < Noosfero::Plugin | |
4 | + | |
5 | + def self.plugin_name | |
6 | + "Oauth Client Plugin" | |
7 | + end | |
8 | + | |
9 | + def self.plugin_description | |
10 | + _("Login with Oauth.") | |
11 | + end | |
12 | + | |
13 | + def login_extra_contents | |
14 | + plugin = self | |
15 | + proc do | |
16 | + render :partial => 'auth/oauth_login', :locals => {:providers => environment.oauth_providers.enabled} | |
17 | + end | |
18 | + end | |
19 | + | |
20 | + def signup_extra_contents | |
21 | + plugin = self | |
22 | + | |
23 | + proc do | |
24 | + if plugin.context.session[:oauth_data].present? | |
25 | + render :partial => 'account/oauth_signup' | |
26 | + else | |
27 | + '' | |
28 | + end | |
29 | + end | |
30 | + end | |
31 | + | |
32 | + PROVIDERS = { | |
33 | + :facebook => { | |
34 | + :name => 'Facebook' | |
35 | + }, | |
36 | + :google_oauth2 => { | |
37 | + :name => 'Google' | |
38 | + }, | |
39 | + :noosfero_oauth2 => { | |
40 | + :name => 'Noosfero' | |
41 | + } | |
42 | + } | |
43 | + | |
44 | + def stylesheet? | |
45 | + true | |
46 | + end | |
47 | + | |
48 | + OmniAuth.config.on_failure = OauthClientPluginPublicController.action(:failure) | |
49 | + | |
50 | + Rails.application.config.middleware.use OmniAuth::Builder do | |
51 | + PROVIDERS.each do |provider, options| | |
52 | + setup = lambda { |env| | |
53 | + request = Rack::Request.new(env) | |
54 | + strategy = env['omniauth.strategy'] | |
55 | + | |
56 | + Noosfero::MultiTenancy.setup!(request.host) | |
57 | + domain = Domain.find_by_name(request.host) | |
58 | + environment = domain.environment rescue Environment.default | |
59 | + | |
60 | + provider_id = request.params['id'] | |
61 | + provider_id ||= request.session['omniauth.params']['id'] if request.session['omniauth.params'] | |
62 | + provider = environment.oauth_providers.find(provider_id) | |
63 | + strategy.options.merge!(provider.options.symbolize_keys) | |
64 | + | |
65 | + request.session[:provider_id] = provider_id | |
66 | + } | |
67 | + | |
68 | + provider provider, :setup => setup, | |
69 | + :path_prefix => '/plugin/oauth_client', | |
70 | + :callback_path => "/plugin/oauth_client/public/callback/#{provider}", | |
71 | + :client_options => { :connection_opts => { :proxy => ENV["OAUTH_HTTP_PROXY"] } } | |
72 | + end | |
73 | + | |
74 | + unless Rails.env.production? | |
75 | + provider :developer, :path_prefix => "/plugin/oauth_client", :callback_path => "/plugin/oauth_client/public/callback/developer" | |
76 | + end | |
77 | + end | |
78 | + | |
79 | + def account_controller_filters | |
80 | + { | |
81 | + :type => 'before_filter', :method_name => 'signup', | |
82 | + :block => proc { | |
83 | + auth = session[:oauth_data] | |
84 | + | |
85 | + if auth.present? && params[:user].present? | |
86 | + params[:user][:oauth_providers] = [OauthClientPlugin::Provider.find(session[:provider_id])] | |
87 | + if request.post? && auth.info.email != params[:user][:email] | |
88 | + raise "Wrong email for oauth signup" | |
89 | + end | |
90 | + end | |
91 | + } | |
92 | + } | |
93 | + end | |
94 | + | |
95 | +end | ... | ... |
plugins/oauth_client/lib/oauth_client_plugin/provider.rb
0 → 100644
... | ... | @@ -0,0 +1,20 @@ |
1 | +class OauthClientPlugin::Provider < Noosfero::Plugin::ActiveRecord | |
2 | + | |
3 | + belongs_to :environment | |
4 | + | |
5 | + validates_presence_of :name, :strategy | |
6 | + | |
7 | + acts_as_having_image | |
8 | + acts_as_having_settings :field => :options | |
9 | + | |
10 | + settings_items :client_id, :type => :string | |
11 | + settings_items :client_secret, :type => :string | |
12 | + settings_items :client_options, :type => Hash | |
13 | + | |
14 | + attr_accessible :name, :environment, :strategy, :client_id, :client_secret, :enabled, :client_options, :image_builder | |
15 | + | |
16 | + scope :enabled, :conditions => {:enabled => true} | |
17 | + | |
18 | + acts_as_having_image | |
19 | + | |
20 | +end | ... | ... |
plugins/oauth_client/lib/oauth_client_plugin/user_provider.rb
0 → 100644
... | ... | @@ -0,0 +1,10 @@ |
1 | +class OauthClientPlugin::UserProvider < Noosfero::Plugin::ActiveRecord | |
2 | + | |
3 | + belongs_to :user, :class_name => 'User' | |
4 | + belongs_to :provider, :class_name => 'OauthClientPlugin::Provider' | |
5 | + | |
6 | + set_table_name :oauth_client_plugin_user_providers | |
7 | + | |
8 | + attr_accessible :user, :provider, :enabled | |
9 | + | |
10 | +end | ... | ... |
plugins/oauth_client/lib/omniauth/strategies/noosfero_oauth2.rb
0 → 100644
... | ... | @@ -0,0 +1,26 @@ |
1 | +require 'omniauth/strategies/oauth2' | |
2 | + | |
3 | +module OmniAuth | |
4 | + module Strategies | |
5 | + class NoosferoOauth2 < OmniAuth::Strategies::OAuth2 | |
6 | + option :name, :noosfero_oauth2 | |
7 | + option :client_options, { | |
8 | + :authorize_url => '/oauth_provider/oauth/authorize', | |
9 | + :token_url => '/oauth_provider/oauth/token' | |
10 | + } | |
11 | + | |
12 | + uid { raw_info["id"] } | |
13 | + | |
14 | + info do | |
15 | + { | |
16 | + :email => raw_info["email"] | |
17 | + } | |
18 | + end | |
19 | + | |
20 | + def raw_info | |
21 | + #FIXME access the noosfero api (coming soon) | |
22 | + @raw_info ||= access_token.get('/plugin/oauth_provider/public/me').parsed | |
23 | + end | |
24 | + end | |
25 | + end | |
26 | +end | ... | ... |
... | ... | @@ -0,0 +1,18 @@ |
1 | +.oauth-login .provider a { | |
2 | + min-width: 20px; | |
3 | + min-height: 20px; | |
4 | + background-size: 20px; | |
5 | + display: inline-block; | |
6 | + text-decoration: none; | |
7 | + background-repeat: no-repeat; | |
8 | + line-height: 20px; | |
9 | +} | |
10 | +.oauth-login .provider a img { | |
11 | + max-width: 40px; | |
12 | +} | |
13 | +.oauth-login .provider a:hover { | |
14 | + opacity: 0.7; | |
15 | +} | |
16 | +.oauth-login .provider .developer { | |
17 | + display: none; | |
18 | +} | ... | ... |
plugins/oauth_client/test/functional/oauth_client_plugin_public_controller_test.rb
0 → 100644
... | ... | @@ -0,0 +1,80 @@ |
1 | +require File.dirname(__FILE__) + '/../test_helper' | |
2 | + | |
3 | +class OauthClientPluginPublicControllerTest < ActionController::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @auth = mock | |
7 | + @auth.stubs(:info).returns(mock) | |
8 | + request.env["omniauth.auth"] = @auth | |
9 | + @environment = Environment.default | |
10 | + @provider = OauthClientPlugin::Provider.create!(:name => 'provider', :strategy => 'provider', :enabled => true) | |
11 | + end | |
12 | + attr_reader :auth, :environment, :provider | |
13 | + | |
14 | + should 'redirect to signup when user is not found' do | |
15 | + auth.info.stubs(:email).returns("xyz123@noosfero.org") | |
16 | + auth.info.stubs(:name).returns('xyz123') | |
17 | + session[:provider_id] = provider.id | |
18 | + | |
19 | + get :callback | |
20 | + assert_match /.*\/account\/signup/, @response.redirect_url | |
21 | + end | |
22 | + | |
23 | + should 'redirect to login when user is found' do | |
24 | + user = fast_create(User, :environment_id => environment.id) | |
25 | + auth.info.stubs(:email).returns(user.email) | |
26 | + auth.info.stubs(:name).returns(user.name) | |
27 | + session[:provider_id] = provider.id | |
28 | + | |
29 | + get :callback | |
30 | + assert_redirected_to :controller => :account, :action => :login | |
31 | + assert_equal user.id, session[:user] | |
32 | + end | |
33 | + | |
34 | + should 'do not login when the provider is disabled' do | |
35 | + user = fast_create(User, :environment_id => environment.id) | |
36 | + auth.info.stubs(:email).returns(user.email) | |
37 | + auth.info.stubs(:name).returns(user.name) | |
38 | + session[:provider_id] = provider.id | |
39 | + provider.update_attribute(:enabled, false) | |
40 | + | |
41 | + get :callback | |
42 | + assert_redirected_to :controller => :account, :action => :login | |
43 | + assert_equal nil, session[:user] | |
44 | + end | |
45 | + | |
46 | + should 'do not login when the provider is disabled for a user' do | |
47 | + user = fast_create(User, :environment_id => environment.id) | |
48 | + auth.info.stubs(:email).returns(user.email) | |
49 | + auth.info.stubs(:name).returns(user.name) | |
50 | + session[:provider_id] = provider.id | |
51 | + user.oauth_user_providers.create(:user => user, :provider => provider, :enabled => false) | |
52 | + | |
53 | + get :callback | |
54 | + assert_redirected_to :controller => :account, :action => :login | |
55 | + assert_equal nil, session[:user] | |
56 | + end | |
57 | + | |
58 | + should 'save provider when an user login with it' do | |
59 | + user = fast_create(User, :environment_id => environment.id) | |
60 | + auth.info.stubs(:email).returns(user.email) | |
61 | + auth.info.stubs(:name).returns(user.name) | |
62 | + session[:provider_id] = provider.id | |
63 | + | |
64 | + get :callback | |
65 | + assert_equal [provider], user.oauth_providers | |
66 | + end | |
67 | + | |
68 | + should 'do not duplicate relations between an user and a provider when the same provider was used again in a login' do | |
69 | + user = fast_create(User, :environment_id => environment.id) | |
70 | + auth.info.stubs(:email).returns(user.email) | |
71 | + auth.info.stubs(:name).returns(user.name) | |
72 | + session[:provider_id] = provider.id | |
73 | + | |
74 | + get :callback | |
75 | + assert_no_difference 'user.oauth_user_providers.count' do | |
76 | + 3.times { get :callback } | |
77 | + end | |
78 | + end | |
79 | + | |
80 | +end | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +require File.dirname(__FILE__) + '/../../../test/test_helper' | ... | ... |
... | ... | @@ -0,0 +1,10 @@ |
1 | +require File.dirname(__FILE__) + '/../test_helper' | |
2 | + | |
3 | +class UserTest < ActiveSupport::TestCase | |
4 | + | |
5 | + should 'be able to add oauth providers in a environment' do | |
6 | + env = fast_create(Environment) | |
7 | + env.oauth_providers << OauthClientPlugin::Provider.new(:name => 'test', :strategy => 'test') | |
8 | + end | |
9 | + | |
10 | +end | ... | ... |
plugins/oauth_client/test/unit/oauth_client_plugin_test.rb
0 → 100644
... | ... | @@ -0,0 +1,86 @@ |
1 | +require File.dirname(__FILE__) + '/../test_helper' | |
2 | + | |
3 | +class OauthClientPluginTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @plugin = OauthClientPlugin.new(self) | |
7 | + @params = {} | |
8 | + @plugin.stubs(:context).returns(self) | |
9 | + @environment = Environment.default | |
10 | + @session = {} | |
11 | + @request = mock | |
12 | + @provider = OauthClientPlugin::Provider.create!(:name => 'name', :strategy => 'strategy') | |
13 | + end | |
14 | + | |
15 | + attr_reader :params, :plugin, :environment, :session, :request, :provider | |
16 | + | |
17 | + should 'has extra contents for login' do | |
18 | + assert plugin.login_extra_contents | |
19 | + end | |
20 | + | |
21 | + should 'has no signup extra contents if no provider was enabled' do | |
22 | + assert_equal '', instance_eval(&plugin.signup_extra_contents) | |
23 | + end | |
24 | + | |
25 | + should 'has signup extra contents if oauth_data exists in session' do | |
26 | + session[:oauth_data] = {:oauth => 'test'} | |
27 | + expects(:render).with(:partial => 'account/oauth_signup').once | |
28 | + instance_eval(&plugin.signup_extra_contents) | |
29 | + end | |
30 | + | |
31 | + should 'define before filter for account controller' do | |
32 | + assert plugin.account_controller_filters | |
33 | + end | |
34 | + | |
35 | + should 'raise error if oauth email was changed' do | |
36 | + request.expects(:post?).returns(true) | |
37 | + | |
38 | + oauth_data = mock | |
39 | + info = mock | |
40 | + oauth_data.stubs(:info).returns(info) | |
41 | + oauth_data.stubs(:uid).returns('uid') | |
42 | + oauth_data.stubs(:provider).returns('provider') | |
43 | + info.stubs(:email).returns('test@example.com') | |
44 | + session[:oauth_data] = oauth_data | |
45 | + session[:provider_id] = provider.id | |
46 | + | |
47 | + params[:user] = {:email => 'test2@example.com'} | |
48 | + assert_raises RuntimeError do | |
49 | + instance_eval(&plugin.account_controller_filters[:block]) | |
50 | + end | |
51 | + end | |
52 | + | |
53 | + should 'do not raise error if oauth email was not changed' do | |
54 | + request.expects(:post?).returns(true) | |
55 | + | |
56 | + oauth_data = mock | |
57 | + info = mock | |
58 | + oauth_data.stubs(:info).returns(info) | |
59 | + oauth_data.stubs(:uid).returns('uid') | |
60 | + oauth_data.stubs(:provider).returns('provider') | |
61 | + info.stubs(:email).returns('test@example.com') | |
62 | + session[:oauth_data] = oauth_data | |
63 | + session[:provider_id] = provider.id | |
64 | + | |
65 | + params[:user] = {:email => 'test@example.com'} | |
66 | + instance_eval(&plugin.account_controller_filters[:block]) | |
67 | + end | |
68 | + | |
69 | + should 'do not raise error if oauth session is not set' do | |
70 | + instance_eval(&plugin.account_controller_filters[:block]) | |
71 | + end | |
72 | + | |
73 | + should 'do not raise error if it is not a post' do | |
74 | + request.expects(:post?).returns(false) | |
75 | + params[:user] = {:email => 'test2@example.com'} | |
76 | + | |
77 | + oauth_data = mock | |
78 | + oauth_data.stubs(:uid).returns('uid') | |
79 | + oauth_data.stubs(:provider).returns('provider') | |
80 | + session[:provider_id] = provider.id | |
81 | + | |
82 | + session[:oauth_data] = oauth_data | |
83 | + instance_eval(&plugin.account_controller_filters[:block]) | |
84 | + end | |
85 | + | |
86 | +end | ... | ... |
... | ... | @@ -0,0 +1,40 @@ |
1 | +require File.dirname(__FILE__) + '/../test_helper' | |
2 | + | |
3 | +class UserTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @provider = OauthClientPlugin::Provider.create!(:name => 'name', :strategy => 'strategy') | |
7 | + end | |
8 | + attr_reader :provider | |
9 | + | |
10 | + should 'password is not required if there is a oauth provider' do | |
11 | + User.create!(:email => 'testoauth@example.com', :login => 'testoauth', :oauth_providers => [provider]) | |
12 | + end | |
13 | + | |
14 | + should 'password is required if there is a oauth provider' do | |
15 | + user = User.new(:email => 'testoauth@example.com', :login => 'testoauth') | |
16 | + user.save | |
17 | + assert user.errors[:password].present? | |
18 | + end | |
19 | + | |
20 | + should 'activate user when created with oauth' do | |
21 | + user = User.create!(:email => 'testoauth@example.com', :login => 'testoauth', :oauth_providers => [provider]) | |
22 | + assert user.activated? | |
23 | + end | |
24 | + | |
25 | + should 'not activate user when created without oauth' do | |
26 | + user = fast_create(User) | |
27 | + assert !user.activated? | |
28 | + end | |
29 | + | |
30 | + should 'not make activation code when created with oauth' do | |
31 | + user = User.create!(:email => 'testoauth@example.com', :login => 'testoauth', :oauth_providers => [provider]) | |
32 | + assert !user.activation_code | |
33 | + end | |
34 | + | |
35 | + should 'make activation code when created without oauth' do | |
36 | + user = User.create!(:email => 'testoauth@example.com', :login => 'testoauth', :password => 'test', :password_confirmation => 'test') | |
37 | + assert user.activation_code | |
38 | + end | |
39 | + | |
40 | +end | ... | ... |
plugins/oauth_client/views/account/_oauth_signup.html.erb
0 → 100644
... | ... | @@ -0,0 +1,11 @@ |
1 | +<%= hidden_field_tag 'return_to', '/' %> | |
2 | + | |
3 | +<style> | |
4 | + #signup-password, #signup-password-confirmation, #signup-email { | |
5 | + display: none; | |
6 | + } | |
7 | +</style> | |
8 | + | |
9 | +<div id='signup-email-readonly'> | |
10 | + <%= labelled_form_field(_('Email'), text_field(:user, :email, :class => "disabled", :readonly => true)) %> | |
11 | +</div> | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +<div class="oauth-login"> | |
2 | + <% unless providers.empty? %> | |
3 | + <%= _('Login with:') %> | |
4 | + <% end %> | |
5 | + <% providers.each do |provider| %> | |
6 | + <span class="provider"> | |
7 | + <%= link_to provider.image ? image_tag(provider.image.public_filename) : provider.name, "/plugin/oauth_client/#{provider.strategy}?id=#{provider.id}", :class => provider.strategy, :title => provider.name %> | |
8 | + </span> | |
9 | + <% end %> | |
10 | + | |
11 | + <span class="provider"> | |
12 | + <% unless Rails.env.production? %> | |
13 | + <%= link_to _('Developer Login'), "/plugin/oauth_client/developer", :class => 'developer' %> | |
14 | + <% end %> | |
15 | + </span> | |
16 | +</div> | ... | ... |
plugins/oauth_client/views/oauth_client_plugin_admin/_noosfero_oauth2.html.erb
0 → 100644
plugins/oauth_client/views/oauth_client_plugin_admin/edit.html.erb
0 → 100644
... | ... | @@ -0,0 +1,39 @@ |
1 | +<h1><%= _('Oauth Client Settings') %></h1> | |
2 | +<h3><%= _('Edit Provider') %></h3> | |
3 | + | |
4 | +<%= form_for @provider, :url => {:action => 'edit'}, :method => 'post' do |f| %> | |
5 | + | |
6 | + <div class="enabled"> | |
7 | + <%= labelled_form_field f.check_box(:enabled) + _('Enabled'), '' %> | |
8 | + </div> | |
9 | + | |
10 | + <div class="name"> | |
11 | + <%= labelled_form_field _('Name'), f.text_field(:name) %> | |
12 | + </div> | |
13 | + | |
14 | + <div class="strategy"> | |
15 | + <%= labelled_form_field _('Strategy'), f.select(:strategy, OauthClientPlugin::PROVIDERS) %> | |
16 | + </div> | |
17 | + | |
18 | + <div class="client-id"> | |
19 | + <%= labelled_form_field _('Client Id'), f.text_field(:client_id) %> | |
20 | + </div> | |
21 | + | |
22 | + <div class="client-secret"> | |
23 | + <%= labelled_form_field _('Client Secret'), f.text_field(:client_secret) %> | |
24 | + </div> | |
25 | + | |
26 | + <% if File.exists?(File.join(File.dirname(__FILE__), "_#{@provider.strategy}.html.erb")) %> | |
27 | + <%= render :partial => "#{@provider.strategy}", :locals => {:f => f, :provider => @provider} %> | |
28 | + <% end %> | |
29 | + | |
30 | + <div class="image-icon"> | |
31 | + <%= f.fields_for :image_builder, @provider.image do |i| %> | |
32 | + <%= file_field_or_thumbnail(_('Image:'), @provider.image, i) %><%= _("Max size: %s (.jpg, .gif, .png)")% Image.max_size.to_humanreadable %> | |
33 | + <% end %> | |
34 | + </div> | |
35 | + | |
36 | + <% button_bar do %> | |
37 | + <%= submit_button(:save, _('Save'), :cancel => {:action => 'index'}) %> | |
38 | + <% end %> | |
39 | +<% end %> | ... | ... |
plugins/oauth_client/views/oauth_client_plugin_admin/index.html.erb
0 → 100644
... | ... | @@ -0,0 +1,24 @@ |
1 | +<h1><%= _('Oauth Client Settings') %></h1> | |
2 | +<h3><%= _('Providers') %></h3> | |
3 | +<%= button :add, _('New'), {:action => 'new'} %> | |
4 | +<table> | |
5 | + <tr> | |
6 | + <th><%= _('Name') %></th> | |
7 | + <th><%= _('Strategy') %></th> | |
8 | + <th><%= _('Actions') %></th> | |
9 | + </tr> | |
10 | + | |
11 | + <% environment.oauth_providers.each do |provider| %> | |
12 | + <tr> | |
13 | + <td><%= provider.name %></td> | |
14 | + <td><%= provider.strategy %></td> | |
15 | + <td> | |
16 | + <%= link_to _('Edit'), {:action => 'edit', :id => provider.id} %> | |
17 | + <%= link_to _('Remove'), {:action => 'remove', :id => provider.id} %> | |
18 | + </td> | |
19 | + </tr> | |
20 | + <% end %> | |
21 | +</table> | |
22 | +<div class="actions"> | |
23 | + <%= button(:back, _('Go back'), {:controller => 'plugins', :action => 'index'}) %> | |
24 | +</div> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +gem 'doorkeeper', '~> 1.4.0' | ... | ... |
... | ... | @@ -0,0 +1,47 @@ |
1 | +README - Oauth Provider Plugin | |
2 | +================================ | |
3 | + | |
4 | +OauthProvider is a plugin which allow noosfero to be used as an oauth provider | |
5 | + | |
6 | +Install | |
7 | +======= | |
8 | + | |
9 | +Enable Plugin | |
10 | +------------- | |
11 | + | |
12 | +cd <your_noosfero_dir> | |
13 | +./script/noosfero-plugins enable oauth_provider | |
14 | + | |
15 | +Active Plugin | |
16 | +------------- | |
17 | + | |
18 | +As a Noosfero administrator user, go to administrator panel: | |
19 | + | |
20 | +- Click on "Enable/disable plugins" option | |
21 | +- Click on "Oauth Provider Plugin" check-box | |
22 | + | |
23 | +Varnish Settings | |
24 | +================ | |
25 | +If varnish has been used in your stack, you've to prevent cookies to be removed when calling authorization actions for oauth_provider. E.g.: | |
26 | + | |
27 | +``` | |
28 | +if (req.url !~ "^/plugin/oauth_provider/*" && req.http.cookie !~ "_noosfero_.*") { | |
29 | + unset req.http.cookie; | |
30 | + return(lookup); | |
31 | +} | |
32 | +``` | |
33 | + | |
34 | +Development | |
35 | +=========== | |
36 | + | |
37 | +Running OauthProvider tests | |
38 | +-------------------- | |
39 | + | |
40 | +$ rake test:noosfero_plugins:oauth_provider | |
41 | + | |
42 | +License | |
43 | +======= | |
44 | + | |
45 | +Copyright (c) The Author developers. | |
46 | + | |
47 | +See Noosfero license. | ... | ... |
plugins/oauth_provider/controllers/doorkeeper/application_controller.rb
0 → 100644
plugins/oauth_provider/controllers/oauth_provider_applications_controller.rb
0 → 100644
plugins/oauth_provider/controllers/oauth_provider_authorizations_controller.rb
0 → 100644
plugins/oauth_provider/controllers/oauth_provider_authorized_applications_controller.rb
0 → 100644
plugins/oauth_provider/controllers/oauth_provider_plugin_admin_controller.rb
0 → 100644
plugins/oauth_provider/controllers/public/oauth_provider_plugin_public_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,10 @@ |
1 | +class OauthProviderPluginPublicController < PublicController | |
2 | + | |
3 | + doorkeeper_for :me | |
4 | + | |
5 | + def me | |
6 | + user = environment.users.find(doorkeeper_token.resource_owner_id) if doorkeeper_token | |
7 | + render :json => {:id =>user.login, :email => user.email}.to_json | |
8 | + end | |
9 | + | |
10 | +end | ... | ... |
plugins/oauth_provider/db/migrate/20140829153047_create_doorkeeper_tables.rb
0 → 100644
... | ... | @@ -0,0 +1,41 @@ |
1 | +class CreateDoorkeeperTables < ActiveRecord::Migration | |
2 | + def change | |
3 | + create_table :oauth_applications do |t| | |
4 | + t.string :name, null: false | |
5 | + t.string :uid, null: false | |
6 | + t.string :secret, null: false | |
7 | + t.text :redirect_uri, null: false | |
8 | + t.timestamps | |
9 | + end | |
10 | + | |
11 | + add_index :oauth_applications, :uid, unique: true | |
12 | + | |
13 | + create_table :oauth_access_grants do |t| | |
14 | + t.integer :resource_owner_id, null: false | |
15 | + t.integer :application_id, null: false | |
16 | + t.string :token, null: false | |
17 | + t.integer :expires_in, null: false | |
18 | + t.text :redirect_uri, null: false | |
19 | + t.datetime :created_at, null: false | |
20 | + t.datetime :revoked_at | |
21 | + t.string :scopes | |
22 | + end | |
23 | + | |
24 | + add_index :oauth_access_grants, :token, unique: true | |
25 | + | |
26 | + create_table :oauth_access_tokens do |t| | |
27 | + t.integer :resource_owner_id | |
28 | + t.integer :application_id | |
29 | + t.string :token, null: false | |
30 | + t.string :refresh_token | |
31 | + t.integer :expires_in | |
32 | + t.datetime :revoked_at | |
33 | + t.datetime :created_at, null: false | |
34 | + t.string :scopes | |
35 | + end | |
36 | + | |
37 | + add_index :oauth_access_tokens, :token, unique: true | |
38 | + add_index :oauth_access_tokens, :resource_owner_id | |
39 | + add_index :oauth_access_tokens, :refresh_token, unique: true | |
40 | + end | |
41 | +end | ... | ... |
... | ... | @@ -0,0 +1,55 @@ |
1 | +class OauthProviderPlugin < Noosfero::Plugin | |
2 | + | |
3 | + def self.plugin_name | |
4 | + "Oauth Provider Plugin" | |
5 | + end | |
6 | + | |
7 | + def self.plugin_description | |
8 | + _("Oauth Provider.") | |
9 | + end | |
10 | + | |
11 | + def stylesheet? | |
12 | + true | |
13 | + end | |
14 | + | |
15 | + Doorkeeper.configure do | |
16 | + orm :active_record | |
17 | + | |
18 | + resource_owner_authenticator do | |
19 | + domain = Domain.find_by_name(request.host) | |
20 | + environment = domain ? domain.environment : Environment.default | |
21 | + environment.users.find_by_id(session[:user]) || redirect_to('/account/login') | |
22 | + end | |
23 | + | |
24 | + admin_authenticator do | |
25 | + domain = Domain.find_by_name(request.host) | |
26 | + environment = domain ? domain.environment : Environment.default | |
27 | + user = environment.users.find_by_id(session[:user]) | |
28 | + unless user && user.person.is_admin?(environment) | |
29 | + redirect_to('/account/login') | |
30 | + end | |
31 | + user | |
32 | + end | |
33 | + | |
34 | + default_scopes :public | |
35 | + end | |
36 | + | |
37 | + Rails.configuration.to_prepare do | |
38 | + Rails.application.routes.prepend do | |
39 | + scope 'oauth_provider' do | |
40 | + use_doorkeeper do | |
41 | + controllers ({ | |
42 | + :applications => 'oauth_provider_applications', | |
43 | + :authorized_applications => 'oauth_provider_authorized_applications', | |
44 | + :authorizations => 'oauth_provider_authorizations' | |
45 | + }) | |
46 | + end | |
47 | + end | |
48 | + end | |
49 | + end | |
50 | + | |
51 | + SCOPE_TRANSLATION = { | |
52 | + 'public' => _('Access your public data') | |
53 | + } | |
54 | + | |
55 | +end | ... | ... |
... | ... | @@ -0,0 +1,13 @@ |
1 | +.oauth-provider-authorize .actions form { | |
2 | + display: inline-block; | |
3 | +} | |
4 | +.oauth-provider-authorize .h4 { | |
5 | + font-size: 14px; | |
6 | + color: rgb(36, 36, 36) | |
7 | +} | |
8 | +.oauth-provider-authorize #oauth-permissions { | |
9 | + color: rgb(92, 92, 92); | |
10 | +} | |
11 | +.oauth-provider .actions { | |
12 | + margin-top: 10px; | |
13 | +} | ... | ... |
plugins/oauth_provider/views/doorkeeper/applications/_delete_form.html.erb
0 → 100644
plugins/oauth_provider/views/doorkeeper/applications/_form.html.erb
0 → 100644
... | ... | @@ -0,0 +1,39 @@ |
1 | +<%= form_for [:oauth, application], html: {class: 'form-horizontal', role: 'form'} do |f| %> | |
2 | + <% if application.errors.any? %> | |
3 | + <div class="alert alert-danger" data-alert> | |
4 | + <p><%= _('Whoops! Check your form for possible errors') %></p> | |
5 | + </div> | |
6 | + <% end %> | |
7 | + | |
8 | + <%= content_tag :div, class: "form-group#{' has-error' if application.errors[:name].present?}" do %> | |
9 | + <%= f.label :name, class: 'col-sm-2 control-label', for: 'application_name' %> | |
10 | + <div class="col-sm-10"> | |
11 | + <%= f.text_field :name, class: 'form-control' %> | |
12 | + <%= doorkeeper_errors_for application, :name %> | |
13 | + </div> | |
14 | + <% end %> | |
15 | + | |
16 | + <%= content_tag :div, class: "form-group#{' has-error' if application.errors[:redirect_uri].present?}" do %> | |
17 | + <%= f.label :redirect_uri, class: 'col-sm-2 control-label', for: 'application_redirect_uri' %> | |
18 | + <div class="col-sm-10"> | |
19 | + <%= f.text_area :redirect_uri, class: 'form-control' %> | |
20 | + <%= doorkeeper_errors_for application, :redirect_uri %> | |
21 | + <span class="help-block"> | |
22 | + <%= _('Use one line per URI') %> | |
23 | + </span> | |
24 | + <% if Doorkeeper.configuration.native_redirect_uri %> | |
25 | + <span class="help-block"> | |
26 | + Use <code><%= Doorkeeper.configuration.native_redirect_uri %></code> for local tests | |
27 | + </span> | |
28 | + <% end %> | |
29 | + </div> | |
30 | + <% end %> | |
31 | + | |
32 | + <div class="form-group"> | |
33 | + <div class="col-sm-offset-2 col-sm-10"> | |
34 | + <%= f.submit _('Submit'), class: "btn btn-primary" %> | |
35 | + <%= link_to _("Cancel"), oauth_applications_path, :class => "btn btn-default" %> | |
36 | + </div> | |
37 | + </div> | |
38 | +<% end %> | |
39 | + | ... | ... |
plugins/oauth_provider/views/doorkeeper/applications/edit.html.erb
0 → 100644
plugins/oauth_provider/views/doorkeeper/applications/index.html.erb
0 → 100644
... | ... | @@ -0,0 +1,31 @@ |
1 | +<div class="oauth-provider"> | |
2 | +<div class="page-header"> | |
3 | + <h3><%= link_to _('Oauh Provider'), '/admin/plugin/oauth_provider' %></h3> | |
4 | +</div> | |
5 | + | |
6 | +<p><%= link_to _('New Application'), new_oauth_application_path, class: 'btn btn-success' %></p> | |
7 | + | |
8 | +<table class="table table-striped"> | |
9 | + <thead> | |
10 | + <tr> | |
11 | + <th><%= _('Name') %></th> | |
12 | + <th><%= _('Callback URL') %></th> | |
13 | + <th></th> | |
14 | + <th></th> | |
15 | + </tr> | |
16 | + </thead> | |
17 | + <tbody> | |
18 | + <% @applications.each do |application| %> | |
19 | + <tr id="application_<%= application.id %>"> | |
20 | + <td><%= link_to application.name, [:oauth, application] %></td> | |
21 | + <td><%= application.redirect_uri %></td> | |
22 | + <td><%= link_to _('Edit'), edit_oauth_application_path(application), class: 'btn btn-link' %></td> | |
23 | + <td><%= render 'delete_form', application: application %></td> | |
24 | + </tr> | |
25 | + <% end %> | |
26 | + </tbody> | |
27 | +</table> | |
28 | +<div class="actions"> | |
29 | + <%= button(:back, _('Go back'), {:controller => 'oauth_provider_plugin_admin', :action => 'index'}) %> | |
30 | +</div> | |
31 | +</div> | ... | ... |
plugins/oauth_provider/views/doorkeeper/applications/new.html.erb
0 → 100644
plugins/oauth_provider/views/doorkeeper/applications/show.html.erb
0 → 100644
... | ... | @@ -0,0 +1,40 @@ |
1 | +<div class="page-header"> | |
2 | + <h1><%= _('Application: %s' % @application.name) %></h1> | |
3 | +</div> | |
4 | + | |
5 | +<div class="row"> | |
6 | + <div class="col-md-8"> | |
7 | + <h4><%= _('Application Id:') %></h4> | |
8 | + | |
9 | + <p><code id="application_id"><%= @application.uid %></code></p> | |
10 | + | |
11 | + <h4><%= _('Secret:') %></h4> | |
12 | + | |
13 | + <p><code id="secret"><%= @application.secret %></code></p> | |
14 | + | |
15 | + <h4><%= _('Callback urls:') %></h4> | |
16 | + | |
17 | + <table> | |
18 | + <% @application.redirect_uri.split.each do |uri| %> | |
19 | + <tr> | |
20 | + <td> | |
21 | + <code><%= uri %></code> | |
22 | + </td> | |
23 | + <td> | |
24 | + </td> | |
25 | + </tr> | |
26 | + <% end %> | |
27 | + </table> | |
28 | + </div> | |
29 | + | |
30 | + <div class="col-md-4"> | |
31 | + <h3><%= _('Actions') %></h3> | |
32 | + | |
33 | + <p> | |
34 | + <%= link_to _('Edit'), edit_oauth_application_path(@application), class: 'btn btn-primary' %> | |
35 | + <%= link_to _("Cancel"), oauth_applications_path, :class => "btn btn-default" %> | |
36 | + </p> | |
37 | + | |
38 | + <p><%= render 'delete_form', application: @application, submit_btn_css: 'btn btn-danger' %></p> | |
39 | + </div> | |
40 | +</div> | ... | ... |
plugins/oauth_provider/views/doorkeeper/authorizations/error.html.erb
0 → 100644
plugins/oauth_provider/views/doorkeeper/authorizations/new.html.erb
0 → 100644
... | ... | @@ -0,0 +1,43 @@ |
1 | +<div class="oauth-provider-authorize"> | |
2 | + | |
3 | +<header class="page-header" role="banner"> | |
4 | + <h1><%= _('Authorize required') %></h1> | |
5 | +</header> | |
6 | + | |
7 | +<main role="main"> | |
8 | + <p class="h4"> | |
9 | + <%= _('Authorize %s to use your account?' % "<strong class=\"text-info\">#{@pre_auth.client.name}</strong>") %> | |
10 | + </p> | |
11 | + | |
12 | + <% if @pre_auth.scopes %> | |
13 | + <div id="oauth-permissions"> | |
14 | + <p><%= _('This application will be able to:') %></p> | |
15 | + | |
16 | + <ul class="text-info"> | |
17 | + <% @pre_auth.scopes.each do |scope| %> | |
18 | + <li><%= OauthProviderPlugin::SCOPE_TRANSLATION[scope] %></li> | |
19 | + <% end %> | |
20 | + </ul> | |
21 | + </div> | |
22 | + <% end %> | |
23 | + | |
24 | + <div class="actions"> | |
25 | + <%= form_tag oauth_authorization_path, method: :post do %> | |
26 | + <%= hidden_field_tag :client_id, @pre_auth.client.uid %> | |
27 | + <%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %> | |
28 | + <%= hidden_field_tag :state, @pre_auth.state %> | |
29 | + <%= hidden_field_tag :response_type, @pre_auth.response_type %> | |
30 | + <%= hidden_field_tag :scope, @pre_auth.scope %> | |
31 | + <%= submit_button :ok, _("Authorize") %> | |
32 | + <% end %> | |
33 | + <%= form_tag oauth_authorization_path, method: :delete do %> | |
34 | + <%= hidden_field_tag :client_id, @pre_auth.client.uid %> | |
35 | + <%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %> | |
36 | + <%= hidden_field_tag :state, @pre_auth.state %> | |
37 | + <%= hidden_field_tag :response_type, @pre_auth.response_type %> | |
38 | + <%= hidden_field_tag :scope, @pre_auth.scope %> | |
39 | + <%= submit_button :cancel, _("Deny") %> | |
40 | + <% end %> | |
41 | + </div> | |
42 | +</main> | |
43 | +</div> | ... | ... |
plugins/oauth_provider/views/doorkeeper/authorizations/show.html.erb
0 → 100644
plugins/oauth_provider/views/doorkeeper/authorized_applications/_delete_form.html.erb
0 → 100644
... | ... | @@ -0,0 +1,5 @@ |
1 | +<%- submit_btn_css ||= 'btn btn-link' %> | |
2 | +<%= form_tag oauth_authorized_application_path(application) do %> | |
3 | + <input type="hidden" name="_method" value="delete"> | |
4 | + <%= submit_tag 'Revoke', onclick: "return confirm('Are you sure?')", class: submit_btn_css %> | |
5 | +<% end %> | ... | ... |
plugins/oauth_provider/views/doorkeeper/authorized_applications/index.html.erb
0 → 100644
... | ... | @@ -0,0 +1,31 @@ |
1 | +<div class="oauth-provider"> | |
2 | +<header class="page-header"> | |
3 | + <h1>Your authorized applications</h1> | |
4 | +</header> | |
5 | + | |
6 | +<main role="main"> | |
7 | + <table class="table table-striped"> | |
8 | + <thead> | |
9 | + <tr> | |
10 | + <th>Application</th> | |
11 | + <th>Created At</th> | |
12 | + <th></th> | |
13 | + <th></th> | |
14 | + </tr> | |
15 | + </thead> | |
16 | + <tbody> | |
17 | + <% @applications.each do |application| %> | |
18 | + <tr> | |
19 | + <td><%= application.name %></td> | |
20 | + <td><%= application.created_at.strftime('%Y-%m-%d %H:%M:%S') %></td> | |
21 | + <td><%= render 'delete_form', application: application %></td> | |
22 | + </tr> | |
23 | + <% end %> | |
24 | + </tbody> | |
25 | + </table> | |
26 | +</main> | |
27 | + | |
28 | +<div class="actions"> | |
29 | + <%= button(:back, _('Go back'), :back) %> | |
30 | +</div> | |
31 | +</div> | ... | ... |
plugins/oauth_provider/views/oauth_provider_plugin_admin/index.html.erb
0 → 100644
... | ... | @@ -0,0 +1,14 @@ |
1 | +<div class="oauth-provider"> | |
2 | +<h3><%= _('Oauh Provider') %></h3> | |
3 | + | |
4 | + <div class="applications"> | |
5 | + <%= link_to _('Applications'), oauth_applications_path %> | |
6 | + </div> | |
7 | + <div class="authorized-applications"> | |
8 | + <%= link_to _('Authorized Applications'), oauth_authorized_applications_path %> | |
9 | + </div> | |
10 | + | |
11 | + <div class="actions"> | |
12 | + <%= button(:back, _('Go back'), {:controller => 'plugins', :action => 'index'}) %> | |
13 | + </div> | |
14 | +</div> | ... | ... |
plugins/relevant_content/lib/relevant_content_plugin/relevant_content_block.rb
... | ... | @@ -4,7 +4,7 @@ class RelevantContentPlugin::RelevantContentBlock < Block |
4 | 4 | end |
5 | 5 | |
6 | 6 | def default_title |
7 | - _('Relevant content') | |
7 | + _('Relevant content') | |
8 | 8 | end |
9 | 9 | |
10 | 10 | def help |
... | ... | @@ -53,7 +53,7 @@ class RelevantContentPlugin::RelevantContentBlock < Block |
53 | 53 | env = owner.environment |
54 | 54 | end |
55 | 55 | |
56 | - if env.plugin_enabled?(VotePlugin) | |
56 | + if env.plugin_enabled?('VotePlugin') | |
57 | 57 | if self.show_most_liked |
58 | 58 | docs = Article.more_positive_votes(owner, self.limit) |
59 | 59 | if !docs.blank? | ... | ... |
plugins/relevant_content/test/unit/article.rb
... | ... | @@ -20,10 +20,10 @@ class RelevantContentBlockTest < ActiveSupport::TestCase |
20 | 20 | |
21 | 21 | def enable_vote_plugin |
22 | 22 | enabled = false |
23 | - environment=Environment.default | |
23 | + environment = Environment.default | |
24 | 24 | if Noosfero::Plugin.all.include?('VotePlugin') |
25 | - if not environment.enabled_plugins.include?(:vote) | |
26 | - environment.enable_plugin(Vote) | |
25 | + if not environment.enabled_plugins.include?('VotePlugin') | |
26 | + environment.enable_plugin(VotePlugin) | |
27 | 27 | environment.save! |
28 | 28 | end |
29 | 29 | enabled = true |
... | ... | @@ -145,4 +145,4 @@ class RelevantContentBlockTest < ActiveSupport::TestCase |
145 | 145 | assert_equal '23 votes for 29 votes against', articles.first.name |
146 | 146 | assert_equal '2 votes against', articles.last.name |
147 | 147 | end |
148 | -end | |
149 | 148 | \ No newline at end of file |
149 | +end | ... | ... |
plugins/relevant_content/test/unit/relevant_content_block_test.rb
... | ... | @@ -44,4 +44,19 @@ class RelevantContentBlockTest < ActiveSupport::TestCase |
44 | 44 | assert_equal RelevantContentPlugin::RelevantContentBlock.expire_on, {:environment=>[:article], :profile=>[:article]} |
45 | 45 | end |
46 | 46 | |
47 | + should 'not crash if vote plugin is not found' do | |
48 | + box = fast_create(Box, :owner_id => @profile.id, :owner_type => 'Profile') | |
49 | + block = RelevantContentPlugin::RelevantContentBlock.new(:box => box) | |
50 | + | |
51 | + Environment.any_instance.stubs(:enabled_plugins).returns(['RelevantContent']) | |
52 | + # When the plugin is disabled from noosfero instance, its constant name is | |
53 | + # undefined. To test this case, I have to manually undefine the constant | |
54 | + # if necessary. | |
55 | + Object.send(:remove_const, VotePlugin.to_s) if defined? VotePlugin | |
56 | + | |
57 | + assert_nothing_raised do | |
58 | + block.content | |
59 | + end | |
60 | + end | |
61 | + | |
47 | 62 | end | ... | ... |
plugins/shopping_cart/public/cart.js
... | ... | @@ -290,14 +290,11 @@ function Cart(config) { |
290 | 290 | log.error('Send request - HTTP '+status, errorThrown); |
291 | 291 | }, |
292 | 292 | complete: function() { |
293 | - $.colorbox.close(); | |
293 | + noosfero.modal.close(); | |
294 | 294 | } |
295 | 295 | }); |
296 | 296 | } |
297 | 297 | |
298 | - Cart.colorbox_close = function() { | |
299 | - $.colorbox.close(); | |
300 | - } | |
301 | 298 | |
302 | 299 | $(window).bind('beforeunload', function(){ |
303 | 300 | log('Page unload.'); | ... | ... |
plugins/shopping_cart/views/cart.html.erb
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | <a href="cart:clean" onclick="Cart.clean(this); return false" class="cart-clean"><%=_('Clean basket')%></a> |
6 | 6 | <ul class="cart-items"></ul> |
7 | 7 | <div class="cart-total"><%=_('Total:')%> <b></b></div> |
8 | - <a href="/plugin/shopping_cart/buy" class="cart-buy colorbox"><%=_('Shopping checkout')%></a> | |
8 | + <a href="/plugin/shopping_cart/buy" class="cart-buy modal"><%=_('Shopping checkout')%></a> | |
9 | 9 | </div> |
10 | 10 | <a href="#" onclick="Cart.toggle(this); return false" class="cart-toggle"> |
11 | 11 | <span class="str-show"><%=_('Show basket')%></span> | ... | ... |
plugins/shopping_cart/views/shopping_cart_plugin/buy.html.erb
... | ... | @@ -24,7 +24,7 @@ |
24 | 24 | <% end %> |
25 | 25 | <% delivery_option = @settings.delivery_options.first && @settings.delivery_options.first.first %> |
26 | 26 | <%= items_table(@cart[:items], @profile, delivery_option) %> |
27 | - <%= link_to '', '#', :onclick => "Cart.colorbox_close(this);", :class => 'cart-box-close icon-cancel' %> | |
27 | + <%= link_to_function '', "noosfero.modal.close();", :class => 'cart-box-close icon-cancel' %> | |
28 | 28 | </div> |
29 | 29 | |
30 | 30 | <%= javascript_include_tag '../plugins/shopping_cart/buy' %> | ... | ... |
plugins/shopping_cart/views/shopping_cart_plugin_profile/buy.html.erb
... | ... | @@ -17,7 +17,7 @@ |
17 | 17 | </div> |
18 | 18 | <% end %> |
19 | 19 | <%= items_table(session[:cart][:items], profile) %> |
20 | - <%= link_to '', '#', :onclick => "Cart.colorbox_close(this);", :class => 'cart-box-close icon-cancel' %> | |
20 | + <%= link_to_function '', "noosfero.modal.close();", :class => 'cart-box-close icon-cancel' %> | |
21 | 21 | </div> |
22 | 22 | |
23 | 23 | <script type="text/javascript"> | ... | ... |
plugins/statistics/test/functional/statistics_plugin_home_controller_test.rb
100644 → 100755
... | ... | @@ -84,6 +84,9 @@ class HomeControllerTest < ActionController::TestCase |
84 | 84 | end |
85 | 85 | |
86 | 86 | should 'not display products class in statistics-block-data block' do |
87 | + @block.product_counter = true | |
88 | + @environment.disable('products_for_enterprises') | |
89 | + @block.save! | |
87 | 90 | get :index |
88 | 91 | |
89 | 92 | assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'products'} } | ... | ... |
plugins/stoa/public/javascripts/signup_complement.js
... | ... | @@ -55,9 +55,10 @@ $("#usp_id_field").observe_field(1, function(){ |
55 | 55 | }); |
56 | 56 | |
57 | 57 | function displayValidationUspIdError(error){ |
58 | - jQuery.colorbox({html: '<h2>'+error.message+'</h2>'+error.backtrace.join("<br />"), | |
58 | + noosfero.modal.html('<h2>'+error.message+'</h2>'+error.backtrace.join("<br />"), { | |
59 | 59 | height: "80%", |
60 | - width: "70%" }); | |
60 | + width: "70%" | |
61 | + }); | |
61 | 62 | } |
62 | 63 | |
63 | 64 | jQuery('#usp_id_field').focus(function() { jQuery('#usp-id-balloon').fadeIn('slow'); }); | ... | ... |
plugins/tolerance_time/lib/tolerance_time_plugin.rb
... | ... | @@ -28,8 +28,7 @@ class ToleranceTimePlugin < Noosfero::Plugin |
28 | 28 | end |
29 | 29 | |
30 | 30 | def cms_controller_filters |
31 | - p = Proc.new { |context| return if !context.environment.plugin_enabled?(ToleranceTimePlugin) } | |
32 | - block = lambda do | |
31 | + block = proc do | |
33 | 32 | content = Article.find(params[:id]) |
34 | 33 | if ToleranceTimePlugin.expired?(content) |
35 | 34 | session[:notice] = _("This content can't be edited anymore because it expired the tolerance time") |
... | ... | @@ -43,8 +42,7 @@ class ToleranceTimePlugin < Noosfero::Plugin |
43 | 42 | end |
44 | 43 | |
45 | 44 | def content_viewer_controller_filters |
46 | - p = Proc.new { |context| return if !context.environment.plugin_enabled?(ToleranceTimePlugin) } | |
47 | - block = lambda do | |
45 | + block = proc do | |
48 | 46 | content = Comment.find(params[:id]) |
49 | 47 | if ToleranceTimePlugin.expired?(content) |
50 | 48 | session[:notice] = _("This content can't be edited anymore because it expired the tolerance time") | ... | ... |
... | ... | @@ -0,0 +1,37 @@ |
1 | +#boxes { | |
2 | + display: table; | |
3 | + width: 100%; | |
4 | +} | |
5 | + | |
6 | +.box-1 { | |
7 | + margin: 0 0 0 240px; | |
8 | +} | |
9 | + | |
10 | +.box-1 .blocks { | |
11 | + width: 100%; | |
12 | + float: left; | |
13 | +} | |
14 | + | |
15 | +.box-2 { | |
16 | + position: relative; | |
17 | + float: left; | |
18 | + width: 190px; | |
19 | +} | |
20 | + | |
21 | +.box-3 { | |
22 | + position: relative; | |
23 | + display: table-footer-group; | |
24 | + width: 100%; | |
25 | +} | |
26 | + | |
27 | +#profile-activity ul, | |
28 | +#profile-network ul, | |
29 | +#profile-wall ul { | |
30 | + width: 460px; | |
31 | +} | |
32 | +#profile-activity ul.comment-replies, | |
33 | +#profile-network ul.comment-replies, | |
34 | +#profile-wall ul.comment-replies { | |
35 | + width: auto; | |
36 | +} | |
37 | + | ... | ... |
3.87 KB
... | ... | @@ -0,0 +1,239 @@ |
1 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
2 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> | |
3 | + | |
4 | +<svg | |
5 | + xmlns:dc="http://purl.org/dc/elements/1.1/" | |
6 | + xmlns:cc="http://creativecommons.org/ns#" | |
7 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |
8 | + xmlns:svg="http://www.w3.org/2000/svg" | |
9 | + xmlns="http://www.w3.org/2000/svg" | |
10 | + xmlns:xlink="http://www.w3.org/1999/xlink" | |
11 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |
12 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |
13 | + width="64px" | |
14 | + height="64px" | |
15 | + id="svg2383" | |
16 | + sodipodi:version="0.32" | |
17 | + inkscape:version="0.48.4 r9939" | |
18 | + sodipodi:docname="thumbnail.svg" | |
19 | + inkscape:output_extension="org.inkscape.output.svg.inkscape" | |
20 | + inkscape:export-filename="thumbnail.png" | |
21 | + inkscape:export-xdpi="90" | |
22 | + inkscape:export-ydpi="90" | |
23 | + version="1.1"> | |
24 | + <defs | |
25 | + id="defs2385"> | |
26 | + <linearGradient | |
27 | + id="linearGradient3263"> | |
28 | + <stop | |
29 | + id="stop3265" | |
30 | + offset="0" | |
31 | + style="stop-color:#204a87;stop-opacity:1" /> | |
32 | + <stop | |
33 | + id="stop3267" | |
34 | + offset="1" | |
35 | + style="stop-color:#729fcf;stop-opacity:1" /> | |
36 | + </linearGradient> | |
37 | + <linearGradient | |
38 | + id="linearGradient3257" | |
39 | + inkscape:collect="always"> | |
40 | + <stop | |
41 | + id="stop3259" | |
42 | + offset="0" | |
43 | + style="stop-color:#204a87;stop-opacity:1" /> | |
44 | + <stop | |
45 | + id="stop3261" | |
46 | + offset="1" | |
47 | + style="stop-color:#729fcf;stop-opacity:1" /> | |
48 | + </linearGradient> | |
49 | + <linearGradient | |
50 | + inkscape:collect="always" | |
51 | + id="linearGradient3245"> | |
52 | + <stop | |
53 | + style="stop-color:#204a87;stop-opacity:1" | |
54 | + offset="0" | |
55 | + id="stop3247" /> | |
56 | + <stop | |
57 | + style="stop-color:#729fcf;stop-opacity:1" | |
58 | + offset="1" | |
59 | + id="stop3249" /> | |
60 | + </linearGradient> | |
61 | + <inkscape:perspective | |
62 | + sodipodi:type="inkscape:persp3d" | |
63 | + inkscape:vp_x="0 : 32 : 1" | |
64 | + inkscape:vp_y="0 : 1000 : 0" | |
65 | + inkscape:vp_z="64 : 32 : 1" | |
66 | + inkscape:persp3d-origin="32 : 21.333333 : 1" | |
67 | + id="perspective2391" /> | |
68 | + <filter | |
69 | + inkscape:collect="always" | |
70 | + id="filter3241"> | |
71 | + <feGaussianBlur | |
72 | + inkscape:collect="always" | |
73 | + stdDeviation="0.9075" | |
74 | + id="feGaussianBlur3243" /> | |
75 | + </filter> | |
76 | + <linearGradient | |
77 | + inkscape:collect="always" | |
78 | + xlink:href="#linearGradient3245" | |
79 | + id="linearGradient3251" | |
80 | + x1="11.5" | |
81 | + y1="60.5" | |
82 | + x2="3.5" | |
83 | + y2="3.5" | |
84 | + gradientUnits="userSpaceOnUse" | |
85 | + gradientTransform="matrix(1.0025263,0,0,0.76423683,0.2157619,0.85033188)" /> | |
86 | + <linearGradient | |
87 | + inkscape:collect="always" | |
88 | + xlink:href="#linearGradient3263" | |
89 | + id="linearGradient3253" | |
90 | + x1="42.5" | |
91 | + y1="60.5" | |
92 | + x2="19.5" | |
93 | + y2="3.5" | |
94 | + gradientUnits="userSpaceOnUse" | |
95 | + gradientTransform="matrix(1.4160224,0,0,0.76166072,-5.6247232,0.93276759)" /> | |
96 | + <linearGradient | |
97 | + inkscape:collect="always" | |
98 | + xlink:href="#linearGradient3257" | |
99 | + id="linearGradient3255" | |
100 | + x1="60.5" | |
101 | + y1="60.5" | |
102 | + x2="51.5" | |
103 | + y2="3.5" | |
104 | + gradientUnits="userSpaceOnUse" | |
105 | + gradientTransform="translate(0.32391508,-62.512846)" /> | |
106 | + </defs> | |
107 | + <sodipodi:namedview | |
108 | + id="base" | |
109 | + pagecolor="#ffffff" | |
110 | + bordercolor="#666666" | |
111 | + borderopacity="1.0" | |
112 | + inkscape:pageopacity="0.0" | |
113 | + inkscape:pageshadow="2" | |
114 | + inkscape:zoom="3.5852524" | |
115 | + inkscape:cx="21.387308" | |
116 | + inkscape:cy="33.791467" | |
117 | + inkscape:current-layer="layer1" | |
118 | + showgrid="true" | |
119 | + inkscape:document-units="px" | |
120 | + inkscape:grid-bbox="true" | |
121 | + inkscape:window-width="1364" | |
122 | + inkscape:window-height="714" | |
123 | + inkscape:window-x="0" | |
124 | + inkscape:window-y="27" | |
125 | + objecttolerance="10" | |
126 | + gridtolerance="10" | |
127 | + guidetolerance="10" | |
128 | + inkscape:window-maximized="0"> | |
129 | + <inkscape:grid | |
130 | + type="xygrid" | |
131 | + id="grid2382" | |
132 | + visible="true" | |
133 | + enabled="true" | |
134 | + originx="0.5px" | |
135 | + originy="0.5px" | |
136 | + empcolor="#0000ff" | |
137 | + empopacity="0.1254902" | |
138 | + dotted="true" /> | |
139 | + </sodipodi:namedview> | |
140 | + <metadata | |
141 | + id="metadata2388"> | |
142 | + <rdf:RDF> | |
143 | + <cc:Work | |
144 | + rdf:about=""> | |
145 | + <dc:format>image/svg+xml</dc:format> | |
146 | + <dc:type | |
147 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |
148 | + <dc:title></dc:title> | |
149 | + </cc:Work> | |
150 | + </rdf:RDF> | |
151 | + </metadata> | |
152 | + <g | |
153 | + id="layer1" | |
154 | + inkscape:label="Layer 1" | |
155 | + inkscape:groupmode="layer"> | |
156 | + <rect | |
157 | + rx="2" | |
158 | + ry="2" | |
159 | + y="2.5" | |
160 | + x="50.5" | |
161 | + height="59" | |
162 | + width="12" | |
163 | + id="rect3186" | |
164 | + style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3241);enable-background:accumulate" | |
165 | + transform="matrix(0,1,-1,0,64.512846,0.32391508)" /> | |
166 | + <rect | |
167 | + style="fill:url(#linearGradient3255);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | |
168 | + id="rect3154" | |
169 | + width="12" | |
170 | + height="59" | |
171 | + x="49.823914" | |
172 | + y="-61.012848" | |
173 | + ry="2" | |
174 | + transform="matrix(0,1,-1,0,0,0)" /> | |
175 | + <rect | |
176 | + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | |
177 | + id="rect3164" | |
178 | + width="10" | |
179 | + height="57" | |
180 | + x="50.823914" | |
181 | + y="-60.012848" | |
182 | + ry="1" | |
183 | + transform="matrix(0,1,-1,0,0,0)" /> | |
184 | + <rect | |
185 | + rx="2" | |
186 | + ry="2" | |
187 | + style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3241);enable-background:accumulate" | |
188 | + id="rect3184" | |
189 | + width="11" | |
190 | + height="59" | |
191 | + x="2.5" | |
192 | + y="2.5" | |
193 | + transform="matrix(1.0025263,0,0,0.76423683,0.2157619,0.85033188)" /> | |
194 | + <rect | |
195 | + rx="2" | |
196 | + ry="2" | |
197 | + style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3241);enable-background:accumulate" | |
198 | + id="rect3188" | |
199 | + width="31" | |
200 | + height="59" | |
201 | + x="16.5" | |
202 | + y="2.5" | |
203 | + transform="matrix(1.4160224,0,0,0.76166071,-5.6247232,0.93276758)" /> | |
204 | + <rect | |
205 | + y="1.9966872" | |
206 | + x="1.7195514" | |
207 | + height="45.089973" | |
208 | + width="11.02779" | |
209 | + id="rect2395" | |
210 | + style="fill:url(#linearGradient3251);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | |
211 | + ry="1.5284736" /> | |
212 | + <rect | |
213 | + y="2.0752587" | |
214 | + x="16.323626" | |
215 | + height="44.937984" | |
216 | + width="43.896694" | |
217 | + id="rect3156" | |
218 | + style="fill:url(#linearGradient3253);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:1.03852236;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | |
219 | + ry="1.5233214" /> | |
220 | + <rect | |
221 | + ry="0.76423681" | |
222 | + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | |
223 | + id="rect3158" | |
224 | + width="9.0227375" | |
225 | + height="43.561501" | |
226 | + x="2.7220778" | |
227 | + y="2.7609239" /> | |
228 | + <rect | |
229 | + y="2.8369193" | |
230 | + x="17.739647" | |
231 | + height="43.414661" | |
232 | + width="41.064651" | |
233 | + id="rect3162" | |
234 | + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1.03852236;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | |
235 | + ry="0.7616607" | |
236 | + inkscape:export-xdpi="90" | |
237 | + inkscape:export-ydpi="90" /> | |
238 | + </g> | |
239 | +</svg> | ... | ... |
public/images/colorbox/controls.png
public/javascripts/application.js
... | ... | @@ -1005,31 +1005,6 @@ log.error = function() { |
1005 | 1005 | window.log.apply(window, jQuery.merge(['error'], arguments)); |
1006 | 1006 | } |
1007 | 1007 | |
1008 | -jQuery(function($) { | |
1009 | - $('.colorbox').live('click', function() { | |
1010 | - $.colorbox({ | |
1011 | - href: $(this).attr('href'), | |
1012 | - maxWidth: $(window).width()-50, | |
1013 | - height: $(window).height()-50, | |
1014 | - open: true, | |
1015 | - fixed: true, | |
1016 | - close: 'Cancel', | |
1017 | - onComplete: function(bt) { | |
1018 | - var opt = {}, maxH = $(window).height()-50; | |
1019 | - if ($('#cboxLoadedContent *:first').height() > maxH) opt.height = maxH; | |
1020 | - $.colorbox.resize(opt); | |
1021 | - } | |
1022 | - }); | |
1023 | - return false; | |
1024 | - }); | |
1025 | - | |
1026 | - $('.colorbox-close').live('click', function() { | |
1027 | - $.colorbox.close(); | |
1028 | - return false; | |
1029 | - }); | |
1030 | - | |
1031 | -}); | |
1032 | - | |
1033 | 1008 | function showHideTermsOfUse() { |
1034 | 1009 | if( jQuery("#article_has_terms_of_use").attr("checked") ) |
1035 | 1010 | jQuery("#text_area_terms_of_use").show(); | ... | ... |
public/javascripts/article.js
... | ... | @@ -88,7 +88,7 @@ jQuery(function($) { |
88 | 88 | var $item = $(this).closest('.item'); |
89 | 89 | var html_selector = $item.attr('data-item'); |
90 | 90 | insert_item_in_text($item.find(html_selector)); |
91 | - $.colorbox.close(); | |
91 | + noosfero.modal.close(); | |
92 | 92 | return false; |
93 | 93 | }); |
94 | 94 | $('a.zoom').live('click', function() { |
... | ... | @@ -96,14 +96,13 @@ jQuery(function($) { |
96 | 96 | var html_selector = $item.attr('data-item'); |
97 | 97 | var name = $item.attr('title'); |
98 | 98 | var img = $item.find(html_selector).find('img').attr('src'); |
99 | - $.colorbox({ | |
100 | - html: zoom_dialog_html(name, img), | |
101 | - scrolling: false | |
99 | + noosfero.modal.html(zoom_dialog_html(img), { | |
100 | + scrolling: false, | |
102 | 101 | }); |
103 | 102 | return false; |
104 | 103 | }); |
105 | 104 | $('a.close').live('click', function() { |
106 | - $.colorbox.close(); | |
105 | + noosfero.modal.close(); | |
107 | 106 | return false; |
108 | 107 | }) |
109 | 108 | ... | ... |
public/javascripts/colorbox.js
... | ... | @@ -1,814 +0,0 @@ |
1 | -// ColorBox v1.3.16 - a full featured, light-weight, customizable lightbox based on jQuery 1.3+ | |
2 | -// Copyright (c) 2011 Jack Moore - jack@colorpowered.com | |
3 | -// Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php | |
4 | -(function ($, document, window) { | |
5 | - var | |
6 | - // ColorBox Default Settings. | |
7 | - // See http://colorpowered.com/colorbox for details. | |
8 | - defaults = { | |
9 | - transition: "elastic", | |
10 | - speed: 300, | |
11 | - width: false, | |
12 | - initialWidth: "600", | |
13 | - innerWidth: false, | |
14 | - maxWidth: false, | |
15 | - height: false, | |
16 | - initialHeight: "450", | |
17 | - innerHeight: false, | |
18 | - maxHeight: false, | |
19 | - scalePhotos: true, | |
20 | - scrolling: true, | |
21 | - inline: false, | |
22 | - html: false, | |
23 | - iframe: false, | |
24 | - fastIframe: true, | |
25 | - photo: false, | |
26 | - href: false, | |
27 | - title: false, | |
28 | - rel: false, | |
29 | - opacity: 0.9, | |
30 | - preloading: true, | |
31 | - current: "image {current} of {total}", | |
32 | - previous: "previous", | |
33 | - next: "next", | |
34 | - close: "close", | |
35 | - open: false, | |
36 | - returnFocus: true, | |
37 | - loop: true, | |
38 | - slideshow: false, | |
39 | - slideshowAuto: true, | |
40 | - slideshowSpeed: 2500, | |
41 | - slideshowStart: "start slideshow", | |
42 | - slideshowStop: "stop slideshow", | |
43 | - onOpen: false, | |
44 | - onLoad: false, | |
45 | - onComplete: false, | |
46 | - onCleanup: false, | |
47 | - onClosed: false, | |
48 | - overlayClose: true, | |
49 | - escKey: true, | |
50 | - arrowKey: true | |
51 | - }, | |
52 | - | |
53 | - // Abstracting the HTML and event identifiers for easy rebranding | |
54 | - colorbox = 'colorbox', | |
55 | - prefix = 'cbox', | |
56 | - | |
57 | - // Events | |
58 | - event_open = prefix + '_open', | |
59 | - event_load = prefix + '_load', | |
60 | - event_complete = prefix + '_complete', | |
61 | - event_cleanup = prefix + '_cleanup', | |
62 | - event_closed = prefix + '_closed', | |
63 | - event_purge = prefix + '_purge', | |
64 | - | |
65 | - // Special Handling for IE | |
66 | - isIE = $.browser.msie && !$.support.opacity, // feature detection alone gave a false positive on at least one phone browser and on some development versions of Chrome. | |
67 | - isIE6 = isIE && $.browser.version < 7, | |
68 | - event_ie6 = prefix + '_IE6', | |
69 | - | |
70 | - // Cached jQuery Object Variables | |
71 | - $overlay, | |
72 | - $box, | |
73 | - $wrap, | |
74 | - $content, | |
75 | - $topBorder, | |
76 | - $leftBorder, | |
77 | - $rightBorder, | |
78 | - $bottomBorder, | |
79 | - $related, | |
80 | - $window, | |
81 | - $loaded, | |
82 | - $loadingBay, | |
83 | - $loadingOverlay, | |
84 | - $title, | |
85 | - $current, | |
86 | - $slideshow, | |
87 | - $next, | |
88 | - $prev, | |
89 | - $close, | |
90 | - $groupControls, | |
91 | - | |
92 | - // Variables for cached values or use across multiple functions | |
93 | - settings = {}, | |
94 | - interfaceHeight, | |
95 | - interfaceWidth, | |
96 | - loadedHeight, | |
97 | - loadedWidth, | |
98 | - element, | |
99 | - index, | |
100 | - photo, | |
101 | - open, | |
102 | - active, | |
103 | - closing = false, | |
104 | - | |
105 | - publicMethod, | |
106 | - boxElement = prefix + 'Element'; | |
107 | - | |
108 | - // **************** | |
109 | - // HELPER FUNCTIONS | |
110 | - // **************** | |
111 | - | |
112 | - // jQuery object generator to reduce code size | |
113 | - function $div(id, cssText) { | |
114 | - var div = document.createElement('div'); | |
115 | - if (id) { | |
116 | - div.id = prefix + id; | |
117 | - } | |
118 | - div.style.cssText = cssText || false; | |
119 | - return $(div); | |
120 | - } | |
121 | - | |
122 | - // Convert % values to pixels | |
123 | - function setSize(size, dimension) { | |
124 | - dimension = dimension === 'x' ? $window.width() : $window.height(); | |
125 | - return (typeof size === 'string') ? Math.round((/%/.test(size) ? (dimension / 100) * parseInt(size, 10) : parseInt(size, 10))) : size; | |
126 | - } | |
127 | - | |
128 | - // Checks an href to see if it is a photo. | |
129 | - // There is a force photo option (photo: true) for hrefs that cannot be matched by this regex. | |
130 | - function isImage(url) { | |
131 | - return settings.photo || /\.(gif|png|jpg|jpeg|bmp)(?:\?([^#]*))?(?:#(\.*))?$/i.test(url); | |
132 | - } | |
133 | - | |
134 | - // Assigns function results to their respective settings. This allows functions to be used as values. | |
135 | - function process(settings) { | |
136 | - for (var i in settings) { | |
137 | - if ($.isFunction(settings[i]) && i.substring(0, 2) !== 'on') { // checks to make sure the function isn't one of the callbacks, they will be handled at the appropriate time. | |
138 | - settings[i] = settings[i].call(element); | |
139 | - } | |
140 | - } | |
141 | - settings.rel = settings.rel || element.rel || 'nofollow'; | |
142 | - settings.href = $.trim(settings.href || $(element).attr('href')); | |
143 | - settings.title = settings.title || element.title; | |
144 | - } | |
145 | - | |
146 | - function trigger(event, callback) { | |
147 | - if (callback) { | |
148 | - callback.call(element); | |
149 | - } | |
150 | - $.event.trigger(event); | |
151 | - } | |
152 | - | |
153 | - // Slideshow functionality | |
154 | - function slideshow() { | |
155 | - var | |
156 | - timeOut, | |
157 | - className = prefix + "Slideshow_", | |
158 | - click = "click." + prefix, | |
159 | - start, | |
160 | - stop, | |
161 | - clear; | |
162 | - | |
163 | - if (settings.slideshow && $related[1]) { | |
164 | - start = function () { | |
165 | - $slideshow | |
166 | - .text(settings.slideshowStop) | |
167 | - .unbind(click) | |
168 | - .bind(event_complete, function () { | |
169 | - if (index < $related.length - 1 || settings.loop) { | |
170 | - timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed); | |
171 | - } | |
172 | - }) | |
173 | - .bind(event_load, function () { | |
174 | - clearTimeout(timeOut); | |
175 | - }) | |
176 | - .one(click + ' ' + event_cleanup, stop); | |
177 | - $box.removeClass(className + "off").addClass(className + "on"); | |
178 | - timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed); | |
179 | - }; | |
180 | - | |
181 | - stop = function () { | |
182 | - clearTimeout(timeOut); | |
183 | - $slideshow | |
184 | - .text(settings.slideshowStart) | |
185 | - .unbind([event_complete, event_load, event_cleanup, click].join(' ')) | |
186 | - .one(click, start); | |
187 | - $box.removeClass(className + "on").addClass(className + "off"); | |
188 | - }; | |
189 | - | |
190 | - if (settings.slideshowAuto) { | |
191 | - start(); | |
192 | - } else { | |
193 | - stop(); | |
194 | - } | |
195 | - } | |
196 | - } | |
197 | - | |
198 | - function launch(elem) { | |
199 | - if (!closing) { | |
200 | - | |
201 | - element = elem; | |
202 | - | |
203 | - process($.extend(settings, $.data(element, colorbox))); | |
204 | - | |
205 | - $related = $(element); | |
206 | - | |
207 | - index = 0; | |
208 | - | |
209 | - if (settings.rel !== 'nofollow') { | |
210 | - $related = $('.' + boxElement).filter(function () { | |
211 | - var relRelated = $.data(this, colorbox).rel || this.rel; | |
212 | - return (relRelated === settings.rel); | |
213 | - }); | |
214 | - index = $related.index(element); | |
215 | - | |
216 | - // Check direct calls to ColorBox. | |
217 | - if (index === -1) { | |
218 | - $related = $related.add(element); | |
219 | - index = $related.length - 1; | |
220 | - } | |
221 | - } | |
222 | - | |
223 | - if (!open) { | |
224 | - open = active = true; // Prevents the page-change action from queuing up if the visitor holds down the left or right keys. | |
225 | - | |
226 | - $box.show(); | |
227 | - | |
228 | - if (settings.returnFocus) { | |
229 | - try { | |
230 | - element.blur(); | |
231 | - $(element).one(event_closed, function () { | |
232 | - try { | |
233 | - this.focus(); | |
234 | - } catch (e) { | |
235 | - // do nothing | |
236 | - } | |
237 | - }); | |
238 | - } catch (e) { | |
239 | - // do nothing | |
240 | - } | |
241 | - } | |
242 | - | |
243 | - // +settings.opacity avoids a problem in IE when using non-zero-prefixed-string-values, like '.5' | |
244 | - $overlay.css({"opacity": +settings.opacity, "cursor": settings.overlayClose ? "pointer" : "auto"}).show(); | |
245 | - | |
246 | - // Opens inital empty ColorBox prior to content being loaded. | |
247 | - settings.w = setSize(settings.initialWidth, 'x'); | |
248 | - settings.h = setSize(settings.initialHeight, 'y'); | |
249 | - publicMethod.position(0); | |
250 | - | |
251 | - if (isIE6) { | |
252 | - $window.bind('resize.' + event_ie6 + ' scroll.' + event_ie6, function () { | |
253 | - $overlay.css({width: $window.width(), height: $window.height(), top: $window.scrollTop(), left: $window.scrollLeft()}); | |
254 | - }).trigger('resize.' + event_ie6); | |
255 | - } | |
256 | - | |
257 | - trigger(event_open, settings.onOpen); | |
258 | - | |
259 | - $groupControls.add($title).hide(); | |
260 | - | |
261 | - $close.html(settings.close).show(); | |
262 | - } | |
263 | - | |
264 | - publicMethod.load(true); | |
265 | - } | |
266 | - } | |
267 | - | |
268 | - // **************** | |
269 | - // PUBLIC FUNCTIONS | |
270 | - // Usage format: $.fn.colorbox.close(); | |
271 | - // Usage from within an iframe: parent.$.fn.colorbox.close(); | |
272 | - // **************** | |
273 | - | |
274 | - publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) { | |
275 | - var $this = this, autoOpen; | |
276 | - | |
277 | - if (!$this[0] && $this.selector) { // if a selector was given and it didn't match any elements, go ahead and exit. | |
278 | - return $this; | |
279 | - } | |
280 | - | |
281 | - options = options || {}; | |
282 | - | |
283 | - if (callback) { | |
284 | - options.onComplete = callback; | |
285 | - } | |
286 | - | |
287 | - if (!$this[0] || $this.selector === undefined) { // detects $.colorbox() and $.fn.colorbox() | |
288 | - $this = $('<a/>'); | |
289 | - options.open = true; // assume an immediate open | |
290 | - } | |
291 | - | |
292 | - $this.each(function () { | |
293 | - $.data(this, colorbox, $.extend({}, $.data(this, colorbox) || defaults, options)); | |
294 | - $(this).addClass(boxElement); | |
295 | - }); | |
296 | - | |
297 | - autoOpen = options.open; | |
298 | - | |
299 | - if ($.isFunction(autoOpen)) { | |
300 | - autoOpen = autoOpen.call($this); | |
301 | - } | |
302 | - | |
303 | - if (autoOpen) { | |
304 | - launch($this[0]); | |
305 | - } | |
306 | - | |
307 | - return $this; | |
308 | - }; | |
309 | - | |
310 | - // Initialize ColorBox: store common calculations, preload the interface graphics, append the html. | |
311 | - // This preps colorbox for a speedy open when clicked, and lightens the burdon on the browser by only | |
312 | - // having to run once, instead of each time colorbox is opened. | |
313 | - publicMethod.init = function () { | |
314 | - // Create & Append jQuery Objects | |
315 | - $window = $(window); | |
316 | - $box = $div().attr({id: colorbox, 'class': isIE ? prefix + (isIE6 ? 'IE6' : 'IE') : ''}); | |
317 | - $overlay = $div("Overlay", isIE6 ? 'position:absolute' : '').hide(); | |
318 | - | |
319 | - $wrap = $div("Wrapper"); | |
320 | - $content = $div("Content").append( | |
321 | - $loaded = $div("LoadedContent", 'width:0; height:0; overflow:hidden'), | |
322 | - $loadingOverlay = $div("LoadingOverlay").add($div("LoadingGraphic")), | |
323 | - $title = $div("Title"), | |
324 | - $current = $div("Current"), | |
325 | - $next = $div("Next"), | |
326 | - $prev = $div("Previous"), | |
327 | - $slideshow = $div("Slideshow").bind(event_open, slideshow), | |
328 | - $close = $div("Close") | |
329 | - ); | |
330 | - $wrap.append( // The 3x3 Grid that makes up ColorBox | |
331 | - $div().append( | |
332 | - $div("TopLeft"), | |
333 | - $topBorder = $div("TopCenter"), | |
334 | - $div("TopRight") | |
335 | - ), | |
336 | - $div(false, 'clear:left').append( | |
337 | - $leftBorder = $div("MiddleLeft"), | |
338 | - $content, | |
339 | - $rightBorder = $div("MiddleRight") | |
340 | - ), | |
341 | - $div(false, 'clear:left').append( | |
342 | - $div("BottomLeft"), | |
343 | - $bottomBorder = $div("BottomCenter"), | |
344 | - $div("BottomRight") | |
345 | - ) | |
346 | - ).children().children().css({'float': 'left'}); | |
347 | - | |
348 | - $loadingBay = $div(false, 'position:absolute; width:9999px; visibility:hidden; display:none'); | |
349 | - | |
350 | - $('body').prepend($overlay, $box.append($wrap, $loadingBay)); | |
351 | - | |
352 | - $content.children() | |
353 | - .hover(function () { | |
354 | - $(this).addClass('hover'); | |
355 | - }, function () { | |
356 | - $(this).removeClass('hover'); | |
357 | - }).addClass('hover'); | |
358 | - | |
359 | - // Cache values needed for size calculations | |
360 | - interfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height();//Subtraction needed for IE6 | |
361 | - interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width(); | |
362 | - loadedHeight = $loaded.outerHeight(true); | |
363 | - loadedWidth = $loaded.outerWidth(true); | |
364 | - | |
365 | - // Setting padding to remove the need to do size conversions during the animation step. | |
366 | - $box.css({"padding-bottom": interfaceHeight, "padding-right": interfaceWidth}).hide(); | |
367 | - | |
368 | - // Setup button events. | |
369 | - $next.click(function () { | |
370 | - publicMethod.next(); | |
371 | - }); | |
372 | - $prev.click(function () { | |
373 | - publicMethod.prev(); | |
374 | - }); | |
375 | - $close.click(function () { | |
376 | - publicMethod.close(); | |
377 | - }); | |
378 | - | |
379 | - $groupControls = $next.add($prev).add($current).add($slideshow); | |
380 | - | |
381 | - // Adding the 'hover' class allowed the browser to load the hover-state | |
382 | - // background graphics. The class can now can be removed. | |
383 | - $content.children().removeClass('hover'); | |
384 | - | |
385 | - $('.' + boxElement).live('click', function (e) { | |
386 | - // checks to see if it was a non-left mouse-click and for clicks modified with ctrl, shift, or alt. | |
387 | - if (!((e.button !== 0 && typeof e.button !== 'undefined') || e.ctrlKey || e.shiftKey || e.altKey)) { | |
388 | - e.preventDefault(); | |
389 | - launch(this); | |
390 | - } | |
391 | - }); | |
392 | - | |
393 | - $overlay.click(function () { | |
394 | - if (settings.overlayClose) { | |
395 | - publicMethod.close(); | |
396 | - } | |
397 | - }); | |
398 | - | |
399 | - // Set Navigation Key Bindings | |
400 | - $(document).bind('keydown.' + prefix, function (e) { | |
401 | - var key = e.keyCode; | |
402 | - if (open && settings.escKey && key === 27) { | |
403 | - e.preventDefault(); | |
404 | - publicMethod.close(); | |
405 | - } | |
406 | - if (open && settings.arrowKey && $related[1]) { | |
407 | - if (key === 37) { | |
408 | - e.preventDefault(); | |
409 | - $prev.click(); | |
410 | - } else if (key === 39) { | |
411 | - e.preventDefault(); | |
412 | - $next.click(); | |
413 | - } | |
414 | - } | |
415 | - }); | |
416 | - }; | |
417 | - | |
418 | - publicMethod.remove = function () { | |
419 | - $box.add($overlay).remove(); | |
420 | - $('.' + boxElement).die('click').removeData(colorbox).removeClass(boxElement); | |
421 | - }; | |
422 | - | |
423 | - publicMethod.position = function (speed, loadedCallback) { | |
424 | - var | |
425 | - animate_speed, | |
426 | - // keeps the top and left positions within the browser's viewport. | |
427 | - posTop = Math.max(document.documentElement.clientHeight - settings.h - loadedHeight - interfaceHeight, 0) / 2 + $window.scrollTop(), | |
428 | - posLeft = Math.max($window.width() - settings.w - loadedWidth - interfaceWidth, 0) / 2 + $window.scrollLeft(); | |
429 | - | |
430 | - // setting the speed to 0 to reduce the delay between same-sized content. | |
431 | - animate_speed = ($box.width() === settings.w + loadedWidth && $box.height() === settings.h + loadedHeight) ? 0 : speed; | |
432 | - | |
433 | - // this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly, | |
434 | - // but it has to be shrank down around the size of div#colorbox when it's done. If not, | |
435 | - // it can invoke an obscure IE bug when using iframes. | |
436 | - $wrap[0].style.width = $wrap[0].style.height = "9999px"; | |
437 | - | |
438 | - function modalDimensions(that) { | |
439 | - // loading overlay height has to be explicitly set for IE6. | |
440 | - $topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = that.style.width; | |
441 | - $loadingOverlay[0].style.height = $loadingOverlay[1].style.height = $content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = that.style.height; | |
442 | - } | |
443 | - | |
444 | - $box.dequeue().animate({width: settings.w + loadedWidth, height: settings.h + loadedHeight, top: posTop, left: posLeft}, { | |
445 | - duration: animate_speed, | |
446 | - complete: function () { | |
447 | - modalDimensions(this); | |
448 | - | |
449 | - active = false; | |
450 | - | |
451 | - // shrink the wrapper down to exactly the size of colorbox to avoid a bug in IE's iframe implementation. | |
452 | - $wrap[0].style.width = (settings.w + loadedWidth + interfaceWidth) + "px"; | |
453 | - $wrap[0].style.height = (settings.h + loadedHeight + interfaceHeight) + "px"; | |
454 | - | |
455 | - if (loadedCallback) { | |
456 | - loadedCallback(); | |
457 | - } | |
458 | - }, | |
459 | - step: function () { | |
460 | - modalDimensions(this); | |
461 | - } | |
462 | - }); | |
463 | - }; | |
464 | - | |
465 | - publicMethod.resize = function (options) { | |
466 | - if (open) { | |
467 | - options = options || {}; | |
468 | - | |
469 | - if (options.width) { | |
470 | - settings.w = setSize(options.width, 'x') - loadedWidth - interfaceWidth; | |
471 | - } | |
472 | - if (options.innerWidth) { | |
473 | - settings.w = setSize(options.innerWidth, 'x'); | |
474 | - } | |
475 | - $loaded.css({width: settings.w}); | |
476 | - | |
477 | - if (options.height) { | |
478 | - settings.h = setSize(options.height, 'y') - loadedHeight - interfaceHeight; | |
479 | - } | |
480 | - if (options.innerHeight) { | |
481 | - settings.h = setSize(options.innerHeight, 'y'); | |
482 | - } | |
483 | - if (!options.innerHeight && !options.height) { | |
484 | - var $child = $loaded.wrapInner("<div style='overflow:auto'></div>").children(); // temporary wrapper to get an accurate estimate of just how high the total content should be. | |
485 | - settings.h = $child.height(); | |
486 | - $child.replaceWith($child.children()); // ditch the temporary wrapper div used in height calculation | |
487 | - } | |
488 | - $loaded.css({height: settings.h}); | |
489 | - | |
490 | - publicMethod.position(settings.transition === "none" ? 0 : settings.speed); | |
491 | - } | |
492 | - }; | |
493 | - | |
494 | - publicMethod.prep = function (object) { | |
495 | - if (!open) { | |
496 | - return; | |
497 | - } | |
498 | - | |
499 | - var speed = settings.transition === "none" ? 0 : settings.speed; | |
500 | - | |
501 | - $window.unbind('resize.' + prefix); | |
502 | - $loaded.remove(); | |
503 | - $loaded = $div('LoadedContent').html(object); | |
504 | - | |
505 | - function getWidth() { | |
506 | - settings.w = settings.w || $loaded.width(); | |
507 | - settings.w = settings.mw && settings.mw < settings.w ? settings.mw : settings.w; | |
508 | - return settings.w; | |
509 | - } | |
510 | - function getHeight() { | |
511 | - settings.h = settings.h || $loaded.height(); | |
512 | - settings.h = settings.mh && settings.mh < settings.h ? settings.mh : settings.h; | |
513 | - return settings.h; | |
514 | - } | |
515 | - | |
516 | - $loaded.hide() | |
517 | - .appendTo($loadingBay.show())// content has to be appended to the DOM for accurate size calculations. | |
518 | - .css({width: getWidth(), overflow: settings.scrolling ? 'auto' : 'hidden'}) | |
519 | - .css({height: getHeight()})// sets the height independently from the width in case the new width influences the value of height. | |
520 | - .prependTo($content); | |
521 | - | |
522 | - $loadingBay.hide(); | |
523 | - | |
524 | - // floating the IMG removes the bottom line-height and fixed a problem where IE miscalculates the width of the parent element as 100% of the document width. | |
525 | - //$(photo).css({'float': 'none', marginLeft: 'auto', marginRight: 'auto'}); | |
526 | - | |
527 | - $(photo).css({'float': 'none'}); | |
528 | - | |
529 | - // Hides SELECT elements in IE6 because they would otherwise sit on top of the overlay. | |
530 | - if (isIE6) { | |
531 | - $('select').not($box.find('select')).filter(function () { | |
532 | - return this.style.visibility !== 'hidden'; | |
533 | - }).css({'visibility': 'hidden'}).one(event_cleanup, function () { | |
534 | - this.style.visibility = 'inherit'; | |
535 | - }); | |
536 | - } | |
537 | - | |
538 | - function setPosition(s) { | |
539 | - publicMethod.position(s, function () { | |
540 | - var prev, prevSrc, next, nextSrc, total = $related.length, iframe, complete; | |
541 | - | |
542 | - if (!open) { | |
543 | - return; | |
544 | - } | |
545 | - | |
546 | - complete = function () { | |
547 | - $loadingOverlay.hide(); | |
548 | - trigger(event_complete, settings.onComplete); | |
549 | - }; | |
550 | - | |
551 | - if (isIE) { | |
552 | - //This fadeIn helps the bicubic resampling to kick-in. | |
553 | - if (photo) { | |
554 | - $loaded.fadeIn(100); | |
555 | - } | |
556 | - } | |
557 | - | |
558 | - $title.html(settings.title).add($loaded).show(); | |
559 | - | |
560 | - if (total > 1) { // handle grouping | |
561 | - if (typeof settings.current === "string") { | |
562 | - $current.html(settings.current.replace(/\{current\}/, index + 1).replace(/\{total\}/, total)).show(); | |
563 | - } | |
564 | - | |
565 | - $next[(settings.loop || index < total - 1) ? "show" : "hide"]().html(settings.next); | |
566 | - $prev[(settings.loop || index) ? "show" : "hide"]().html(settings.previous); | |
567 | - | |
568 | - prev = index ? $related[index - 1] : $related[total - 1]; | |
569 | - next = index < total - 1 ? $related[index + 1] : $related[0]; | |
570 | - | |
571 | - if (settings.slideshow) { | |
572 | - $slideshow.show(); | |
573 | - } | |
574 | - | |
575 | - // Preloads images within a rel group | |
576 | - if (settings.preloading) { | |
577 | - nextSrc = $.data(next, colorbox).href || next.href; | |
578 | - prevSrc = $.data(prev, colorbox).href || prev.href; | |
579 | - | |
580 | - nextSrc = $.isFunction(nextSrc) ? nextSrc.call(next) : nextSrc; | |
581 | - prevSrc = $.isFunction(prevSrc) ? prevSrc.call(prev) : prevSrc; | |
582 | - | |
583 | - if (isImage(nextSrc)) { | |
584 | - $('<img/>')[0].src = nextSrc; | |
585 | - } | |
586 | - | |
587 | - if (isImage(prevSrc)) { | |
588 | - $('<img/>')[0].src = prevSrc; | |
589 | - } | |
590 | - } | |
591 | - } else { | |
592 | - $groupControls.hide(); | |
593 | - } | |
594 | - | |
595 | - if (settings.iframe) { | |
596 | - iframe = $('<iframe/>').addClass(prefix + 'Iframe')[0]; | |
597 | - | |
598 | - if (settings.fastIframe) { | |
599 | - complete(); | |
600 | - } else { | |
601 | - $(iframe).load(complete); | |
602 | - } | |
603 | - iframe.name = prefix + (+new Date()); | |
604 | - iframe.src = settings.href; | |
605 | - | |
606 | - if (!settings.scrolling) { | |
607 | - iframe.scrolling = "no"; | |
608 | - } | |
609 | - | |
610 | - if (isIE) { | |
611 | - iframe.frameBorder=0; | |
612 | - iframe.allowTransparency = "true"; | |
613 | - } | |
614 | - | |
615 | - $(iframe).appendTo($loaded).one(event_purge, function () { | |
616 | - iframe.src = "//about:blank"; | |
617 | - }); | |
618 | - } else { | |
619 | - complete(); | |
620 | - } | |
621 | - | |
622 | - if (settings.transition === 'fade') { | |
623 | - $box.fadeTo(speed, 1, function () { | |
624 | - $box[0].style.filter = ""; | |
625 | - }); | |
626 | - } else { | |
627 | - $box[0].style.filter = ""; | |
628 | - } | |
629 | - | |
630 | - $window.bind('resize.' + prefix, function () { | |
631 | - publicMethod.position(0); | |
632 | - }); | |
633 | - }); | |
634 | - } | |
635 | - | |
636 | - if (settings.transition === 'fade') { | |
637 | - $box.fadeTo(speed, 0, function () { | |
638 | - setPosition(0); | |
639 | - }); | |
640 | - } else { | |
641 | - setPosition(speed); | |
642 | - } | |
643 | - }; | |
644 | - | |
645 | - publicMethod.load = function (launched) { | |
646 | - var href, setResize, prep = publicMethod.prep; | |
647 | - | |
648 | - active = true; | |
649 | - | |
650 | - photo = false; | |
651 | - | |
652 | - element = $related[index]; | |
653 | - | |
654 | - if (!launched) { | |
655 | - process($.extend(settings, $.data(element, colorbox))); | |
656 | - } | |
657 | - | |
658 | - trigger(event_purge); | |
659 | - | |
660 | - trigger(event_load, settings.onLoad); | |
661 | - | |
662 | - settings.h = settings.height ? | |
663 | - setSize(settings.height, 'y') - loadedHeight - interfaceHeight : | |
664 | - settings.innerHeight && setSize(settings.innerHeight, 'y'); | |
665 | - | |
666 | - settings.w = settings.width ? | |
667 | - setSize(settings.width, 'x') - loadedWidth - interfaceWidth : | |
668 | - settings.innerWidth && setSize(settings.innerWidth, 'x'); | |
669 | - | |
670 | - // Sets the minimum dimensions for use in image scaling | |
671 | - settings.mw = settings.w; | |
672 | - settings.mh = settings.h; | |
673 | - | |
674 | - // Re-evaluate the minimum width and height based on maxWidth and maxHeight values. | |
675 | - // If the width or height exceed the maxWidth or maxHeight, use the maximum values instead. | |
676 | - if (settings.maxWidth) { | |
677 | - settings.mw = setSize(settings.maxWidth, 'x') - loadedWidth - interfaceWidth; | |
678 | - settings.mw = settings.w && settings.w < settings.mw ? settings.w : settings.mw; | |
679 | - } | |
680 | - if (settings.maxHeight) { | |
681 | - settings.mh = setSize(settings.maxHeight, 'y') - loadedHeight - interfaceHeight; | |
682 | - settings.mh = settings.h && settings.h < settings.mh ? settings.h : settings.mh; | |
683 | - } | |
684 | - | |
685 | - href = settings.href; | |
686 | - | |
687 | - $loadingOverlay.show(); | |
688 | - | |
689 | - if (settings.inline) { | |
690 | - // Inserts an empty placeholder where inline content is being pulled from. | |
691 | - // An event is bound to put inline content back when ColorBox closes or loads new content. | |
692 | - $div().hide().insertBefore($(href)[0]).one(event_purge, function () { | |
693 | - $(this).replaceWith($loaded.children()); | |
694 | - }); | |
695 | - prep($(href)); | |
696 | - } else if (settings.iframe) { | |
697 | - // IFrame element won't be added to the DOM until it is ready to be displayed, | |
698 | - // to avoid problems with DOM-ready JS that might be trying to run in that iframe. | |
699 | - prep(" "); | |
700 | - } else if (settings.html) { | |
701 | - prep(settings.html); | |
702 | - } else if (isImage(href)) { | |
703 | - $(photo = new Image()) | |
704 | - .addClass(prefix + 'Photo') | |
705 | - .error(function () { | |
706 | - settings.title = false; | |
707 | - prep($div('Error').text('This image could not be loaded')); | |
708 | - }) | |
709 | - .load(function () { | |
710 | - var percent; | |
711 | - photo.onload = null; //stops animated gifs from firing the onload repeatedly. | |
712 | - | |
713 | - if (settings.scalePhotos) { | |
714 | - setResize = function () { | |
715 | - photo.height -= photo.height * percent; | |
716 | - photo.width -= photo.width * percent; | |
717 | - }; | |
718 | - if (settings.mw && photo.width > settings.mw) { | |
719 | - percent = (photo.width - settings.mw) / photo.width; | |
720 | - setResize(); | |
721 | - } | |
722 | - if (settings.mh && photo.height > settings.mh) { | |
723 | - percent = (photo.height - settings.mh) / photo.height; | |
724 | - setResize(); | |
725 | - } | |
726 | - } | |
727 | - | |
728 | - if (settings.h) { | |
729 | - photo.style.marginTop = Math.max(settings.h - photo.height, 0) / 2 + 'px'; | |
730 | - } | |
731 | - | |
732 | - if ($related[1] && (index < $related.length - 1 || settings.loop)) { | |
733 | - photo.style.cursor = 'pointer'; | |
734 | - photo.onclick = function () { | |
735 | - publicMethod.next(); | |
736 | - }; | |
737 | - } | |
738 | - | |
739 | - if (isIE) { | |
740 | - photo.style.msInterpolationMode = 'bicubic'; | |
741 | - } | |
742 | - | |
743 | - setTimeout(function () { // A pause because Chrome will sometimes report a 0 by 0 size otherwise. | |
744 | - prep(photo); | |
745 | - }, 1); | |
746 | - }); | |
747 | - | |
748 | - setTimeout(function () { // A pause because Opera 10.6+ will sometimes not run the onload function otherwise. | |
749 | - photo.src = href; | |
750 | - }, 1); | |
751 | - } else if (href) { | |
752 | - $loadingBay.load(href, function (data, status, xhr) { | |
753 | - prep(status === 'error' ? $div('Error').text('Request unsuccessful: ' + xhr.statusText) : $(this).contents()); | |
754 | - }); | |
755 | - } | |
756 | - }; | |
757 | - | |
758 | - // Navigates to the next page/image in a set. | |
759 | - publicMethod.next = function () { | |
760 | - if (!active && $related[1] && (index < $related.length - 1 || settings.loop)) { | |
761 | - index = index < $related.length - 1 ? index + 1 : 0; | |
762 | - publicMethod.load(); | |
763 | - } | |
764 | - }; | |
765 | - | |
766 | - publicMethod.prev = function () { | |
767 | - if (!active && $related[1] && (index || settings.loop)) { | |
768 | - index = index ? index - 1 : $related.length - 1; | |
769 | - publicMethod.load(); | |
770 | - } | |
771 | - }; | |
772 | - | |
773 | - // Note: to use this within an iframe use the following format: parent.$.fn.colorbox.close(); | |
774 | - publicMethod.close = function () { | |
775 | - if (open && !closing) { | |
776 | - | |
777 | - closing = true; | |
778 | - | |
779 | - open = false; | |
780 | - | |
781 | - trigger(event_cleanup, settings.onCleanup); | |
782 | - | |
783 | - $window.unbind('.' + prefix + ' .' + event_ie6); | |
784 | - | |
785 | - $overlay.fadeTo(200, 0); | |
786 | - | |
787 | - $box.stop().fadeTo(300, 0, function () { | |
788 | - | |
789 | - $box.add($overlay).css({'opacity': 1, cursor: 'auto'}).hide(); | |
790 | - | |
791 | - trigger(event_purge); | |
792 | - | |
793 | - $loaded.remove(); | |
794 | - | |
795 | - setTimeout(function () { | |
796 | - closing = false; | |
797 | - trigger(event_closed, settings.onClosed); | |
798 | - }, 1); | |
799 | - }); | |
800 | - } | |
801 | - }; | |
802 | - | |
803 | - // A method for fetching the current element ColorBox is referencing. | |
804 | - // returns a jQuery object. | |
805 | - publicMethod.element = function () { | |
806 | - return $(element); | |
807 | - }; | |
808 | - | |
809 | - publicMethod.settings = defaults; | |
810 | - | |
811 | - // Initializes ColorBox when the DOM has loaded | |
812 | - $(publicMethod.init); | |
813 | - | |
814 | -}(jQuery, document, this)); | |
815 | 0 | \ No newline at end of file |
public/javascripts/comment_form.js
... | ... | @@ -53,7 +53,7 @@ function save_comment(button) { |
53 | 53 | //Comment of reply |
54 | 54 | $('#'+ data.render_target).replaceWith(data.html); |
55 | 55 | $('#' + data.render_target).effect("highlight", {}, 3000); |
56 | - $.colorbox.close(); | |
56 | + noosfero.modal.close(); | |
57 | 57 | increment_comment_count(comment_div); |
58 | 58 | } else { |
59 | 59 | //New comment of article |
... | ... | @@ -64,7 +64,7 @@ function save_comment(button) { |
64 | 64 | }); |
65 | 65 | |
66 | 66 | page_comment_form.find('.errorExplanation').remove(); |
67 | - $.colorbox.close(); | |
67 | + noosfero.modal.close(); | |
68 | 68 | increment_comment_count(comment_div); |
69 | 69 | } |
70 | 70 | ... | ... |
... | ... | @@ -0,0 +1,7 @@ |
1 | +/*! | |
2 | + Colorbox v1.4.36 - 2014-02-01 | |
3 | + jQuery lightbox and modal window plugin | |
4 | + (c) 2014 Jack Moore - http://www.jacklmoore.com/colorbox | |
5 | + license: http://www.opensource.org/licenses/mit-license.php | |
6 | +*/ | |
7 | +(function(e,t,i){function o(i,o,n){var r=t.createElement(i);return o&&(r.id=Z+o),n&&(r.style.cssText=n),e(r)}function n(){return i.innerHeight?i.innerHeight:e(i).height()}function r(e){var t=k.length,i=(z+e)%t;return 0>i?t+i:i}function h(e,t){return Math.round((/%/.test(e)?("x"===t?E.width():n())/100:1)*parseInt(e,10))}function l(e,t){return e.photo||e.photoRegex.test(t)}function s(e,t){return e.retinaUrl&&i.devicePixelRatio>1?t.replace(e.photoRegex,e.retinaSuffix):t}function a(e){"contains"in g[0]&&!g[0].contains(e.target)&&(e.stopPropagation(),g.focus())}function d(){var t,i=e.data(N,Y);null==i?(B=e.extend({},X),console&&console.log&&console.log("Error: cboxElement missing settings object")):B=e.extend({},i);for(t in B)e.isFunction(B[t])&&"on"!==t.slice(0,2)&&(B[t]=B[t].call(N));B.rel=B.rel||N.rel||e(N).data("rel")||"nofollow",B.href=B.href||e(N).attr("href"),B.title=B.title||N.title,"string"==typeof B.href&&(B.href=e.trim(B.href))}function c(i,o){e(t).trigger(i),lt.triggerHandler(i),e.isFunction(o)&&o.call(N)}function u(i){q||(N=i,d(),k=e(N),z=0,"nofollow"!==B.rel&&(k=e("."+et).filter(function(){var t,i=e.data(this,Y);return i&&(t=e(this).data("rel")||i.rel||this.rel),t===B.rel}),z=k.index(N),-1===z&&(k=k.add(N),z=k.length-1)),w.css({opacity:parseFloat(B.opacity),cursor:B.overlayClose?"pointer":"auto",visibility:"visible"}).show(),J&&g.add(w).removeClass(J),B.className&&g.add(w).addClass(B.className),J=B.className,B.closeButton?K.html(B.close).appendTo(y):K.appendTo("<div/>"),U||(U=$=!0,g.css({visibility:"hidden",display:"block"}),H=o(st,"LoadedContent","width:0; height:0; overflow:hidden"),y.css({width:"",height:""}).append(H),O=x.height()+C.height()+y.outerHeight(!0)-y.height(),_=b.width()+T.width()+y.outerWidth(!0)-y.width(),D=H.outerHeight(!0),A=H.outerWidth(!0),B.w=h(B.initialWidth,"x"),B.h=h(B.initialHeight,"y"),H.css({width:"",height:B.h}),Q.position(),c(tt,B.onOpen),P.add(L).hide(),g.focus(),B.trapFocus&&t.addEventListener&&(t.addEventListener("focus",a,!0),lt.one(rt,function(){t.removeEventListener("focus",a,!0)})),B.returnFocus&<.one(rt,function(){e(N).focus()})),m())}function f(){!g&&t.body&&(V=!1,E=e(i),g=o(st).attr({id:Y,"class":e.support.opacity===!1?Z+"IE":"",role:"dialog",tabindex:"-1"}).hide(),w=o(st,"Overlay").hide(),F=e([o(st,"LoadingOverlay")[0],o(st,"LoadingGraphic")[0]]),v=o(st,"Wrapper"),y=o(st,"Content").append(L=o(st,"Title"),S=o(st,"Current"),I=e('<button type="button"/>').attr({id:Z+"Previous"}),R=e('<button type="button"/>').attr({id:Z+"Next"}),M=o("button","Slideshow"),F),K=e('<button type="button"/>').attr({id:Z+"Close"}),v.append(o(st).append(o(st,"TopLeft"),x=o(st,"TopCenter"),o(st,"TopRight")),o(st,!1,"clear:left").append(b=o(st,"MiddleLeft"),y,T=o(st,"MiddleRight")),o(st,!1,"clear:left").append(o(st,"BottomLeft"),C=o(st,"BottomCenter"),o(st,"BottomRight"))).find("div div").css({"float":"left"}),W=o(st,!1,"position:absolute; width:9999px; visibility:hidden; display:none; max-width:none;"),P=R.add(I).add(S).add(M),e(t.body).append(w,g.append(v,W)))}function p(){function i(e){e.which>1||e.shiftKey||e.altKey||e.metaKey||e.ctrlKey||(e.preventDefault(),u(this))}return g?(V||(V=!0,R.click(function(){Q.next()}),I.click(function(){Q.prev()}),K.click(function(){Q.close()}),w.click(function(){B.overlayClose&&Q.close()}),e(t).bind("keydown."+Z,function(e){var t=e.keyCode;U&&B.escKey&&27===t&&(e.preventDefault(),Q.close()),U&&B.arrowKey&&k[1]&&!e.altKey&&(37===t?(e.preventDefault(),I.click()):39===t&&(e.preventDefault(),R.click()))}),e.isFunction(e.fn.on)?e(t).on("click."+Z,"."+et,i):e("."+et).live("click."+Z,i)),!0):!1}function m(){var n,r,a,u=Q.prep,f=++at;$=!0,j=!1,N=k[z],d(),c(ht),c(it,B.onLoad),B.h=B.height?h(B.height,"y")-D-O:B.innerHeight&&h(B.innerHeight,"y"),B.w=B.width?h(B.width,"x")-A-_:B.innerWidth&&h(B.innerWidth,"x"),B.mw=B.w,B.mh=B.h,B.maxWidth&&(B.mw=h(B.maxWidth,"x")-A-_,B.mw=B.w&&B.w<B.mw?B.w:B.mw),B.maxHeight&&(B.mh=h(B.maxHeight,"y")-D-O,B.mh=B.h&&B.h<B.mh?B.h:B.mh),n=B.href,G=setTimeout(function(){F.show()},100),B.inline?(a=o(st).hide().insertBefore(e(n)[0]),lt.one(ht,function(){a.replaceWith(H.children())}),u(e(n))):B.iframe?u(" "):B.html?u(B.html):l(B,n)?(n=s(B,n),j=t.createElement("img"),e(j).addClass(Z+"Photo").bind("error",function(){B.title=!1,u(o(st,"Error").html(B.imgError))}).one("load",function(){var t;f===at&&(e.each(["alt","longdesc","aria-describedby"],function(t,i){var o=e(N).attr(i)||e(N).attr("data-"+i);o&&j.setAttribute(i,o)}),B.retinaImage&&i.devicePixelRatio>1&&(j.height=j.height/i.devicePixelRatio,j.width=j.width/i.devicePixelRatio),B.scalePhotos&&(r=function(){j.height-=j.height*t,j.width-=j.width*t},B.mw&&j.width>B.mw&&(t=(j.width-B.mw)/j.width,r()),B.mh&&j.height>B.mh&&(t=(j.height-B.mh)/j.height,r())),B.h&&(j.style.marginTop=Math.max(B.mh-j.height,0)/2+"px"),k[1]&&(B.loop||k[z+1])&&(j.style.cursor="pointer",j.onclick=function(){Q.next()}),j.style.width=j.width+"px",j.style.height=j.height+"px",setTimeout(function(){u(j)},1))}),setTimeout(function(){j.src=n},1)):n&&W.load(n,B.data,function(t,i){f===at&&u("error"===i?o(st,"Error").html(B.xhrError):e(this).contents())})}var w,g,v,y,x,b,T,C,k,E,H,W,F,L,S,M,R,I,K,P,B,O,_,D,A,N,z,j,U,$,q,G,Q,J,V,X={html:!1,photo:!1,iframe:!1,inline:!1,transition:"elastic",speed:300,fadeOut:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,href:!1,title:!1,rel:!1,opacity:.9,preloading:!0,className:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:void 0,closeButton:!0,fastIframe:!0,open:!1,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",photoRegex:/\.(gif|png|jp(e|g|eg)|bmp|ico|webp)((#|\?).*)?$/i,retinaImage:!1,retinaUrl:!1,retinaSuffix:"@2x.$1",current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",returnFocus:!0,trapFocus:!0,onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1},Y="colorbox",Z="cbox",et=Z+"Element",tt=Z+"_open",it=Z+"_load",ot=Z+"_complete",nt=Z+"_cleanup",rt=Z+"_closed",ht=Z+"_purge",lt=e("<a/>"),st="div",at=0,dt={},ct=function(){function e(){clearTimeout(h)}function t(){(B.loop||k[z+1])&&(e(),h=setTimeout(Q.next,B.slideshowSpeed))}function i(){M.html(B.slideshowStop).unbind(s).one(s,o),lt.bind(ot,t).bind(it,e),g.removeClass(l+"off").addClass(l+"on")}function o(){e(),lt.unbind(ot,t).unbind(it,e),M.html(B.slideshowStart).unbind(s).one(s,function(){Q.next(),i()}),g.removeClass(l+"on").addClass(l+"off")}function n(){r=!1,M.hide(),e(),lt.unbind(ot,t).unbind(it,e),g.removeClass(l+"off "+l+"on")}var r,h,l=Z+"Slideshow_",s="click."+Z;return function(){r?B.slideshow||(lt.unbind(nt,n),n()):B.slideshow&&k[1]&&(r=!0,lt.one(nt,n),B.slideshowAuto?i():o(),M.show())}}();e.colorbox||(e(f),Q=e.fn[Y]=e[Y]=function(t,i){var o=this;if(t=t||{},f(),p()){if(e.isFunction(o))o=e("<a/>"),t.open=!0;else if(!o[0])return o;i&&(t.onComplete=i),o.each(function(){e.data(this,Y,e.extend({},e.data(this,Y)||X,t))}).addClass(et),(e.isFunction(t.open)&&t.open.call(o)||t.open)&&u(o[0])}return o},Q.position=function(t,i){function o(){x[0].style.width=C[0].style.width=y[0].style.width=parseInt(g[0].style.width,10)-_+"px",y[0].style.height=b[0].style.height=T[0].style.height=parseInt(g[0].style.height,10)-O+"px"}var r,l,s,a=0,d=0,c=g.offset();if(E.unbind("resize."+Z),g.css({top:-9e4,left:-9e4}),l=E.scrollTop(),s=E.scrollLeft(),B.fixed?(c.top-=l,c.left-=s,g.css({position:"fixed"})):(a=l,d=s,g.css({position:"absolute"})),d+=B.right!==!1?Math.max(E.width()-B.w-A-_-h(B.right,"x"),0):B.left!==!1?h(B.left,"x"):Math.round(Math.max(E.width()-B.w-A-_,0)/2),a+=B.bottom!==!1?Math.max(n()-B.h-D-O-h(B.bottom,"y"),0):B.top!==!1?h(B.top,"y"):Math.round(Math.max(n()-B.h-D-O,0)/2),g.css({top:c.top,left:c.left,visibility:"visible"}),v[0].style.width=v[0].style.height="9999px",r={width:B.w+A+_,height:B.h+D+O,top:a,left:d},t){var u=0;e.each(r,function(e){return r[e]!==dt[e]?(u=t,void 0):void 0}),t=u}dt=r,t||g.css(r),g.dequeue().animate(r,{duration:t||0,complete:function(){o(),$=!1,v[0].style.width=B.w+A+_+"px",v[0].style.height=B.h+D+O+"px",B.reposition&&setTimeout(function(){E.bind("resize."+Z,Q.position)},1),i&&i()},step:o})},Q.resize=function(e){var t;U&&(e=e||{},e.width&&(B.w=h(e.width,"x")-A-_),e.innerWidth&&(B.w=h(e.innerWidth,"x")),H.css({width:B.w}),e.height&&(B.h=h(e.height,"y")-D-O),e.innerHeight&&(B.h=h(e.innerHeight,"y")),e.innerHeight||e.height||(t=H.scrollTop(),H.css({height:"auto"}),B.h=H.height()),H.css({height:B.h}),t&&H.scrollTop(t),Q.position("none"===B.transition?0:B.speed))},Q.prep=function(i){function n(){return B.w=B.w||H.width(),B.w=B.mw&&B.mw<B.w?B.mw:B.w,B.w}function h(){return B.h=B.h||H.height(),B.h=B.mh&&B.mh<B.h?B.mh:B.h,B.h}if(U){var a,d="none"===B.transition?0:B.speed;H.empty().remove(),H=o(st,"LoadedContent").append(i),H.hide().appendTo(W.show()).css({width:n(),overflow:B.scrolling?"auto":"hidden"}).css({height:h()}).prependTo(y),W.hide(),e(j).css({"float":"none"}),a=function(){function i(){e.support.opacity===!1&&g[0].style.removeAttribute("filter")}var n,h,a=k.length,u="frameBorder",f="allowTransparency";U&&(h=function(){clearTimeout(G),F.hide(),c(ot,B.onComplete)},L.html(B.title).add(H).show(),a>1?("string"==typeof B.current&&S.html(B.current.replace("{current}",z+1).replace("{total}",a)).show(),R[B.loop||a-1>z?"show":"hide"]().html(B.next),I[B.loop||z?"show":"hide"]().html(B.previous),ct(),B.preloading&&e.each([r(-1),r(1)],function(){var i,o,n=k[this],r=e.data(n,Y);r&&r.href?(i=r.href,e.isFunction(i)&&(i=i.call(n))):i=e(n).attr("href"),i&&l(r,i)&&(i=s(r,i),o=t.createElement("img"),o.src=i)})):P.hide(),B.iframe?(n=o("iframe")[0],u in n&&(n[u]=0),f in n&&(n[f]="true"),B.scrolling||(n.scrolling="no"),e(n).attr({src:B.href,name:(new Date).getTime(),"class":Z+"Iframe",allowFullScreen:!0,webkitAllowFullScreen:!0,mozallowfullscreen:!0}).one("load",h).appendTo(H),lt.one(ht,function(){n.src="//about:blank"}),B.fastIframe&&e(n).trigger("load")):h(),"fade"===B.transition?g.fadeTo(d,1,i):i())},"fade"===B.transition?g.fadeTo(d,0,function(){Q.position(0,a)}):Q.position(d,a)}},Q.next=function(){!$&&k[1]&&(B.loop||k[z+1])&&(z=r(1),u(k[z]))},Q.prev=function(){!$&&k[1]&&(B.loop||z)&&(z=r(-1),u(k[z]))},Q.close=function(){U&&!q&&(q=!0,U=!1,c(nt,B.onCleanup),E.unbind("."+Z),w.fadeTo(B.fadeOut||0,0),g.stop().fadeTo(B.fadeOut||0,0,function(){g.add(w).css({opacity:1,cursor:"auto"}).hide(),c(ht),H.empty().remove(),setTimeout(function(){q=!1,c(rt,B.onClosed)},1)}))},Q.remove=function(){g&&(g.stop(),e.colorbox.close(),g.stop().remove(),w.remove(),q=!1,g=null,e("."+et).removeData(Y).removeClass(et),e(t).unbind("click."+Z))},Q.element=function(){return e(N)},Q.settings=X)})(jQuery,document,window); | |
0 | 8 | \ No newline at end of file | ... | ... |
public/javascripts/lightbox.js
... | ... | @@ -1,232 +0,0 @@ |
1 | -/* | |
2 | -Created By: Chris Campbell | |
3 | -Website: http://particletree.com | |
4 | -Date: 2/1/2006 | |
5 | - | |
6 | -Inspired by the lightbox implementation found at http://www.huddletogether.com/projects/lightbox/ | |
7 | -*/ | |
8 | - | |
9 | -/*-------------------------------GLOBAL VARIABLES------------------------------------*/ | |
10 | - | |
11 | -var detect = navigator.userAgent.toLowerCase(); | |
12 | -var OS,browser,version,total,thestring; | |
13 | - | |
14 | -/*-----------------------------------------------------------------------------------------------*/ | |
15 | - | |
16 | -//Browser detect script origionally created by Peter Paul Koch at http://www.quirksmode.org/ | |
17 | - | |
18 | -function getBrowserInfo() { | |
19 | - if (checkIt('konqueror')) { | |
20 | - browser = "Konqueror"; | |
21 | - OS = "Linux"; | |
22 | - } | |
23 | - else if (checkIt('safari')) browser = "Safari" | |
24 | - else if (checkIt('omniweb')) browser = "OmniWeb" | |
25 | - else if (checkIt('opera')) browser = "Opera" | |
26 | - else if (checkIt('webtv')) browser = "WebTV"; | |
27 | - else if (checkIt('icab')) browser = "iCab" | |
28 | - else if (checkIt('msie')) browser = "Internet Explorer" | |
29 | - else if (!checkIt('compatible')) { | |
30 | - browser = "Netscape Navigator" | |
31 | - version = detect.charAt(8); | |
32 | - } | |
33 | - else browser = "An unknown browser"; | |
34 | - | |
35 | - if (!version) version = detect.charAt(place + thestring.length); | |
36 | - | |
37 | - if (!OS) { | |
38 | - if (checkIt('linux')) OS = "Linux"; | |
39 | - else if (checkIt('x11')) OS = "Unix"; | |
40 | - else if (checkIt('mac')) OS = "Mac" | |
41 | - else if (checkIt('win')) OS = "Windows" | |
42 | - else OS = "an unknown operating system"; | |
43 | - } | |
44 | -} | |
45 | - | |
46 | -function checkIt(string) { | |
47 | - place = detect.indexOf(string) + 1; | |
48 | - thestring = string; | |
49 | - return place; | |
50 | -} | |
51 | - | |
52 | -/*-----------------------------------------------------------------------------------------------*/ | |
53 | - | |
54 | -Event.observe(window, 'load', getBrowserInfo, false); | |
55 | - | |
56 | -var lightbox = Class.create(); | |
57 | - | |
58 | -lightbox.prototype = { | |
59 | - | |
60 | - yPos : 0, | |
61 | - xPos : 0, | |
62 | - | |
63 | - initialize: function(ctrl) { | |
64 | - this.content = ctrl.href; | |
65 | - if (ctrl.id != '') { | |
66 | - this.lightbox_className = ctrl.id; | |
67 | - } | |
68 | - ctrl.onclick = function(){return false;}; | |
69 | - ctrl.lightbox = this; | |
70 | - }, | |
71 | - | |
72 | - // Turn everything on - mainly the IE fixes | |
73 | - activate: function(){ | |
74 | - if (browser == 'Internet Explorer'){ | |
75 | - this.getScroll(); | |
76 | - this.prepareIE('100%', 'hidden'); | |
77 | - this.setScroll(0,0); | |
78 | - this.hideSelects('hidden'); | |
79 | - } | |
80 | - this.hideObjectsAndEmbeds('hidden'); | |
81 | - this.displayLightbox("block"); | |
82 | - }, | |
83 | - | |
84 | - // Ie requires height to 100% and overflow hidden or else you can scroll down past the lightbox | |
85 | - prepareIE: function(height, overflow){ | |
86 | - bod = document.getElementsByTagName('body')[0]; | |
87 | - bod.style.height = height; | |
88 | - bod.style.overflow = overflow; | |
89 | - | |
90 | - htm = document.getElementsByTagName('html')[0]; | |
91 | - htm.style.height = height; | |
92 | - htm.style.overflow = overflow; | |
93 | - }, | |
94 | - | |
95 | - // In IE, select elements hover on top of the lightbox | |
96 | - hideSelects: function(visibility){ | |
97 | - selects = document.getElementsByTagName('select'); | |
98 | - for(i = 0; i < selects.length; i++) { | |
99 | - selects[i].style.visibility = visibility; | |
100 | - } | |
101 | - }, | |
102 | - | |
103 | - // In FF, objects and embeds elements hover on top of the lightbox | |
104 | - hideObjectsAndEmbeds: function(visibility){ | |
105 | - var f = function(collection) { | |
106 | - for(i = 0; i < collection.length; i++) { | |
107 | - if (collection[i].style) { | |
108 | - collection[i].style.visibility = visibility; | |
109 | - } | |
110 | - } | |
111 | - }; | |
112 | - f(document.getElementsByTagName('object')); | |
113 | - f(document.getElementsByTagName('embed')); | |
114 | - }, | |
115 | - | |
116 | - // Taken from lightbox implementation found at http://www.huddletogether.com/projects/lightbox/ | |
117 | - getScroll: function(){ | |
118 | - if (self.pageYOffset) { | |
119 | - this.yPos = self.pageYOffset; | |
120 | - } else if (document.documentElement && document.documentElement.scrollTop){ | |
121 | - this.yPos = document.documentElement.scrollTop; | |
122 | - } else if (document.body) { | |
123 | - this.yPos = document.body.scrollTop; | |
124 | - } | |
125 | - }, | |
126 | - | |
127 | - setScroll: function(x, y){ | |
128 | - window.scrollTo(x, y); | |
129 | - }, | |
130 | - | |
131 | - displayLightbox: function(display){ | |
132 | - $('overlay').style.display = display; | |
133 | - $('lightbox').style.display = display; | |
134 | - if(display != 'none') this.loadInfo(); | |
135 | - }, | |
136 | - | |
137 | - // Begin Ajax request based off of the href of the clicked linked | |
138 | - loadInfo: function() { | |
139 | - var myAjax = new Ajax.Request( | |
140 | - this.content, | |
141 | - {method: 'post', parameters: "", onComplete: this.processInfo.bindAsEventListener(this)} | |
142 | - ); | |
143 | - | |
144 | - }, | |
145 | - | |
146 | - // Display Ajax response | |
147 | - processInfo: function(response){ | |
148 | - info = "<div id='lbContent'><div id='lbBottomBG'><div id='lbTopBG'>" + response.responseText + "</div></div></div>"; | |
149 | - new Insertion.Before($('lbLoadMessage'), info) | |
150 | - if (this.lightbox_className) { | |
151 | - $('lightbox').className = "done " + this.lightbox_className; | |
152 | - } else { | |
153 | - $('lightbox').className = "done"; | |
154 | - } | |
155 | - this.actions(); | |
156 | - }, | |
157 | - | |
158 | - // Search through new links within the lightbox, and attach click event | |
159 | - actions: function(){ | |
160 | - lbActions = document.getElementsByClassName('lbAction'); | |
161 | - | |
162 | - for(i = 0; i < lbActions.length; i++) { | |
163 | - Event.observe(lbActions[i], 'click', this[lbActions[i].rel].bindAsEventListener(this), false); | |
164 | - lbActions[i].onclick = function(){return false;}; | |
165 | - } | |
166 | - | |
167 | - }, | |
168 | - | |
169 | - // Example of creating your own functionality once lightbox is initiated | |
170 | - insert: function(e){ | |
171 | - link = Event.element(e).parentNode; | |
172 | - Element.remove($('lbContent')); | |
173 | - | |
174 | - var myAjax = new Ajax.Request( | |
175 | - link.href, | |
176 | - {method: 'post', parameters: "", onComplete: this.processInfo.bindAsEventListener(this)} | |
177 | - ); | |
178 | - | |
179 | - }, | |
180 | - | |
181 | - // Example of creating your own functionality once lightbox is initiated | |
182 | - deactivate: function(){ | |
183 | - Element.remove($('lbContent')); | |
184 | - | |
185 | - if (browser == "Internet Explorer"){ | |
186 | - this.setScroll(0,this.yPos); | |
187 | - this.prepareIE("auto", "auto"); | |
188 | - this.hideSelects("visible"); | |
189 | - } | |
190 | - this.hideObjectsAndEmbeds("visible"); | |
191 | - this.displayLightbox("none"); | |
192 | - } | |
193 | -} | |
194 | - | |
195 | -/*-----------------------------------------------------------------------------------------------*/ | |
196 | - | |
197 | -jQuery('.lbOn').live('click', function(event) { | |
198 | - if (jQuery('#lbLoadMessage').length == 0) | |
199 | - addLightboxMarkup(); | |
200 | - if (this.lightbox == undefined) | |
201 | - valid = new lightbox(this); | |
202 | - else { | |
203 | - removeLightboxMarkup(); | |
204 | - addLightboxMarkup(); | |
205 | - } | |
206 | - | |
207 | - this.lightbox.activate(); | |
208 | - | |
209 | - event.preventDefault(); | |
210 | - return false; | |
211 | -}); | |
212 | - | |
213 | -// Add in markup necessary to make this work. Basically two divs: | |
214 | -// Overlay holds the shadow | |
215 | -// Lightbox is the centered square that the content is put into. | |
216 | -function addLightboxMarkup() { | |
217 | - bod = document.getElementsByTagName('body')[0]; | |
218 | - overlay = document.createElement('div'); | |
219 | - overlay.id = 'overlay'; | |
220 | - lb = document.createElement('div'); | |
221 | - lb.id = 'lightbox'; | |
222 | - lb.className = 'loading'; | |
223 | - lb.innerHTML = '<div id="lbLoadMessage">' + | |
224 | - '<img src="' + noosfero_root() + '/images/2loading.gif"/>' + | |
225 | - '</div>'; | |
226 | - bod.appendChild(overlay); | |
227 | - bod.appendChild(lb); | |
228 | -} | |
229 | -function removeLightboxMarkup() { | |
230 | - Element.remove($('overlay')); | |
231 | - Element.remove($('lightbox')); | |
232 | -} |
... | ... | @@ -0,0 +1,58 @@ |
1 | +noosfero.modal = { | |
2 | + | |
3 | + watchClass: function() { | |
4 | + jQuery(function($) { | |
5 | + $(document).delegate('.modal-toggle', 'click', function() { | |
6 | + $.colorbox({ | |
7 | + href: $(this).attr('href'), | |
8 | + maxWidth: $(window).width()-50, | |
9 | + height: $(window).height()-50, | |
10 | + open: true, | |
11 | + close: 'Cancel', | |
12 | + class: 'modal', | |
13 | + onComplete: function(bt) { | |
14 | + var opt = {}, maxH = $(window).height()-50; | |
15 | + if ($('#cboxLoadedContent *:first').height() > maxH) opt.height = maxH; | |
16 | + $.colorbox.resize(opt); | |
17 | + } | |
18 | + }); | |
19 | + return false; | |
20 | + }); | |
21 | + | |
22 | + $(document).delegate('.modal-close', 'click', function() { | |
23 | + $.colorbox.close(); | |
24 | + return false; | |
25 | + }); | |
26 | + | |
27 | + }); | |
28 | + }, | |
29 | + | |
30 | + inline: function(href, options) { | |
31 | + href = jQuery(href); | |
32 | + options = jQuery.extend({ | |
33 | + inline: true, href: href, | |
34 | + onLoad: function(){ href.show(); }, | |
35 | + onCleanup: function(){ href.hide(); }, | |
36 | + }, options) | |
37 | + | |
38 | + jQuery.colorbox(options); | |
39 | + | |
40 | + return false; | |
41 | + }, | |
42 | + | |
43 | + html: function(html, options) { | |
44 | + options = jQuery.extend({ | |
45 | + html: html, | |
46 | + }, options); | |
47 | + | |
48 | + jQuery.colorbox(options); | |
49 | + }, | |
50 | + | |
51 | + close: function() { | |
52 | + jQuery.colorbox.close(); | |
53 | + }, | |
54 | + | |
55 | +}; | |
56 | + | |
57 | +noosfero.modal.watchClass(); | |
58 | + | ... | ... |
public/javascripts/report-abuse.js
public/javascripts/thickbox.js
... | ... | @@ -1,319 +0,0 @@ |
1 | -/* | |
2 | - * Thickbox 3.1 - One Box To Rule Them All. | |
3 | - * By Cody Lindley (http://www.codylindley.com) | |
4 | - * Copyright (c) 2007 cody lindley | |
5 | - * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php | |
6 | -*/ | |
7 | - | |
8 | -var tb_pathToImage = "/images/loading.gif"; | |
9 | - | |
10 | -/*!!!!!!!!!!!!!!!!! edit below this line at your own risk !!!!!!!!!!!!!!!!!!!!!!!*/ | |
11 | - | |
12 | -//on page load call tb_init | |
13 | -jQuery(document).ready(function(){ | |
14 | - tb_init('a.thickbox, area.thickbox, input.thickbox');//pass where to apply thickbox | |
15 | - imgLoader = new Image();// preload image | |
16 | - imgLoader.src = noosfero_root() + tb_pathToImage; | |
17 | -}); | |
18 | - | |
19 | -//add thickbox to href & area elements that have a class of .thickbox | |
20 | -function tb_init(domChunk){ | |
21 | - jQuery(domChunk).click(function(){ | |
22 | - var t = this.title || this.name || null; | |
23 | - var a = this.href || this.alt; | |
24 | - var g = this.rel || false; | |
25 | - tb_show(t,a,g); | |
26 | - this.blur(); | |
27 | - return false; | |
28 | - }); | |
29 | -} | |
30 | - | |
31 | -function tb_show(caption, url, imageGroup) {//function called when the user clicks on a thickbox link | |
32 | - | |
33 | - try { | |
34 | - if (typeof document.body.style.maxHeight === "undefined") {//if IE 6 | |
35 | - jQuery("body","html").css({height: "100%", width: "100%"}); | |
36 | - jQuery("html").css("overflow","hidden"); | |
37 | - if (document.getElementById("TB_HideSelect") === null) {//iframe to hide select elements in ie6 | |
38 | - jQuery("body").append("<iframe id='TB_HideSelect'></iframe><div id='TB_overlay'></div><div id='TB_window'></div>"); | |
39 | - jQuery("#TB_overlay").click(tb_remove); | |
40 | - } | |
41 | - }else{//all others | |
42 | - if(document.getElementById("TB_overlay") === null){ | |
43 | - jQuery("body").append("<div id='TB_overlay'></div><div id='TB_window'></div>"); | |
44 | - jQuery("#TB_overlay").click(tb_remove); | |
45 | - } | |
46 | - } | |
47 | - | |
48 | - if(tb_detectMacXFF()){ | |
49 | - jQuery("#TB_overlay").addClass("TB_overlayMacFFBGHack");//use png overlay so hide flash | |
50 | - }else{ | |
51 | - jQuery("#TB_overlay").addClass("TB_overlayBG");//use background and opacity | |
52 | - } | |
53 | - | |
54 | - if(caption===null){caption="";} | |
55 | - jQuery("body").append("<div id='TB_load'><img src='"+imgLoader.src+"' /></div>");//add loader to the page | |
56 | - jQuery('#TB_load').show();//show loader | |
57 | - | |
58 | - var baseURL; | |
59 | - if(url.indexOf("?")!==-1){ //ff there is a query string involved | |
60 | - baseURL = url.substr(0, url.indexOf("?")); | |
61 | - }else{ | |
62 | - baseURL = url; | |
63 | - } | |
64 | - | |
65 | - var urlString = /\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$/; | |
66 | - var urlType = baseURL.toLowerCase().match(urlString); | |
67 | - | |
68 | - if(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || urlType == '.gif' || urlType == '.bmp'){//code to show images | |
69 | - | |
70 | - TB_PrevCaption = ""; | |
71 | - TB_PrevURL = ""; | |
72 | - TB_PrevHTML = ""; | |
73 | - TB_NextCaption = ""; | |
74 | - TB_NextURL = ""; | |
75 | - TB_NextHTML = ""; | |
76 | - TB_imageCount = ""; | |
77 | - TB_FoundURL = false; | |
78 | - if(imageGroup){ | |
79 | - TB_TempArray = jQuery("a[@rel="+imageGroup+"]").get(); | |
80 | - for (TB_Counter = 0; ((TB_Counter < TB_TempArray.length) && (TB_NextHTML === "")); TB_Counter++) { | |
81 | - var urlTypeTemp = TB_TempArray[TB_Counter].href.toLowerCase().match(urlString); | |
82 | - if (!(TB_TempArray[TB_Counter].href == url)) { | |
83 | - if (TB_FoundURL) { | |
84 | - TB_NextCaption = TB_TempArray[TB_Counter].title; | |
85 | - TB_NextURL = TB_TempArray[TB_Counter].href; | |
86 | - TB_NextHTML = "<span id='TB_next'> <a href='#'>Next ></a></span>"; | |
87 | - } else { | |
88 | - TB_PrevCaption = TB_TempArray[TB_Counter].title; | |
89 | - TB_PrevURL = TB_TempArray[TB_Counter].href; | |
90 | - TB_PrevHTML = "<span id='TB_prev'> <a href='#'>< Prev</a></span>"; | |
91 | - } | |
92 | - } else { | |
93 | - TB_FoundURL = true; | |
94 | - TB_imageCount = "Image " + (TB_Counter + 1) +" of "+ (TB_TempArray.length); | |
95 | - } | |
96 | - } | |
97 | - } | |
98 | - | |
99 | - imgPreloader = new Image(); | |
100 | - imgPreloader.onload = function(){ | |
101 | - imgPreloader.onload = null; | |
102 | - | |
103 | - // Resizing large images - orginal by Christian Montoya edited by me. | |
104 | - var pagesize = tb_getPageSize(); | |
105 | - var x = pagesize[0] - 150; | |
106 | - var y = pagesize[1] - 150; | |
107 | - var imageWidth = imgPreloader.width; | |
108 | - var imageHeight = imgPreloader.height; | |
109 | - if (imageWidth > x) { | |
110 | - imageHeight = imageHeight * (x / imageWidth); | |
111 | - imageWidth = x; | |
112 | - if (imageHeight > y) { | |
113 | - imageWidth = imageWidth * (y / imageHeight); | |
114 | - imageHeight = y; | |
115 | - } | |
116 | - } else if (imageHeight > y) { | |
117 | - imageWidth = imageWidth * (y / imageHeight); | |
118 | - imageHeight = y; | |
119 | - if (imageWidth > x) { | |
120 | - imageHeight = imageHeight * (x / imageWidth); | |
121 | - imageWidth = x; | |
122 | - } | |
123 | - } | |
124 | - // End Resizing | |
125 | - | |
126 | - TB_WIDTH = imageWidth + 30; | |
127 | - TB_HEIGHT = imageHeight + 60; | |
128 | - jQuery("#TB_window").append("<a href='' id='TB_ImageOff' title='Close'><img id='TB_Image' src='"+url+"' width='"+imageWidth+"' height='"+imageHeight+"' alt='"+caption+"'/></a>" + "<div id='TB_caption'>"+caption+"<div id='TB_secondLine'>" + TB_imageCount + TB_PrevHTML + TB_NextHTML + "</div></div><div id='TB_closeWindow'><a href='#' id='TB_closeWindowButton' title='Close'>close</a> or Esc Key</div>"); | |
129 | - | |
130 | - jQuery("#TB_closeWindowButton").click(tb_remove); | |
131 | - | |
132 | - if (!(TB_PrevHTML === "")) { | |
133 | - function goPrev(){ | |
134 | - if(jQuery(document).unbind("click",goPrev)){jQuery(document).unbind("click",goPrev);} | |
135 | - jQuery("#TB_window").remove(); | |
136 | - jQuery("body").append("<div id='TB_window'></div>"); | |
137 | - tb_show(TB_PrevCaption, TB_PrevURL, imageGroup); | |
138 | - return false; | |
139 | - } | |
140 | - jQuery("#TB_prev").click(goPrev); | |
141 | - } | |
142 | - | |
143 | - if (!(TB_NextHTML === "")) { | |
144 | - function goNext(){ | |
145 | - jQuery("#TB_window").remove(); | |
146 | - jQuery("body").append("<div id='TB_window'></div>"); | |
147 | - tb_show(TB_NextCaption, TB_NextURL, imageGroup); | |
148 | - return false; | |
149 | - } | |
150 | - jQuery("#TB_next").click(goNext); | |
151 | - | |
152 | - } | |
153 | - | |
154 | - document.onkeydown = function(e){ | |
155 | - if (e == null) { // ie | |
156 | - keycode = event.keyCode; | |
157 | - } else { // mozilla | |
158 | - keycode = e.which; | |
159 | - } | |
160 | - if(keycode == 27){ // close | |
161 | - tb_remove(); | |
162 | - } else if(keycode == 190){ // display previous image | |
163 | - if(!(TB_NextHTML == "")){ | |
164 | - document.onkeydown = ""; | |
165 | - goNext(); | |
166 | - } | |
167 | - } else if(keycode == 188){ // display next image | |
168 | - if(!(TB_PrevHTML == "")){ | |
169 | - document.onkeydown = ""; | |
170 | - goPrev(); | |
171 | - } | |
172 | - } | |
173 | - }; | |
174 | - | |
175 | - tb_position(); | |
176 | - jQuery("#TB_load").remove(); | |
177 | - jQuery("#TB_ImageOff").click(tb_remove); | |
178 | - jQuery("#TB_window").css({display:"block"}); //for safari using css instead of show | |
179 | - }; | |
180 | - | |
181 | - imgPreloader.src = url; | |
182 | - }else{//code to show html | |
183 | - | |
184 | - var queryString = url.replace(/^[^\?]+\??/,''); | |
185 | - var params = tb_parseQuery( queryString ); | |
186 | - | |
187 | - TB_WIDTH = (params['width']*1) + 30 || 630; //defaults to 630 if no paramaters were added to URL | |
188 | - TB_HEIGHT = (params['height']*1) + 40 || 440; //defaults to 440 if no paramaters were added to URL | |
189 | - ajaxContentW = TB_WIDTH - 30; | |
190 | - ajaxContentH = TB_HEIGHT - 45; | |
191 | - | |
192 | - if(url.indexOf('TB_iframe') != -1){// either iframe or ajax window | |
193 | - urlNoQuery = url.split('TB_'); | |
194 | - jQuery("#TB_iframeContent").remove(); | |
195 | - if(params['modal'] != "true"){//iframe no modal | |
196 | - jQuery("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='Close'>close</a> or Esc Key</div></div><iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;' > </iframe>"); | |
197 | - }else{//iframe modal | |
198 | - jQuery("#TB_overlay").unbind(); | |
199 | - jQuery("#TB_window").append("<iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;'> </iframe>"); | |
200 | - } | |
201 | - }else{// not an iframe, ajax | |
202 | - if(jQuery("#TB_window").css("display") != "block"){ | |
203 | - if(params['modal'] != "true"){//ajax no modal | |
204 | - jQuery("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton'>close</a> or Esc Key</div></div><div id='TB_ajaxContent' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px'></div>"); | |
205 | - }else{//ajax modal | |
206 | - jQuery("#TB_overlay").unbind(); | |
207 | - jQuery("#TB_window").append("<div id='TB_ajaxContent' class='TB_modal' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px;'></div>"); | |
208 | - } | |
209 | - }else{//this means the window is already up, we are just loading new content via ajax | |
210 | - jQuery("#TB_ajaxContent")[0].style.width = ajaxContentW +"px"; | |
211 | - jQuery("#TB_ajaxContent")[0].style.height = ajaxContentH +"px"; | |
212 | - jQuery("#TB_ajaxContent")[0].scrollTop = 0; | |
213 | - jQuery("#TB_ajaxWindowTitle").html(caption); | |
214 | - } | |
215 | - } | |
216 | - | |
217 | - jQuery("#TB_closeWindowButton").click(tb_remove); | |
218 | - | |
219 | - if(url.indexOf('TB_inline') != -1){ | |
220 | - jQuery("#TB_ajaxContent").append(jQuery('#' + params['inlineId']).children()); | |
221 | - jQuery("#TB_window").unload(function () { | |
222 | - jQuery('#' + params['inlineId']).append( jQuery("#TB_ajaxContent").children() ); // move elements back when you're finished | |
223 | - }); | |
224 | - tb_position(); | |
225 | - jQuery("#TB_load").remove(); | |
226 | - jQuery("#TB_window").css({display:"block"}); | |
227 | - }else if(url.indexOf('TB_iframe') != -1){ | |
228 | - tb_position(); | |
229 | - if(jQuery.browser.safari){//safari needs help because it will not fire iframe onload | |
230 | - jQuery("#TB_load").remove(); | |
231 | - jQuery("#TB_window").css({display:"block"}); | |
232 | - } | |
233 | - }else{ | |
234 | - jQuery("#TB_ajaxContent").load(url += "&random=" + (new Date().getTime()),function(){//to do a post change this load method | |
235 | - tb_position(); | |
236 | - jQuery("#TB_load").remove(); | |
237 | - tb_init("#TB_ajaxContent a.thickbox"); | |
238 | - jQuery("#TB_window").css({display:"block"}); | |
239 | - }); | |
240 | - } | |
241 | - | |
242 | - } | |
243 | - | |
244 | - if(!params['modal']){ | |
245 | - document.onkeyup = function(e){ | |
246 | - if (e == null) { // ie | |
247 | - keycode = event.keyCode; | |
248 | - } else { // mozilla | |
249 | - keycode = e.which; | |
250 | - } | |
251 | - if(keycode == 27){ // close | |
252 | - tb_remove(); | |
253 | - } | |
254 | - }; | |
255 | - } | |
256 | - | |
257 | - } catch(e) { | |
258 | - //nothing here | |
259 | - } | |
260 | -} | |
261 | - | |
262 | -//helper functions below | |
263 | -function tb_showIframe(){ | |
264 | - jQuery("#TB_load").remove(); | |
265 | - jQuery("#TB_window").css({display:"block"}); | |
266 | -} | |
267 | - | |
268 | -function tb_remove() { | |
269 | - jQuery("#TB_imageOff").unbind("click"); | |
270 | - jQuery("#TB_closeWindowButton").unbind("click"); | |
271 | - jQuery("#TB_window").fadeOut("fast",function(){jQuery('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().remove();}); | |
272 | - jQuery("#TB_load").remove(); | |
273 | - if (typeof document.body.style.maxHeight == "undefined") {//if IE 6 | |
274 | - jQuery("body","html").css({height: "auto", width: "auto"}); | |
275 | - jQuery("html").css("overflow",""); | |
276 | - } | |
277 | - document.onkeydown = ""; | |
278 | - document.onkeyup = ""; | |
279 | - return false; | |
280 | -} | |
281 | - | |
282 | -function tb_position() { | |
283 | -jQuery("#TB_window").css({marginLeft: '-' + parseInt((TB_WIDTH / 2),10) + 'px', width: TB_WIDTH + 'px'}); | |
284 | - if ( !(jQuery.browser.msie && jQuery.browser.version < 7)) { // take away IE6 | |
285 | - jQuery("#TB_window").css({marginTop: '-' + parseInt((TB_HEIGHT / 2),10) + 'px'}); | |
286 | - } | |
287 | -} | |
288 | - | |
289 | -function tb_parseQuery ( query ) { | |
290 | - var Params = {}; | |
291 | - if ( ! query ) {return Params;}// return empty object | |
292 | - var Pairs = query.split(/[;&]/); | |
293 | - for ( var i = 0; i < Pairs.length; i++ ) { | |
294 | - var KeyVal = Pairs[i].split('='); | |
295 | - if ( ! KeyVal || KeyVal.length != 2 ) {continue;} | |
296 | - var key = unescape( KeyVal[0] ); | |
297 | - var val = unescape( KeyVal[1] ); | |
298 | - val = val.replace(/\+/g, ' '); | |
299 | - Params[key] = val; | |
300 | - } | |
301 | - return Params; | |
302 | -} | |
303 | - | |
304 | -function tb_getPageSize(){ | |
305 | - var de = document.documentElement; | |
306 | - var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth; | |
307 | - var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight; | |
308 | - arrayPageSize = [w,h]; | |
309 | - return arrayPageSize; | |
310 | -} | |
311 | - | |
312 | -function tb_detectMacXFF() { | |
313 | - var userAgent = navigator.userAgent.toLowerCase(); | |
314 | - if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1) { | |
315 | - return true; | |
316 | - } | |
317 | -} | |
318 | - | |
319 | - |
public/stylesheets/application.css
... | ... | @@ -1901,17 +1901,6 @@ a.button.disabled, input.disabled { |
1901 | 1901 | * Block options editor floating window * |
1902 | 1902 | ****************************************/ |
1903 | 1903 | |
1904 | -/* FIXME This changes broke colorboxes all over the place. | |
1905 | - * Therefore I'm canceling them until they are properly treateda. */ | |
1906 | -#cboxLoadedContent { | |
1907 | - background: #FFF; | |
1908 | -/* box-shadow: 0 0 15px #888 inset; | |
1909 | - border-radius: 5px; | |
1910 | - border: 1px solid #777; | |
1911 | - border-left: none; | |
1912 | - border-right: none; */ | |
1913 | -} | |
1914 | - | |
1915 | 1904 | .block-config-options { |
1916 | 1905 | padding: 0px 10px 0px 30px; |
1917 | 1906 | } | ... | ... |
public/stylesheets/colorbox.css
1 | 1 | /* |
2 | - ColorBox Core Style: | |
2 | + Colorbox Core Style: | |
3 | 3 | The following CSS is consistent between example themes and should not be altered. |
4 | 4 | */ |
5 | 5 | #colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;} |
6 | +#cboxWrapper {max-width:none;} | |
6 | 7 | #cboxOverlay{position:fixed; width:100%; height:100%;} |
7 | 8 | #cboxMiddleLeft, #cboxBottomLeft{clear:left;} |
8 | 9 | #cboxContent{position:relative;} |
9 | -#cboxLoadedContent{overflow:auto;} | |
10 | +#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;} | |
10 | 11 | #cboxTitle{margin:0;} |
11 | -#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%;} | |
12 | +#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;} | |
12 | 13 | #cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;} |
13 | -.cboxPhoto{float:left; margin:auto; border:0; display:block;} | |
14 | +.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none; -ms-interpolation-mode:bicubic;} | |
14 | 15 | .cboxIframe{width:100%; height:100%; display:block; border:0;} |
16 | +#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;} | |
15 | 17 | |
16 | -/* | |
18 | +/* | |
17 | 19 | User Style: |
18 | - Change the following styles to modify the appearance of ColorBox. They are | |
20 | + Change the following styles to modify the appearance of Colorbox. They are | |
19 | 21 | ordered & tabbed in a way that represents the nesting of the generated HTML. |
20 | 22 | */ |
21 | 23 | #cboxOverlay{background:url(../images/colorbox/overlay.png) repeat 0 0;} |
22 | -#colorbox{} | |
23 | - #cboxTopLeft{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -100px 0;} | |
24 | - #cboxTopRight{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -129px 0;} | |
25 | - #cboxBottomLeft{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -100px -29px;} | |
26 | - #cboxBottomRight{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -129px -29px;} | |
24 | +#colorbox{outline:0;} | |
25 | + #cboxTopLeft{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -101px 0;} | |
26 | + #cboxTopRight{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -130px 0;} | |
27 | + #cboxBottomLeft{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -101px -29px;} | |
28 | + #cboxBottomRight{width:21px; height:21px; background:url(../images/colorbox/controls.png) no-repeat -130px -29px;} | |
27 | 29 | #cboxMiddleLeft{width:21px; background:url(../images/colorbox/controls.png) left top repeat-y;} |
28 | 30 | #cboxMiddleRight{width:21px; background:url(../images/colorbox/controls.png) right top repeat-y;} |
29 | 31 | #cboxTopCenter{height:21px; background:url(../images/colorbox/border.png) 0 0 repeat-x;} |
30 | 32 | #cboxBottomCenter{height:21px; background:url(../images/colorbox/border.png) 0 -29px repeat-x;} |
31 | 33 | #cboxContent{background:#fff; overflow:hidden;} |
34 | + .cboxIframe{background:#fff;} | |
32 | 35 | #cboxError{padding:50px; border:1px solid #ccc;} |
33 | 36 | #cboxLoadedContent{margin-bottom:28px;} |
34 | 37 | #cboxTitle{position:absolute; bottom:4px; left:0; text-align:center; width:100%; color:#949494;} |
35 | 38 | #cboxCurrent{position:absolute; bottom:4px; left:58px; color:#949494;} |
39 | + #cboxLoadingOverlay{background:url(../images/colorbox/loading_background.png) no-repeat center center;} | |
40 | + #cboxLoadingGraphic{background:url(../images/colorbox/loading.gif) no-repeat center center;} | |
41 | + | |
42 | + /* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */ | |
43 | + #cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; width:auto; background:none; } | |
44 | + | |
45 | + /* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */ | |
46 | + #cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;} | |
47 | + | |
36 | 48 | #cboxSlideshow{position:absolute; bottom:4px; right:30px; color:#0092ef;} |
37 | 49 | #cboxPrevious{position:absolute; bottom:0; left:0; background:url(../images/colorbox/controls.png) no-repeat -75px 0; width:25px; height:25px; text-indent:-9999px;} |
38 | - #cboxPrevious.hover{background-position:-75px -25px;} | |
50 | + #cboxPrevious:hover{background-position:-75px -25px;} | |
39 | 51 | #cboxNext{position:absolute; bottom:0; left:27px; background:url(../images/colorbox/controls.png) no-repeat -50px 0; width:25px; height:25px; text-indent:-9999px;} |
40 | - #cboxNext.hover{background-position:-50px -25px;} | |
41 | - #cboxLoadingOverlay{background:url(../images/colorbox/loading_background.png) no-repeat center center;} | |
42 | - #cboxLoadingGraphic{background:url(../images/colorbox/loading.gif) no-repeat center center;} | |
52 | + #cboxNext:hover{background-position:-50px -25px;} | |
43 | 53 | #cboxClose{position:absolute; bottom:0; right:0; background:url(../images/colorbox/controls.png) no-repeat -25px 0; width:25px; height:25px; text-indent:-9999px;} |
44 | - #cboxClose.hover{background-position:-25px -25px;} | |
54 | + #cboxClose:hover{background-position:-25px -25px;} | |
45 | 55 | |
46 | 56 | /* |
47 | - The following fixes a problem where IE7+ replaces a PNG's alpha transparency with a black fill | |
48 | - when an alpha filter (opacity change) is set on the element or ancestor element. | |
57 | + The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill | |
58 | + when an alpha filter (opacity change) is set on the element or ancestor element. This style is not applied to or needed in IE9. | |
59 | + See: http://jacklmoore.com/notes/ie-transparency-problems/ | |
49 | 60 | */ |
50 | 61 | .cboxIE #cboxTopLeft, |
51 | 62 | .cboxIE #cboxTopCenter, |
... | ... | @@ -57,26 +68,3 @@ |
57 | 68 | .cboxIE #cboxMiddleRight { |
58 | 69 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF); |
59 | 70 | } |
60 | - | |
61 | -/* | |
62 | - The following provides PNG transparency support for IE6 | |
63 | -*/ | |
64 | -.cboxIE6 #cboxTopLeft{background:url(../images/colorbox/ie6/borderTopLeft.png);} | |
65 | -.cboxIE6 #cboxTopCenter{background:url(../images/colorbox/ie6/borderTopCenter.png);} | |
66 | -.cboxIE6 #cboxTopRight{background:url(../images/colorbox/ie6/borderTopRight.png);} | |
67 | -.cboxIE6 #cboxBottomLeft{background:url(../images/colorbox/ie6/borderBottomLeft.png);} | |
68 | -.cboxIE6 #cboxBottomCenter{background:url(../images/colorbox/ie6/borderBottomCenter.png);} | |
69 | -.cboxIE6 #cboxBottomRight{background:url(../images/colorbox/ie6/borderBottomRight.png);} | |
70 | -.cboxIE6 #cboxMiddleLeft{background:url(../images/colorbox/ie6/borderMiddleLeft.png);} | |
71 | -.cboxIE6 #cboxMiddleRight{background:url(../images/colorbox/ie6/borderMiddleRight.png);} | |
72 | - | |
73 | -.cboxIE6 #cboxTopLeft, | |
74 | -.cboxIE6 #cboxTopCenter, | |
75 | -.cboxIE6 #cboxTopRight, | |
76 | -.cboxIE6 #cboxBottomLeft, | |
77 | -.cboxIE6 #cboxBottomCenter, | |
78 | -.cboxIE6 #cboxBottomRight, | |
79 | -.cboxIE6 #cboxMiddleLeft, | |
80 | -.cboxIE6 #cboxMiddleRight { | |
81 | - _behavior: expression(this.src = this.src ? this.src : this.currentStyle.backgroundImage.split('"')[1], this.style.background = "none", this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=" + this.src + ", sizingMethod='scale')"); | |
82 | -} | ... | ... |
public/stylesheets/lightbox.css
... | ... | @@ -1,63 +0,0 @@ |
1 | -/* - - - - - - - - - - - - - - - - - - - - - | |
2 | - | |
3 | -Title : Lightbox CSS | |
4 | -Author : Kevin Hale | |
5 | -URL : http://particletree.com/features/lightbox-gone-wild/ | |
6 | - | |
7 | -Created : January 13, 2006 | |
8 | -Modified : February 1, 2006 | |
9 | - | |
10 | -- - - - - - - - - - - - - - - - - - - - - */ | |
11 | - | |
12 | -#lightbox { | |
13 | - display: none; | |
14 | - position: absolute; | |
15 | - top: 150px; | |
16 | - left: 50%; | |
17 | - z-index: 300; | |
18 | - width: 500px; | |
19 | - margin-left: -265px; | |
20 | - border: 1px solid #000; | |
21 | - text-align: left; | |
22 | - padding: 1em; | |
23 | - background: #FFF; | |
24 | -} | |
25 | - | |
26 | -#overlay{ | |
27 | - display:none; | |
28 | - position:absolute; | |
29 | - top:0; | |
30 | - left:0; | |
31 | - width:100%; | |
32 | - height:100%; | |
33 | - z-index:200; | |
34 | - background-color:#000; | |
35 | - -moz-opacity: 0.75; | |
36 | - opacity:.75; | |
37 | - filter: alpha(opacity=75); | |
38 | -} | |
39 | -#overlay[id]{ | |
40 | - position:fixed; | |
41 | -} | |
42 | - | |
43 | -#lightbox.done #lbLoadMessage{ | |
44 | - display:none; | |
45 | -} | |
46 | -#lightbox.done #lbContent{ | |
47 | - display:block; | |
48 | -} | |
49 | -#lightbox.loading #lbContent{ | |
50 | - display:none; | |
51 | -} | |
52 | -#lightbox.loading #lbLoadMessage{ | |
53 | - display:block; | |
54 | -} | |
55 | - | |
56 | -#lightbox.done img{ | |
57 | - width:100%; | |
58 | - height:100%; | |
59 | -} | |
60 | - | |
61 | -#lightbox select { | |
62 | - max-width: 100%; | |
63 | -} |
public/stylesheets/thickbox.css
... | ... | @@ -1,163 +0,0 @@ |
1 | -/* ----------------------------------------------------------------------------------------------------------------*/ | |
2 | -/* ---------->>> global settings needed for thickbox <<<-----------------------------------------------------------*/ | |
3 | -/* ----------------------------------------------------------------------------------------------------------------*/ | |
4 | -/**{padding: 0; margin: 0;}*/ | |
5 | - | |
6 | -/* ----------------------------------------------------------------------------------------------------------------*/ | |
7 | -/* ---------->>> thickbox specific link and font settings <<<------------------------------------------------------*/ | |
8 | -/* ----------------------------------------------------------------------------------------------------------------*/ | |
9 | -#TB_window { | |
10 | - font: 12px Arial, Helvetica, sans-serif; | |
11 | - color: #333333; | |
12 | -} | |
13 | - | |
14 | -#TB_secondLine { | |
15 | - font: 10px Arial, Helvetica, sans-serif; | |
16 | - color:#666666; | |
17 | -} | |
18 | - | |
19 | -#TB_window a:link {color: #666666;} | |
20 | -#TB_window a:visited {color: #666666;} | |
21 | -#TB_window a:hover {color: #000;} | |
22 | -#TB_window a:active {color: #666666;} | |
23 | -#TB_window a:focus{color: #666666;} | |
24 | - | |
25 | -/* ----------------------------------------------------------------------------------------------------------------*/ | |
26 | -/* ---------->>> thickbox settings <<<-----------------------------------------------------------------------------*/ | |
27 | -/* ----------------------------------------------------------------------------------------------------------------*/ | |
28 | -#TB_overlay { | |
29 | - position: fixed; | |
30 | - z-index:200; | |
31 | - top: 0px; | |
32 | - left: 0px; | |
33 | - height:100%; | |
34 | - width:100%; | |
35 | -} | |
36 | - | |
37 | -.TB_overlayMacFFBGHack {background: url(macFFBgHack.png) repeat;} | |
38 | -.TB_overlayBG { | |
39 | - background-color:#000; | |
40 | - filter:alpha(opacity=75); | |
41 | - -moz-opacity: 0.75; | |
42 | - opacity: 0.75; | |
43 | -} | |
44 | - | |
45 | -* html #TB_overlay { /* ie6 hack */ | |
46 | - position: absolute; | |
47 | - height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); | |
48 | -} | |
49 | - | |
50 | -#TB_window { | |
51 | - position: fixed; | |
52 | - background: white; | |
53 | - z-index: 202; | |
54 | - color:#000000; | |
55 | - display:none; | |
56 | - border: 1px solid #000; | |
57 | - text-align:left; | |
58 | - top:50%; | |
59 | - left:50%; | |
60 | -} | |
61 | - | |
62 | -* html #TB_window { /* ie6 hack */ | |
63 | -position: absolute; | |
64 | -margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); | |
65 | -} | |
66 | - | |
67 | -#TB_window img#TB_Image { | |
68 | - display:block; | |
69 | - margin: 15px 0 0 15px; | |
70 | - border-right: 1px solid #ccc; | |
71 | - border-bottom: 1px solid #ccc; | |
72 | - border-top: 1px solid #666; | |
73 | - border-left: 1px solid #666; | |
74 | -} | |
75 | - | |
76 | -#TB_caption{ | |
77 | - height:25px; | |
78 | - padding:7px 30px 10px 25px; | |
79 | - float:left; | |
80 | -} | |
81 | - | |
82 | -#TB_closeWindow{ | |
83 | - height:25px; | |
84 | - padding:11px 25px 10px 0; | |
85 | - float:right; | |
86 | -} | |
87 | - | |
88 | -#TB_closeAjaxWindow{ | |
89 | - padding:7px 10px 5px 0; | |
90 | - margin-bottom:1px; | |
91 | - text-align:right; | |
92 | - float:right; | |
93 | -} | |
94 | - | |
95 | -#TB_ajaxWindowTitle{ | |
96 | - float:left; | |
97 | - padding:7px 0 5px 10px; | |
98 | - margin-bottom:1px; | |
99 | -} | |
100 | - | |
101 | -#TB_title{ | |
102 | - background-color:#e8e8e8; | |
103 | - height:27px; | |
104 | -} | |
105 | - | |
106 | -#TB_ajaxContent{ | |
107 | - clear:both; | |
108 | - padding:2px 15px 15px 15px; | |
109 | - overflow:auto; | |
110 | - text-align:left; | |
111 | - line-height:1.4em; | |
112 | -} | |
113 | - | |
114 | -#TB_ajaxContent.TB_modal{ | |
115 | - padding:15px; | |
116 | -} | |
117 | - | |
118 | -#TB_ajaxContent p{ | |
119 | - padding:5px 0px 5px 0px; | |
120 | -} | |
121 | - | |
122 | -#TB_load{ | |
123 | - position: fixed; | |
124 | - display:none; | |
125 | - height:13px; | |
126 | - width:208px; | |
127 | - z-index:203; | |
128 | - top: 50%; | |
129 | - left: 50%; | |
130 | - margin: -6px 0 0 -104px; /* -height/2 0 0 -width/2 */ | |
131 | -} | |
132 | - | |
133 | -* html #TB_load { /* ie6 hack */ | |
134 | -position: absolute; | |
135 | -margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); | |
136 | -} | |
137 | - | |
138 | -#TB_HideSelect{ | |
139 | - z-index:199; | |
140 | - position:fixed; | |
141 | - top: 0; | |
142 | - left: 0; | |
143 | - background-color:#fff; | |
144 | - border:none; | |
145 | - filter:alpha(opacity=0); | |
146 | - -moz-opacity: 0; | |
147 | - opacity: 0; | |
148 | - height:100%; | |
149 | - width:100%; | |
150 | -} | |
151 | - | |
152 | -* html #TB_HideSelect { /* ie6 hack */ | |
153 | - position: absolute; | |
154 | - height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); | |
155 | -} | |
156 | - | |
157 | -#TB_iframeContent{ | |
158 | - clear:both; | |
159 | - border:none; | |
160 | - margin-bottom:-1px; | |
161 | - margin-top:1px; | |
162 | - _margin-bottom:1px; | |
163 | -} |
... | ... | @@ -0,0 +1,56 @@ |
1 | +#!/usr/bin/env ruby | |
2 | + | |
3 | +# These just forward the signals to the whole process group and | |
4 | +# then immediately exit. | |
5 | +pgid = Process.getpgid Process.pid | |
6 | +Signal.trap(:TERM) { Process.kill(:TERM, -pgid); exit } | |
7 | +Signal.trap(:INT) { Process.kill(:INT, -pgid); exit } | |
8 | + | |
9 | +def run command, options = {} | |
10 | + command = "#{command} 2>&1 > /dev/null" if options[:output] == false | |
11 | + #command = "time #{command}" unless options[:runtime] == false | |
12 | + puts "== #{command}" | |
13 | + system command | |
14 | +end | |
15 | + | |
16 | +@id = (0...10).map{ ('a'..'z').to_a[rand(26)] }.join | |
17 | +@db = "gitlab-ci-#{@id}" | |
18 | + | |
19 | +def config | |
20 | + require 'yaml' | |
21 | + db_config = { | |
22 | + 'adapter' => 'postgresql', 'encoding' => 'unicode', | |
23 | + 'database' => @db, 'username' => ENV['USER'], | |
24 | + } | |
25 | + File.write 'config/database.yml', YAML.dump('test' => db_config, 'development' => db_config) | |
26 | +end | |
27 | + | |
28 | +def prepare | |
29 | + run("createdb #{@db}") and | |
30 | + run('mkdir -p tmp/pids log') and | |
31 | + run('bundle check || bundle install') and | |
32 | + run('rake db:schema:load', output: false) and | |
33 | + run('script/noosfero-plugins disableall') and | |
34 | + run('rake db:migrate') | |
35 | +end | |
36 | + | |
37 | +def test | |
38 | + %w[ | |
39 | + test:units | |
40 | + test:functionals | |
41 | + test:integration | |
42 | + cucumber | |
43 | + test:noosfero_plugins | |
44 | + ].each do |task| | |
45 | + run "rake #{task}" | |
46 | + end | |
47 | +end | |
48 | + | |
49 | +def cleanup | |
50 | + run "dropdb #{@db}" | |
51 | +end | |
52 | + | |
53 | +ret = config and prepare and test | |
54 | +cleanup | |
55 | + | |
56 | +exit (if ret == true then 0 else 1 end) | ... | ... |
script/install-dependencies/debian-squeeze.sh
... | ... | @@ -5,7 +5,7 @@ run sudo apt-get -y install $runtime_dependencies |
5 | 5 | sudo apt-get -y install iceweasel || sudo apt-get -y install firefox |
6 | 6 | |
7 | 7 | # needed for development |
8 | -run sudo apt-get -y install libtidy-ruby libhpricot-ruby libmocha-ruby imagemagick po4a xvfb libxml2-dev libxslt-dev postgresql openjdk-6-jre | |
8 | +run sudo apt-get -y install libtidy-ruby libmocha-ruby imagemagick po4a xvfb libxml2-dev libxslt-dev postgresql openjdk-6-jre | |
9 | 9 | gem which bundler >/dev/null 2>&1 || gem_install bundler |
10 | 10 | setup_rubygems_path |
11 | 11 | run bundle install | ... | ... |
test/functional/account_controller_test.rb
... | ... | @@ -818,17 +818,17 @@ class AccountControllerTest < ActionController::TestCase |
818 | 818 | end |
819 | 819 | |
820 | 820 | should 'login with an alternative authentication defined by plugin' do |
821 | + user = create_user | |
821 | 822 | class Plugin1 < Noosfero::Plugin |
822 | - def alternative_authentication | |
823 | - User.new(:login => 'testuser') | |
824 | - end | |
825 | 823 | end |
824 | + Plugin1.send(:define_method, :alternative_authentication){ user } | |
825 | + | |
826 | 826 | Noosfero::Plugin.stubs(:all).returns([Plugin1.name]) |
827 | 827 | Environment.default.enable_plugin(Plugin1.name) |
828 | 828 | |
829 | 829 | post :login, :user => {:login => "testuser"} |
830 | 830 | |
831 | - assert_equal 'testuser', assigns(:current_user).login | |
831 | + assert_equal user.login, assigns(:current_user).login | |
832 | 832 | assert_response :redirect |
833 | 833 | end |
834 | 834 | ... | ... |
test/functional/chat_controller_test.rb
... | ... | @@ -6,18 +6,20 @@ class ChatControllerTest < ActionController::TestCase |
6 | 6 | env = Environment.default |
7 | 7 | env.enable('xmpp_chat') |
8 | 8 | env.save! |
9 | + #TODO Maybe someday we should have a real testing ejabberd server | |
10 | + RubyBOSH.stubs(:initialize_session).returns(['fake-jid@example.org', 'fake-sid', 'fake-rid']) | |
9 | 11 | @person = create_user('testuser').person |
10 | 12 | end |
11 | 13 | |
12 | 14 | should 'cant view chat when not logged in' do |
13 | - get :index | |
15 | + get :start_session | |
14 | 16 | assert_response 302 |
15 | 17 | end |
16 | 18 | |
17 | 19 | should 'can view chat when logged in' do |
18 | 20 | login_as 'testuser' |
19 | 21 | |
20 | - get :index | |
22 | + get :start_session | |
21 | 23 | assert_response :success |
22 | 24 | end |
23 | 25 | |
... | ... | @@ -39,29 +41,6 @@ class ChatControllerTest < ActionController::TestCase |
39 | 41 | assert @response.body.index('PNG') |
40 | 42 | end |
41 | 43 | |
42 | - should 'auto connect if last presence status is blank' do | |
43 | - login_as 'testuser' | |
44 | - | |
45 | - get :index | |
46 | - assert_template 'auto_connect_online' | |
47 | - end | |
48 | - | |
49 | - should 'auto connect if there last presence status was chat' do | |
50 | - create_user('testuser_online', :last_chat_status => 'chat') | |
51 | - login_as 'testuser_online' | |
52 | - | |
53 | - get :index | |
54 | - assert_template 'auto_connect_online' | |
55 | - end | |
56 | - | |
57 | - should 'auto connect busy if last presence status was dnd' do | |
58 | - create_user('testuser_busy', :last_chat_status => 'dnd') | |
59 | - login_as 'testuser_busy' | |
60 | - | |
61 | - get :index | |
62 | - assert_template 'auto_connect_busy' | |
63 | - end | |
64 | - | |
65 | 44 | begin |
66 | 45 | require 'ruby_bosh' |
67 | 46 | should 'try to start xmpp session' do |
... | ... | @@ -87,7 +66,7 @@ class ChatControllerTest < ActionController::TestCase |
87 | 66 | env.disable('xmpp_chat') |
88 | 67 | env.save! |
89 | 68 | |
90 | - get :index | |
69 | + get :start_session | |
91 | 70 | |
92 | 71 | assert_response 404 |
93 | 72 | assert_template 'not_found' |
... | ... | @@ -116,4 +95,67 @@ class ChatControllerTest < ActionController::TestCase |
116 | 95 | assert_not_equal chat_status_at, @person.user.chat_status_at |
117 | 96 | end |
118 | 97 | |
98 | + should 'toggle chat status' do | |
99 | + login_as 'testuser' | |
100 | + | |
101 | + get :start_session | |
102 | + assert_nil session[:chat][:status] | |
103 | + | |
104 | + get :toggle | |
105 | + assert_equal 'opened', session[:chat][:status] | |
106 | + | |
107 | + get :toggle | |
108 | + assert_equal 'closed', session[:chat][:status] | |
109 | + | |
110 | + get :toggle | |
111 | + assert_equal 'opened', session[:chat][:status] | |
112 | + end | |
113 | + | |
114 | + should 'set tab' do | |
115 | + login_as 'testuser' | |
116 | + get :start_session | |
117 | + | |
118 | + post :tab, :tab_id => 'my_tab' | |
119 | + assert_equal 'my_tab', session[:chat][:tab_id] | |
120 | + end | |
121 | + | |
122 | + should 'join room' do | |
123 | + login_as 'testuser' | |
124 | + get :start_session | |
125 | + | |
126 | + post :join, :room_id => 'room1' | |
127 | + assert_equivalent ['room1'], session[:chat][:rooms] | |
128 | + | |
129 | + post :join, :room_id => 'room2' | |
130 | + assert_equivalent ['room1', 'room2'], session[:chat][:rooms] | |
131 | + | |
132 | + post :join, :room_id => 'room1' | |
133 | + assert_equivalent ['room1', 'room2'], session[:chat][:rooms] | |
134 | + end | |
135 | + | |
136 | + should 'leave room' do | |
137 | + login_as 'testuser' | |
138 | + get :start_session | |
139 | + session[:chat][:rooms] = ['room1', 'room2'] | |
140 | + | |
141 | + post :leave, :room_id => 'room2' | |
142 | + assert_equivalent ['room1'], session[:chat][:rooms] | |
143 | + | |
144 | + post :leave, :room_id => 'room1' | |
145 | + assert_equivalent [], session[:chat][:rooms] | |
146 | + | |
147 | + post :leave, :room_id => 'room1' | |
148 | + assert_equivalent [], session[:chat][:rooms] | |
149 | + end | |
150 | + | |
151 | + should 'fetch chat session as json' do | |
152 | + login_as 'testuser' | |
153 | + get :start_session | |
154 | + my_chat = {:status => 'opened', :rooms => ['room1', 'room2'], :tab_id => 'room1'} | |
155 | + session[:chat] = my_chat | |
156 | + | |
157 | + get :my_session | |
158 | + assert_equal @response.body, my_chat.to_json | |
159 | + end | |
160 | + | |
119 | 161 | end | ... | ... |
test/functional/cms_controller_test.rb
... | ... | @@ -638,7 +638,7 @@ class CmsControllerTest < ActionController::TestCase |
638 | 638 | |
639 | 639 | should 'display OK button on why_categorize popup' do |
640 | 640 | get :why_categorize, :profile => profile.identifier |
641 | - assert_tag :tag => 'a', :attributes => { :rel => 'deactivate'} # lightbox close button | |
641 | + assert_tag :tag => 'a', :attributes => { :rel => 'deactivate'} # modal close button | |
642 | 642 | end |
643 | 643 | |
644 | 644 | should 'display published option' do |
... | ... | @@ -663,8 +663,8 @@ class CmsControllerTest < ActionController::TestCase |
663 | 663 | should 'be able to add image with alignment' do |
664 | 664 | post :new, :type => 'TinyMceArticle', :profile => profile.identifier, :article => { :name => 'image-alignment', :body => "the text of the article with image <img src='#' align='right'/> right align..." } |
665 | 665 | saved = TinyMceArticle.find_by_name('image-alignment') |
666 | - assert_match /<img.*src="#".*\/>/, saved.body | |
667 | - assert_match /<img.*align="right".*\/>/, saved.body | |
666 | + assert_match /<img.*src="#".*>/, saved.body | |
667 | + assert_match /<img.*align="right".*>/, saved.body | |
668 | 668 | end |
669 | 669 | |
670 | 670 | should 'be able to add image with alignment when textile' do | ... | ... |
test/functional/profile_editor_controller_test.rb
... | ... | @@ -500,7 +500,7 @@ class ProfileEditorControllerTest < ActionController::TestCase |
500 | 500 | xhr :get, :update_categories, :profile => profile.identifier, :category_id => top.id |
501 | 501 | assert_template 'shared/update_categories' |
502 | 502 | assert_equal top, assigns(:current_category) |
503 | - assert_equal [c1, c2], assigns(:categories) | |
503 | + assert_equivalent [c1, c2], assigns(:categories) | |
504 | 504 | end |
505 | 505 | |
506 | 506 | should 'display manage my groups button for person' do | ... | ... |
test/test_helper.rb
... | ... | @@ -3,7 +3,6 @@ ENV["RAILS_ENV"] = "test" |
3 | 3 | require File.expand_path(File.dirname(__FILE__) + "/../config/environment") |
4 | 4 | require 'rails/test_help' |
5 | 5 | require 'mocha' |
6 | -require 'hpricot' | |
7 | 6 | |
8 | 7 | require 'noosfero/test' |
9 | 8 | require 'authenticated_test_helper' | ... | ... |
test/unit/application_helper_test.rb
... | ... | @@ -261,7 +261,7 @@ class ApplicationHelperTest < ActionView::TestCase |
261 | 261 | fast_create(Community, :is_template => true, :environment_id => environment.id) |
262 | 262 | environment.community_default_template= community |
263 | 263 | environment.save |
264 | - | |
264 | + | |
265 | 265 | assert_tag_in_string template_options(:communities, 'community'), :tag => 'input', |
266 | 266 | :attributes => { :name => "community[template_id]", :value => community.id, :checked => true } |
267 | 267 | end |
... | ... | @@ -273,7 +273,7 @@ class ApplicationHelperTest < ActionView::TestCase |
273 | 273 | fast_create(Person, :is_template => true, :environment_id => environment.id) |
274 | 274 | environment.person_default_template= person |
275 | 275 | environment.save |
276 | - | |
276 | + | |
277 | 277 | assert_tag_in_string template_options(:people, 'profile_data'), :tag => 'input', |
278 | 278 | :attributes => { :name => "profile_data[template_id]", :value => person.id, :checked => true } |
279 | 279 | end |
... | ... | @@ -287,7 +287,7 @@ class ApplicationHelperTest < ActionView::TestCase |
287 | 287 | environment.enterprise_default_template= enterprise |
288 | 288 | environment.save |
289 | 289 | environment.reload |
290 | - | |
290 | + | |
291 | 291 | assert_tag_in_string template_options(:enterprises, 'create_enterprise'), :tag => 'input', |
292 | 292 | :attributes => { :name => "create_enterprise[template_id]", :value => enterprise.id, :checked => true } |
293 | 293 | end |
... | ... | @@ -734,16 +734,16 @@ class ApplicationHelperTest < ActionView::TestCase |
734 | 734 | <div class='macro nonEdit' data-macro='unexistent' data-macro-param='987'></div> |
735 | 735 | " |
736 | 736 | parsed_html = convert_macro(html, mock()) |
737 | - parsed_divs = Hpricot(parsed_html).search('div') | |
738 | - expected_divs = Hpricot(" | |
739 | - <div data-macro='#{macro1_name}' class='parsed-macro #{macro1_name}'>Test1</div> | |
740 | - <div data-macro='#{macro2_name}' class='parsed-macro #{macro2_name}'>Test2</div> | |
737 | + parsed_divs = Nokogiri::HTML.fragment(parsed_html).css('div') | |
738 | + expected_divs = Nokogiri::HTML.fragment(" | |
739 | + <div class='parsed-macro #{macro1_name}' data-macro='#{macro1_name}'>Test1</div> | |
740 | + <div class='parsed-macro #{macro2_name}' data-macro='#{macro2_name}'>Test2</div> | |
741 | 741 | <div data-macro='unexistent' class='failed-macro unexistent'>Unsupported macro unexistent!</div> |
742 | - ").search('div') | |
742 | + ").css('div') | |
743 | 743 | |
744 | 744 | # comparing div attributes between parsed and expected html |
745 | 745 | parsed_divs.each_with_index do |div, i| |
746 | - assert_equal expected_divs[i].attributes.to_hash, div.attributes.to_hash | |
746 | + assert_equal expected_divs[i].attributes.to_xml, div.attributes.to_xml | |
747 | 747 | assert_equal expected_divs[i].inner_text, div.inner_text |
748 | 748 | end |
749 | 749 | end | ... | ... |
test/unit/colorbox_helper_test.rb
... | ... | @@ -1,36 +0,0 @@ |
1 | -require_relative "../test_helper" | |
2 | - | |
3 | -class ColorboxHelperTest < ActiveSupport::TestCase | |
4 | - | |
5 | - include ColorboxHelper | |
6 | - | |
7 | - should 'provide the needed files' do | |
8 | - assert File.exists?(Rails.root.join('public', 'stylesheets', 'colorbox.css')), 'colorbox.css expected to be in public/stylesheets, but not found' | |
9 | - assert File.exists?(Rails.root.join('public', 'javascripts', 'colorbox.js')), 'colorbox.js expected to be in public/javascripts, but not found' | |
10 | - end | |
11 | - | |
12 | - should 'provide link to close colorbox' do | |
13 | - expects(:button).with(:close, 'text', '#', has_entries({ :class => 'colorbox-close', :id => 'my-id' })).returns('[close-colorbox]') | |
14 | - | |
15 | - assert_equal '[close-colorbox]', colorbox_close_button('text', :id => 'my-id') | |
16 | - end | |
17 | - | |
18 | - should 'merge existing :class option in colorbox_close_button' do | |
19 | - expects(:button).with(:close, 'text', '#', has_entries({ :class => 'colorbox-close my-class', :id => 'my-id' })).returns('[close-colorbox]') | |
20 | - | |
21 | - assert_equal '[close-colorbox]', colorbox_close_button('text', :class => 'my-class', :id => 'my-id' ) | |
22 | - end | |
23 | - | |
24 | - should 'provide colorbox_button' do | |
25 | - expects(:button).with('type', 'label', { :action => 'popup'}, has_entries({ :class => 'colorbox' })).returns('[button]') | |
26 | - | |
27 | - assert_equal '[button]', colorbox_button('type', 'label', { :action => 'popup'}) | |
28 | - end | |
29 | - | |
30 | - should 'provide colorbox_icon_button' do | |
31 | - expects(:icon_button).with('type', 'label', { :action => 'popup'}, has_entries({ :class => 'colorbox' })).returns('[button]') | |
32 | - | |
33 | - assert_equal '[button]', colorbox_icon_button('type', 'label', { :action => 'popup'}) | |
34 | - end | |
35 | - | |
36 | -end |
test/unit/comment_helper_test.rb
... | ... | @@ -137,7 +137,7 @@ class CommentHelperTest < ActiveSupport::TestCase |
137 | 137 | plugin_action = {:link => 'plugin_action', :action_bar => true} |
138 | 138 | @plugins.stubs(:dispatch).returns([plugin_action]) |
139 | 139 | html = comment_actions(comment) |
140 | - assert_match /plugin_action/, Hpricot(html).search('.comments-action-bar').html | |
140 | + assert_match /plugin_action/, Nokogiri::HTML.fragment(html).css('.comments-action-bar').to_html | |
141 | 141 | end |
142 | 142 | |
143 | 143 | def link_to_function(content, url, options = {}) | ... | ... |
test/unit/external_feed_test.rb
... | ... | @@ -18,7 +18,8 @@ class ExternalFeedTest < ActiveSupport::TestCase |
18 | 18 | end |
19 | 19 | |
20 | 20 | should 'not add same item twice' do |
21 | - e = create(:external_feed) | |
21 | + blog = create_blog | |
22 | + e = create(:external_feed, blog: blog) | |
22 | 23 | assert e.add_item('Article title', 'http://orig.link.invalid', Time.now, 'Content for external post') |
23 | 24 | assert !e.add_item('Article title', 'http://orig.link.invalid', Time.now, 'Content for external post') |
24 | 25 | assert_equal 1, e.blog.posts.size |
... | ... | @@ -52,7 +53,8 @@ class ExternalFeedTest < ActiveSupport::TestCase |
52 | 53 | |
53 | 54 | should 'add items to blog as posts' do |
54 | 55 | handler = FeedHandler.new |
55 | - e = create(:external_feed) | |
56 | + blog = create_blog | |
57 | + e = create(:external_feed, blog: blog) | |
56 | 58 | handler.process(e) |
57 | 59 | assert_equal ["Last POST", "Second POST", "First POST"], e.blog.posts.map{|i| i.title} |
58 | 60 | end |
... | ... | @@ -164,7 +166,7 @@ class ExternalFeedTest < ActiveSupport::TestCase |
164 | 166 | next if a.kind_of?(RssFeed) |
165 | 167 | dd << a.body.to_s.strip.gsub(/\s+/, ' ') |
166 | 168 | end |
167 | - assert_equal '<img src="noosfero.png" /><p>Html content 1.</p><p>Html content 2.</p>', dd.sort.join | |
169 | + assert_equal '<img src="noosfero.png"><p>Html content 1.</p><p>Html content 2.</p>', dd.sort.join | |
168 | 170 | end |
169 | 171 | |
170 | 172 | should 'use feed title as author name' do | ... | ... |
test/unit/lightbox_helper_test.rb
... | ... | @@ -1,65 +0,0 @@ |
1 | -require_relative "../test_helper" | |
2 | - | |
3 | -class LightboxHelperTest < ActiveSupport::TestCase | |
4 | - | |
5 | - include LightboxHelper | |
6 | - | |
7 | - def setup | |
8 | - stubs(:_).with(anything).returns('TEXT') | |
9 | - end | |
10 | - | |
11 | - should 'provide the needed files' do | |
12 | - assert File.exists?(Rails.root.join('public', 'stylesheets', 'lightbox.css')), 'lightbox.css expected to be in public/stylesheets, but not found' | |
13 | - assert File.exists?(Rails.root.join('public', 'javascripts', 'lightbox.js')), 'lightbox.js expected to be in public/javascripts, but not found' | |
14 | - end | |
15 | - | |
16 | - should 'provide lightbox_link_to helper' do | |
17 | - expects(:link_to).with('text', { :action => 'view', :id => '1' }, has_entries({ :class => 'lbOn', :id => 'my-link' })).returns('[link]') | |
18 | - assert_equal '[link]', lightbox_link_to('text', { :action => 'view', :id => '1'}, { :id => 'my-link' }) | |
19 | - end | |
20 | - | |
21 | - should 'merge existing :class option in lightbox_link_to' do | |
22 | - expects(:link_to).with('text', { :action => 'view', :id => '1' }, has_entries({ :class => 'lbOn my-button', :id => 'my-link' })).returns('[link]') | |
23 | - assert_equal '[link]', lightbox_link_to('text', { :action => 'view', :id => '1'}, { :class => 'my-button', :id => 'my-link' }) | |
24 | - | |
25 | - end | |
26 | - | |
27 | - should 'provide link to close lightbox' do | |
28 | - expects(:button).with(:close, 'text', '#', has_entries({ :class => 'lbAction', :rel => 'deactivate', :id => 'my-id' })).returns('[close-lightbox]') | |
29 | - | |
30 | - assert_equal '[close-lightbox]', lightbox_close_button('text', :id => 'my-id') | |
31 | - end | |
32 | - | |
33 | - should 'merge existing :class option in lightbox_close_button' do | |
34 | - expects(:button).with(:close, 'text', '#', has_entries({ :class => 'lbAction my-class', :rel => 'deactivate', :id => 'my-id' })).returns('[close-lightbox]') | |
35 | - | |
36 | - assert_equal '[close-lightbox]', lightbox_close_button('text', :class => 'my-class', :id => 'my-id' ) | |
37 | - end | |
38 | - | |
39 | - should 'provide lightbox_button' do | |
40 | - expects(:button).with('type', 'label', { :action => 'popup'}, has_entries({ :class => 'lbOn' })).returns('[button]') | |
41 | - | |
42 | - assert_equal '[button]', lightbox_button('type', 'label', { :action => 'popup'}) | |
43 | - end | |
44 | - | |
45 | - should 'provide lightbox_icon_button' do | |
46 | - expects(:icon_button).with('type', 'label', { :action => 'popup'}, has_entries({ :class => 'lbOn' })).returns('[button]') | |
47 | - | |
48 | - assert_equal '[button]', lightbox_icon_button('type', 'label', { :action => 'popup'}) | |
49 | - end | |
50 | - | |
51 | - should 'tell if rendering inside lightbox' do | |
52 | - request = mock | |
53 | - expects(:request).returns(request) | |
54 | - request.expects(:xhr?).returns(true) | |
55 | - | |
56 | - assert lightbox? | |
57 | - end | |
58 | - | |
59 | - should 'provide lightbox_remote_button' do | |
60 | - expects(:button).with('type', 'label', { :action => 'popup'}, has_entries({ :class => 'remote-lbOn' })).returns('[button]') | |
61 | - | |
62 | - assert_equal '[button]', lightbox_remote_button('type', 'label', { :action => 'popup'}) | |
63 | - end | |
64 | - | |
65 | -end |
test/unit/macro_test.rb
... | ... | @@ -15,7 +15,7 @@ class MacroTest < ActiveSupport::TestCase |
15 | 15 | |
16 | 16 | def setup |
17 | 17 | @macro = Plugin1::Macro.new |
18 | - @macro_element = Hpricot(MACRO).search('.macro').first | |
18 | + @macro_element = Nokogiri::HTML.fragment(MACRO).css('.macro').first | |
19 | 19 | end |
20 | 20 | |
21 | 21 | attr_reader :macro, :macro_element | ... | ... |
... | ... | @@ -0,0 +1,36 @@ |
1 | +require_relative '../test_helper' | |
2 | + | |
3 | +class ModalHelperTest < ActiveSupport::TestCase | |
4 | + | |
5 | + include ModalHelper | |
6 | + | |
7 | + should 'provide the needed files' do | |
8 | + assert File.exists?(Rails.root.join('public', 'stylesheets', 'colorbox.css')), 'colorbox.css expected to be in public/stylesheets, but not found' | |
9 | + assert File.exists?(Rails.root.join('public', 'javascripts', 'jquery.colorbox-min.js')), 'jquery.colorbox-min.js expected to be in public/javascripts, but not found' | |
10 | + end | |
11 | + | |
12 | + should 'provide link to close modal' do | |
13 | + expects(:button).with(:close, 'text', '#', has_entries({ :class => 'modal-toggle modal-close', :id => 'my-id' })).returns('[close-modal]') | |
14 | + | |
15 | + assert_equal '[close-modal]', modal_close_button('text', :id => 'my-id') | |
16 | + end | |
17 | + | |
18 | + should 'merge existing :class option in modal_close_button' do | |
19 | + expects(:button).with(:close, 'text', '#', has_entries({ :class => 'modal-toggle modal-close my-class', :id => 'my-id' })).returns('[close-modal]') | |
20 | + | |
21 | + assert_equal '[close-modal]', modal_close_button('text', :class => 'my-class', :id => 'my-id' ) | |
22 | + end | |
23 | + | |
24 | + should 'provide modal_button' do | |
25 | + expects(:button).with('type', 'label', { :action => 'popup'}, has_entries({ :class => 'modal-toggle' })).returns('[button]') | |
26 | + | |
27 | + assert_equal '[button]', modal_button('type', 'label', { :action => 'popup'}) | |
28 | + end | |
29 | + | |
30 | + should 'provide modal_icon_button' do | |
31 | + expects(:icon_button).with('type', 'label', { :action => 'popup'}, has_entries({ :class => 'modal-toggle' })).returns('[button]') | |
32 | + | |
33 | + assert_equal '[button]', modal_icon_button('type', 'label', { :action => 'popup'}) | |
34 | + end | |
35 | + | |
36 | +end | ... | ... |
test/unit/person_notifier_test.rb
... | ... | @@ -225,6 +225,35 @@ class PersonNotifierTest < ActiveSupport::TestCase |
225 | 225 | assert !jobs.select {|j| !j.failed? && j.last_error.nil? }.empty? |
226 | 226 | end |
227 | 227 | |
228 | + should 'render image tags for both internal and external src' do | |
229 | + @community.add_member(@member) | |
230 | + process_delayed_job_queue | |
231 | + notify | |
232 | + sent = ActionMailer::Base.deliveries.last | |
233 | + assert_match /src="\/\/www.gravatar.com\/avatar.*"/, sent.body.to_s | |
234 | + assert_match /src="http:\/\/.*\/images\/icons-app\/community-icon.png.*"/, sent.body.to_s | |
235 | + end | |
236 | + | |
237 | + should 'do not raise errors in NotifyJob failure to avoid loop' do | |
238 | + Delayed::Worker.max_attempts = 1 | |
239 | + Delayed::Job.enqueue(PersonNotifier::NotifyJob.new(@member.id)) | |
240 | + | |
241 | + PersonNotifier.any_instance.stubs(:notify).raises('error') | |
242 | + PersonNotifier.any_instance.stubs(:dispatch_notification_mail).raises('error') | |
243 | + | |
244 | + process_delayed_job_queue | |
245 | + jobs = PersonNotifier::NotifyJob.find(@member.id) | |
246 | + assert jobs.select {|j| !j.failed? && j.last_error.nil? }.empty? | |
247 | + end | |
248 | + | |
249 | + should 'list tasks in notification mail' do | |
250 | + task = @member.tasks.create! | |
251 | + process_delayed_job_queue | |
252 | + notify | |
253 | + sent = ActionMailer::Base.deliveries.last | |
254 | + assert_match /href=".*\/myprofile\/member\/tasks"/, sent.body.to_s | |
255 | + end | |
256 | + | |
228 | 257 | private |
229 | 258 | |
230 | 259 | def notify | ... | ... |
test/unit/product_test.rb
... | ... | @@ -492,7 +492,7 @@ class ProductTest < ActiveSupport::TestCase |
492 | 492 | :amount_used => 10, :price_per_unit => 10, :is_from_solidarity_economy => false) |
493 | 493 | assert_equal 25, prod.percentage_from_solidarity_economy.first |
494 | 494 | |
495 | - prod = fast_create(Product, :name => 'test product1', :product_category_id => @product_category.id, :enterprise_id => @profile.id) | |
495 | + prod = fast_create(Product, :name => 'test product1', :product_category_id => @product_category.id, :profile_id => @profile.id) | |
496 | 496 | prod.inputs.create!(:product_id => prod.id, :product_category_id => @product_category.id, |
497 | 497 | :amount_used => 10, :price_per_unit => 10, :is_from_solidarity_economy => true) |
498 | 498 | prod.inputs.create!(:product_id => prod.id, :product_category_id => @product_category.id, |
... | ... | @@ -503,7 +503,7 @@ class ProductTest < ActiveSupport::TestCase |
503 | 503 | :amount_used => 10, :price_per_unit => 10, :is_from_solidarity_economy => false) |
504 | 504 | assert_equal 75, prod.percentage_from_solidarity_economy.first |
505 | 505 | |
506 | - prod = fast_create(Product, :name => 'test product', :product_category_id => @product_category.id, :enterprise_id => @profile.id) | |
506 | + prod = fast_create(Product, :name => 'test product', :product_category_id => @product_category.id, :profile_id => @profile.id) | |
507 | 507 | prod.inputs.create!(:product_id => prod.id, :product_category_id => @product_category.id, |
508 | 508 | :amount_used => 10, :price_per_unit => 10, :is_from_solidarity_economy => true) |
509 | 509 | assert_equal 100, prod.percentage_from_solidarity_economy.first | ... | ... |
test/unit/text_article_test.rb
1 | 1 | require_relative "../test_helper" |
2 | 2 | |
3 | 3 | class TextArticleTest < ActiveSupport::TestCase |
4 | - | |
4 | + | |
5 | 5 | # mostly dummy test. Can be removed when (if) there are real tests for this |
6 | - # this class. | |
6 | + # this class. | |
7 | 7 | should 'inherit from Article' do |
8 | 8 | assert_kind_of Article, TextArticle.new |
9 | 9 | end |
... | ... | @@ -44,7 +44,7 @@ class TextArticleTest < ActiveSupport::TestCase |
44 | 44 | env = Environment.default |
45 | 45 | article.body = "<img src=\"http://#{env.default_hostname}/test.png\" />" |
46 | 46 | article.save! |
47 | - assert_equal "<img src=\"/test.png\" />", article.body | |
47 | + assert_equal "<img src=\"/test.png\">", article.body | |
48 | 48 | end |
49 | 49 | |
50 | 50 | should 'change link to relative path' do |
... | ... | @@ -60,18 +60,18 @@ class TextArticleTest < ActiveSupport::TestCase |
60 | 60 | person = create_user('testuser').person |
61 | 61 | article = TextArticle.new(:profile => person, :name => 'test') |
62 | 62 | env = Environment.default |
63 | - article.body = "<img src=\"https://#{env.default_hostname}/test.png\" />" | |
63 | + article.body = "<img src=\"https://#{env.default_hostname}/test.png\">" | |
64 | 64 | article.save! |
65 | - assert_equal "<img src=\"/test.png\" />", article.body | |
65 | + assert_equal "<img src=\"/test.png\">", article.body | |
66 | 66 | end |
67 | 67 | |
68 | 68 | should 'change image path to relative for domain with port' do |
69 | 69 | person = create_user('testuser').person |
70 | 70 | article = TextArticle.new(:profile => person, :name => 'test') |
71 | 71 | env = Environment.default |
72 | - article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\" />" | |
72 | + article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\">" | |
73 | 73 | article.save! |
74 | - assert_equal "<img src=\"/test.png\" />", article.body | |
74 | + assert_equal "<img src=\"/test.png\">", article.body | |
75 | 75 | end |
76 | 76 | |
77 | 77 | should 'change image path to relative for domain with www' do |
... | ... | @@ -80,16 +80,16 @@ class TextArticleTest < ActiveSupport::TestCase |
80 | 80 | env = Environment.default |
81 | 81 | env.force_www = true |
82 | 82 | env.save! |
83 | - article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\" />" | |
83 | + article.body = "<img src=\"http://#{env.default_hostname}:3000/test.png\">" | |
84 | 84 | article.save! |
85 | - assert_equal "<img src=\"/test.png\" />", article.body | |
85 | + assert_equal "<img src=\"/test.png\">", article.body | |
86 | 86 | end |
87 | 87 | |
88 | 88 | should 'not be translatable if there is no language available on environment' do |
89 | 89 | environment = fast_create(Environment) |
90 | 90 | environment.languages = nil |
91 | 91 | profile = fast_create(Person, :environment_id => environment.id) |
92 | - | |
92 | + | |
93 | 93 | text = TextArticle.new(:profile => profile) |
94 | 94 | |
95 | 95 | assert !text.translatable? |
... | ... | @@ -102,11 +102,10 @@ class TextArticleTest < ActiveSupport::TestCase |
102 | 102 | text = fast_create(TextArticle, :profile_id => profile.id) |
103 | 103 | |
104 | 104 | assert !text.translatable? |
105 | - | |
106 | 105 | |
107 | 106 | environment.languages = ['en','pt','fr'] |
108 | 107 | environment.save |
109 | - text.reload | |
108 | + text.reload | |
110 | 109 | assert text.translatable? |
111 | 110 | end |
112 | 111 | ... | ... |
test/unit/thickbox_helper_test.rb
... | ... | @@ -1,25 +0,0 @@ |
1 | -require_relative "../test_helper" | |
2 | - | |
3 | -class ThickboxHelperTest < ActiveSupport::TestCase | |
4 | - include ThickboxHelper | |
5 | - | |
6 | - def url_for(url) | |
7 | - url | |
8 | - end | |
9 | - | |
10 | - should 'create thickbox links correcly' do | |
11 | - expects(:link_to).with('Title', '/url#TB_inline?height=300&width=500&inlineId=inlineLoginBox&modal=true', :class => 'thickbox') | |
12 | - thickbox_inline_popup_link('Title', '/url', 'inlineLoginBox') | |
13 | - end | |
14 | - | |
15 | - should 'pass along extra options' do | |
16 | - expects(:link_to).with('Title', anything, :class => 'thickbox', :id => 'lalala', :title => 'lelele') | |
17 | - thickbox_inline_popup_link('Title', '/url', 'inlineLoginBox', :id => 'lalala', :title => 'lelele') | |
18 | - end | |
19 | - | |
20 | - should 'generate close button' do | |
21 | - expects(:button_to_function).with(:close, 'Title', 'tb_remove();').returns('[close-button]') | |
22 | - assert_equal '[close-button]', thickbox_close_button('Title') | |
23 | - end | |
24 | - | |
25 | -end |
test/unit/tiny_mce_article_test.rb
... | ... | @@ -9,7 +9,7 @@ class TinyMceArticleTest < ActiveSupport::TestCase |
9 | 9 | end |
10 | 10 | attr_reader :profile |
11 | 11 | |
12 | - # this test can be removed when we get real tests for TinyMceArticle | |
12 | + # this test can be removed when we get real tests for TinyMceArticle | |
13 | 13 | should 'be an article' do |
14 | 14 | assert_subclass TextArticle, TinyMceArticle |
15 | 15 | end |
... | ... | @@ -44,11 +44,6 @@ class TinyMceArticleTest < ActiveSupport::TestCase |
44 | 44 | assert(article.body.is_utf8?, "%s expected to be valid UTF-8 content" % article.body.inspect) |
45 | 45 | end |
46 | 46 | |
47 | - should 'fix tinymce mess with itheora comments for IE from tiny mce article body' do | |
48 | - article = create(TinyMceArticle, :profile => profile, :name => 'article', :abstract => 'abstract', :body => "the <!--–-[if IE]--> just for ie... <!--[endif]-->") | |
49 | - assert_equal "the <!–-[if IE]> just for ie... <![endif]-–>", article.body.html_safe | |
50 | - end | |
51 | - | |
52 | 47 | should 'remove iframe if it is not from a trusted site' do |
53 | 48 | article = create(TinyMceArticle, :profile => profile, :name => 'article', :abstract => 'abstract', :body => "<iframe src='http://anything/videos.ogg'></iframe>") |
54 | 49 | assert_equal "", article.body |
... | ... | @@ -94,12 +89,6 @@ class TinyMceArticleTest < ActiveSupport::TestCase |
94 | 89 | assert_equal '', article.body |
95 | 90 | end |
96 | 91 | |
97 | - #TinymMCE convert config={"key":(.*)} in config={"key":(.*)} | |
98 | - should 'not replace " with &quot; when adding an Archive.org video' do | |
99 | - article = create(TinyMceArticle, :profile => profile, :name => 'article', :abstract => 'abstract', :body => "<embed flashvars='config={"key":"\#$b6eb72a0f2f1e29f3d4"}'> </embed>") | |
100 | - assert_equal "<embed flashvars=\"config={"key":"\#$b6eb72a0f2f1e29f3d4"}\"> </embed>", article.body | |
101 | - end | |
102 | - | |
103 | 92 | should 'not sanitize html comments' do |
104 | 93 | article = TinyMceArticle.new |
105 | 94 | article.body = '<p><!-- <asdf> << aasdfa >>> --> <h1> Wellformed html code </h1>' | ... | ... |
test/unit/user_activation_job_test.rb
test/unit/user_test.rb
... | ... | @@ -526,9 +526,19 @@ class UserTest < ActiveSupport::TestCase |
526 | 526 | assert user.activated? |
527 | 527 | end |
528 | 528 | |
529 | - should 'delay activation check' do | |
529 | + should 'delay activation check with default time' do | |
530 | 530 | user = new_user |
531 | - assert_match /UserActivationJob/, Delayed::Job.last.handler | |
531 | + job = Delayed::Job.last | |
532 | + assert_match /UserActivationJob/, job.handler | |
533 | + assert_equal 72, ((job.run_at - user.created_at)/1.hour).round | |
534 | + end | |
535 | + | |
536 | + should 'delay activation check with custom time' do | |
537 | + NOOSFERO_CONF.stubs(:[]).with('hours_until_user_activation_check').returns(240) | |
538 | + user = new_user | |
539 | + job = Delayed::Job.last | |
540 | + assert_match /UserActivationJob/, job.handler | |
541 | + assert_equal 240, ((job.run_at - user.created_at)/1.hour).round | |
532 | 542 | end |
533 | 543 | |
534 | 544 | should 'not create job to check activation to template users' do | ... | ... |
vendor/cardmagic-contacts-f66219e6589ccaf3ab9e3574fdd41225d0dd5073/lib/contacts/aol.rb
... | ... | @@ -8,20 +8,19 @@ class Hash |
8 | 8 | end |
9 | 9 | |
10 | 10 | class Contacts |
11 | - require 'hpricot' | |
12 | 11 | class Aol < Base |
13 | 12 | URL = "http://www.aol.com/" |
14 | 13 | LOGIN_URL = "https://my.screenname.aol.com/_cqr/login/login.psp" |
15 | 14 | LOGIN_REFERER_URL = "http://webmail.aol.com/" |
16 | 15 | LOGIN_REFERER_PATH = "sitedomain=sns.webmail.aol.com&lang=en&locale=us&authLev=0&uitype=mini&loginId=&redirType=js&xchk=false" |
17 | 16 | AOL_NUM = "29970-343" # this seems to change each time they change the protocol |
18 | - | |
17 | + | |
19 | 18 | CONTACT_LIST_URL = "http://webmail.aol.com/#{AOL_NUM}/aim-2/en-us/Lite/ContactList.aspx?folder=Inbox&showUserFolders=False" |
20 | 19 | CONTACT_LIST_CSV_URL = "http://webmail.aol.com/#{AOL_NUM}/aim-2/en-us/Lite/ABExport.aspx?command=all" |
21 | 20 | PROTOCOL_ERROR = "AOL has changed its protocols, please upgrade this library first. If that does not work, dive into the code and submit a patch at http://github.com/cardmagic/contacts" |
22 | - | |
21 | + | |
23 | 22 | def real_connect |
24 | - | |
23 | + | |
25 | 24 | postdata = { |
26 | 25 | "loginId" => login, |
27 | 26 | "password" => password, |
... | ... | @@ -62,15 +61,15 @@ class Contacts |
62 | 61 | until forward.nil? |
63 | 62 | data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward] |
64 | 63 | end |
65 | - | |
64 | + | |
66 | 65 | data, resp, cookies, forward, old_url = get("#{LOGIN_URL}?#{LOGIN_REFERER_PATH}", cookies) + [LOGIN_REFERER_URL] |
67 | 66 | until forward.nil? |
68 | 67 | data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward] |
69 | 68 | end |
70 | 69 | |
71 | - doc = Hpricot(data) | |
72 | - (doc/:input).each do |input| | |
73 | - postdata["usrd"] = input.attributes["value"] if input.attributes["name"] == "usrd" | |
70 | + doc = Nokogiri::HTML.fragment data | |
71 | + doc.css('input').each do |input| | |
72 | + postdata["usrd"] = input["value"] if input["name"] == "usrd" | |
74 | 73 | end |
75 | 74 | # parse data for <input name="usrd" value="2726212" type="hidden"> and add it to the postdata |
76 | 75 | |
... | ... | @@ -78,13 +77,13 @@ class Contacts |
78 | 77 | postdata["SNS_LDC"] = cookie_hash_from_string(cookies)["SNS_LDC"] |
79 | 78 | postdata["LTState"] = cookie_hash_from_string(cookies)["LTState"] |
80 | 79 | # raise data.inspect |
81 | - | |
80 | + | |
82 | 81 | data, resp, cookies, forward, old_url = post(LOGIN_URL, postdata.to_query_string, cookies, LOGIN_REFERER_URL) + [LOGIN_REFERER_URL] |
83 | - | |
82 | + | |
84 | 83 | until forward.nil? |
85 | 84 | data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward] |
86 | 85 | end |
87 | - | |
86 | + | |
88 | 87 | if data.index("Invalid Screen Name or Password.") |
89 | 88 | raise AuthenticationError, "Username and password do not match" |
90 | 89 | elsif data.index("Required field must not be blank") |
... | ... | @@ -113,19 +112,19 @@ class Contacts |
113 | 112 | until forward.nil? |
114 | 113 | data, resp, cookies, forward, old_url = get(forward, cookies, old_url) + [forward] |
115 | 114 | end |
116 | - | |
115 | + | |
117 | 116 | if resp.code_type != Net::HTTPOK |
118 | 117 | raise ConnectionError, self.class.const_get(:PROTOCOL_ERROR) |
119 | 118 | end |
120 | 119 | |
121 | 120 | # parse data and grab <input name="user" value="8QzMPIAKs2" type="hidden"> |
122 | - doc = Hpricot(data) | |
123 | - (doc/:input).each do |input| | |
124 | - postdata["user"] = input.attributes["value"] if input.attributes["name"] == "user" | |
121 | + doc = Nokogiri::HTML.fragment data | |
122 | + doc.css('input').each do |input| | |
123 | + postdata["user"] = input["value"] if input["name"] == "user" | |
125 | 124 | end |
126 | - | |
125 | + | |
127 | 126 | data, resp, cookies, forward, old_url = get(CONTACT_LIST_CSV_URL, @cookies, CONTACT_LIST_URL) + [CONTACT_LIST_URL] |
128 | - | |
127 | + | |
129 | 128 | if forward.nil? |
130 | 129 | parse data |
131 | 130 | else |
... | ... | @@ -134,15 +133,15 @@ class Contacts |
134 | 133 | end |
135 | 134 | end |
136 | 135 | private |
137 | - | |
136 | + | |
138 | 137 | def parse(data, options={}) |
139 | 138 | data = CSV.parse(data) |
140 | 139 | col_names = data.shift |
141 | 140 | @contacts = data.map do |person| |
142 | 141 | ["#{person[0]} #{person[1]}", person[4]] unless person[4].empty? |
143 | 142 | end.compact |
144 | - end | |
143 | + end | |
145 | 144 | end |
146 | 145 | |
147 | 146 | TYPES[:aol] = Aol |
148 | -end | |
149 | 147 | \ No newline at end of file |
148 | +end | ... | ... |
vendor/plugins/ruby_bosh/Rakefile
vendor/plugins/ruby_bosh/lib/ruby_bosh.rb
... | ... | @@ -2,10 +2,10 @@ require 'rest_client' |
2 | 2 | require 'builder' |
3 | 3 | require 'rexml/document' |
4 | 4 | require 'base64' |
5 | -require 'hpricot' | |
5 | +require 'nokogiri' | |
6 | 6 | require 'timeout' |
7 | 7 | |
8 | -class RubyBOSH | |
8 | +class RubyBOSH | |
9 | 9 | BOSH_XMLNS = 'http://jabber.org/protocol/httpbind' |
10 | 10 | TLS_XMLNS = 'urn:ietf:params:xml:ns:xmpp-tls' |
11 | 11 | SASL_XMLNS = 'urn:ietf:params:xml:ns:xmpp-sasl' |
... | ... | @@ -24,12 +24,12 @@ class RubyBOSH |
24 | 24 | end |
25 | 25 | |
26 | 26 | attr_accessor :jid, :rid, :sid, :success |
27 | - def initialize(jid, pw, service_url, opts={}) | |
27 | + def initialize(jid, pw, service_url, opts={}) | |
28 | 28 | @service_url = service_url |
29 | 29 | @jid, @pw = jid, pw |
30 | 30 | @host = jid.split("@").last |
31 | 31 | @success = false |
32 | - @timeout = opts[:timeout] || 3 #seconds | |
32 | + @timeout = opts[:timeout] || 3 #seconds | |
33 | 33 | @headers = {"Content-Type" => "text/xml; charset=utf-8", |
34 | 34 | "Accept" => "text/xml"} |
35 | 35 | @wait = opts[:wait] || 5 |
... | ... | @@ -47,7 +47,7 @@ class RubyBOSH |
47 | 47 | |
48 | 48 | def connect |
49 | 49 | initialize_bosh_session |
50 | - if send_auth_request | |
50 | + if send_auth_request | |
51 | 51 | send_restart_request |
52 | 52 | request_resource_binding |
53 | 53 | @success = send_session_request |
... | ... | @@ -55,12 +55,12 @@ class RubyBOSH |
55 | 55 | |
56 | 56 | raise RubyBOSH::AuthFailed, "could not authenticate #{@jid}" unless success? |
57 | 57 | @rid += 1 #updates the rid for the next call from the browser |
58 | - | |
58 | + | |
59 | 59 | [@jid, @sid, @rid] |
60 | 60 | end |
61 | 61 | |
62 | 62 | private |
63 | - def initialize_bosh_session | |
63 | + def initialize_bosh_session | |
64 | 64 | response = deliver(construct_body(:wait => @wait, :to => @host, |
65 | 65 | :hold => @hold, :window => @window, |
66 | 66 | "xmpp:version" => '1.0')) |
... | ... | @@ -72,7 +72,7 @@ class RubyBOSH |
72 | 72 | |
73 | 73 | builder = Builder::XmlMarkup.new |
74 | 74 | parameters = {:rid => @rid, :xmlns => BOSH_XMLNS, |
75 | - "xmpp:version" => "1.0", | |
75 | + "xmpp:version" => "1.0", | |
76 | 76 | "xmlns:xmpp" => "urn:xmpp:xbosh"}.merge(params) |
77 | 77 | |
78 | 78 | if block_given? |
... | ... | @@ -82,10 +82,10 @@ class RubyBOSH |
82 | 82 | end |
83 | 83 | end |
84 | 84 | |
85 | - def send_auth_request | |
85 | + def send_auth_request | |
86 | 86 | request = construct_body(:sid => @sid) do |body| |
87 | - auth_string = "#{@jid}\x00#{@jid.split("@").first.strip}\x00#{@pw}" | |
88 | - body.auth(Base64.encode64(auth_string).gsub(/\s/,''), | |
87 | + auth_string = "#{@jid}\x00#{@jid.split("@").first.strip}\x00#{@pw}" | |
88 | + body.auth(Base64.encode64(auth_string).gsub(/\s/,''), | |
89 | 89 | :xmlns => SASL_XMLNS, :mechanism => 'PLAIN') |
90 | 90 | end |
91 | 91 | |
... | ... | @@ -100,16 +100,16 @@ class RubyBOSH |
100 | 100 | |
101 | 101 | def request_resource_binding |
102 | 102 | request = construct_body(:sid => @sid) do |body| |
103 | - body.iq(:id => "bind_#{rand(100000)}", :type => "set", | |
103 | + body.iq(:id => "bind_#{rand(100000)}", :type => "set", | |
104 | 104 | :xmlns => "jabber:client") do |iq| |
105 | 105 | iq.bind(:xmlns => BIND_XMLNS) do |bind| |
106 | 106 | bind.resource("bosh_#{rand(10000)}") |
107 | 107 | end |
108 | 108 | end |
109 | 109 | end |
110 | - | |
110 | + | |
111 | 111 | response = deliver(request) |
112 | - response.include?("<jid>") | |
112 | + response.include?("<jid>") | |
113 | 113 | end |
114 | 114 | |
115 | 115 | def send_session_request |
... | ... | @@ -117,16 +117,16 @@ class RubyBOSH |
117 | 117 | body.iq(:xmlns => CLIENT_XMLNS, :type => "set", |
118 | 118 | :id => "sess_#{rand(100000)}") do |iq| |
119 | 119 | iq.session(:xmlns => SESSION_XMLNS) |
120 | - end | |
120 | + end | |
121 | 121 | end |
122 | 122 | |
123 | 123 | response = deliver(request) |
124 | - response.include?("body") | |
124 | + response.include?("body") | |
125 | 125 | end |
126 | 126 | |
127 | 127 | def parse(_response) |
128 | - doc = Hpricot(_response.to_s) | |
129 | - doc.search("//body").each do |body| | |
128 | + doc = Nokogiri::HTML.fragment(_response.to_s) | |
129 | + doc.search("body").each do |body| | |
130 | 130 | @sid = body.attributes["sid"].to_s |
131 | 131 | end |
132 | 132 | _response |
... | ... | @@ -156,6 +156,6 @@ end |
156 | 156 | |
157 | 157 | |
158 | 158 | if __FILE__ == $0 |
159 | - p RubyBOSH.initialize_session(ARGV[0], ARGV[1], | |
159 | + p RubyBOSH.initialize_session(ARGV[0], ARGV[1], | |
160 | 160 | "http://localhost:5280/http-bind") |
161 | 161 | end | ... | ... |
vendor/plugins/ruby_bosh/ruby_bosh.gemspec
... | ... | @@ -24,18 +24,15 @@ Gem::Specification.new do |s| |
24 | 24 | if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then |
25 | 25 | s.add_runtime_dependency(%q<builder>, [">= 0"]) |
26 | 26 | s.add_runtime_dependency(%q<adamwiggins-rest-client>, [">= 0"]) |
27 | - s.add_runtime_dependency(%q<hpricot>, [">= 0"]) | |
28 | 27 | s.add_runtime_dependency(%q<SystemTimer>, [">= 0"]) |
29 | 28 | else |
30 | 29 | s.add_dependency(%q<builder>, [">= 0"]) |
31 | 30 | s.add_dependency(%q<adamwiggins-rest-client>, [">= 0"]) |
32 | - s.add_dependency(%q<hpricot>, [">= 0"]) | |
33 | 31 | s.add_dependency(%q<SystemTimer>, [">= 0"]) |
34 | 32 | end |
35 | 33 | else |
36 | 34 | s.add_dependency(%q<builder>, [">= 0"]) |
37 | 35 | s.add_dependency(%q<adamwiggins-rest-client>, [">= 0"]) |
38 | - s.add_dependency(%q<hpricot>, [">= 0"]) | |
39 | 36 | s.add_dependency(%q<SystemTimer>, [">= 0"]) |
40 | 37 | end |
41 | 38 | end | ... | ... |