Commit 313f8a54d53a4fdfa651f02197813026e1660e3b
Exists in
master
and in
28 other branches
Merge commit 'refs/merge-requests/33' of git://gitorious.org/noosfero/noosfero i…
…nto merge-requests/33 (ActionItem2059)
Showing
17 changed files
with
312 additions
and
485 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
... | ... | @@ -177,8 +177,7 @@ class CmsController < MyProfileController |
177 | 177 | @article = @parent = check_parent(params[:parent_id]) |
178 | 178 | @target = @parent ? ('/%s/%s' % [profile.identifier, @parent.full_name]) : '/%s' % profile.identifier |
179 | 179 | @folders = Folder.find(:all, :conditions => { :profile_id => profile }) |
180 | - @media_listing = params[:media_listing] | |
181 | - if @article && !@media_listing | |
180 | + if @article | |
182 | 181 | record_coming |
183 | 182 | end |
184 | 183 | if request.post? && params[:uploaded_files] |
... | ... | @@ -187,26 +186,14 @@ class CmsController < MyProfileController |
187 | 186 | end |
188 | 187 | @errors = @uploaded_files.select { |f| f.errors.any? } |
189 | 188 | if @errors.any? |
190 | - if @media_listing | |
191 | - flash[:notice] = _('Could not upload all files') | |
192 | - redirect_to :action => 'media_listing' | |
193 | - else | |
194 | - render :action => 'upload_files', :parent_id => @parent_id | |
195 | - end | |
189 | + render :action => 'upload_files', :parent_id => @parent_id | |
196 | 190 | else |
197 | - if @media_listing | |
198 | - flash[:notice] = _('All files were uploaded successfully') | |
199 | - redirect_to :action => 'media_listing' | |
191 | + if @back_to | |
192 | + redirect_to @back_to | |
193 | + elsif @parent | |
194 | + redirect_to :action => 'view', :id => @parent.id | |
200 | 195 | else |
201 | - if @back_to | |
202 | - redirect_to @back_to | |
203 | - else | |
204 | - redirect_to( if @parent | |
205 | - {:action => 'view', :id => @parent.id} | |
206 | - else | |
207 | - {:action => 'index'} | |
208 | - end) | |
209 | - end | |
196 | + redirect_to :action => 'index' | |
210 | 197 | end |
211 | 198 | end |
212 | 199 | end |
... | ... | @@ -302,37 +289,21 @@ class CmsController < MyProfileController |
302 | 289 | end |
303 | 290 | end |
304 | 291 | |
305 | - def media_listing | |
306 | - if params[:image_folder_id] | |
307 | - folder = profile.articles.find(params[:image_folder_id]) if !params[:image_folder_id].blank? | |
308 | - @images = (folder ? folder.children : profile.top_level_articles).images | |
309 | - elsif params[:document_folder_id] | |
310 | - folder = profile.articles.find(params[:document_folder_id]) if !params[:document_folder_id].blank? | |
311 | - @documents = (folder ? folder.children : profile.top_level_articles) | |
312 | - else | |
313 | - @documents = profile.articles | |
314 | - @images = @documents.images | |
315 | - @documents -= @images | |
316 | - end | |
317 | - | |
318 | - @images = @images.paginate(:per_page => per_page, :page => params[:ipage], :order => "updated_at desc") if @images | |
319 | - @documents = @documents.paginate(:per_page => per_page, :page => params[:dpage], :order => "updated_at desc", :conditions => {:is_image => false}) if @documents | |
320 | - | |
321 | - @folders = profile.folders | |
322 | - @image_folders = @folders.select {|f| f.children.any? {|c| c.image?} } | |
323 | - @document_folders = @folders.select {|f| f.children.any? {|c| !c.image? && c.kind_of?(UploadedFile) } } | |
324 | - | |
325 | - @media_listing = true | |
326 | - | |
327 | - respond_to do |format| | |
328 | - format.html { render :layout => false} | |
329 | - format.js { | |
330 | - render :update do |page| | |
331 | - page.replace_html 'media-listing-folder-images', :partial => 'image_thumb', :locals => {:images => @images } if !@images.blank? | |
332 | - page.replace_html 'media-listing-folder-documents', :partial => 'document_link', :locals => {:documents => @documents } if !@documents.blank? | |
333 | - end | |
334 | - } | |
292 | + def search | |
293 | + query = params[:q] | |
294 | + results = query.blank? ? [] : profile.articles.published.find_by_contents(query) | |
295 | + render :text => article_list_to_json(results), :content_type => 'application/json' | |
296 | + end | |
297 | + def media_upload | |
298 | + files_uploaded = [] | |
299 | + parent = check_parent(params[:parent_id]) | |
300 | + files = [:file1,:file2, :file3].map { |f| params[f] }.compact | |
301 | + if request.post? | |
302 | + files.each do |file| | |
303 | + files_uploaded << UploadedFile.create(:uploaded_data => file, :profile => profile, :parent => parent) unless file == '' | |
304 | + end | |
335 | 305 | end |
306 | + render :text => article_list_to_json(files_uploaded), :content_type => 'text/plain' | |
336 | 307 | end |
337 | 308 | |
338 | 309 | protected |
... | ... | @@ -366,7 +337,7 @@ class CmsController < MyProfileController |
366 | 337 | end |
367 | 338 | |
368 | 339 | def refuse_blocks |
369 | - if ['TinyMceArticle', 'Event', 'EnterpriseHomepage'].include?(@type) | |
340 | + if ['TinyMceArticle', 'TextileArticle', 'Event', 'EnterpriseHomepage'].include?(@type) | |
370 | 341 | @no_design_blocks = true |
371 | 342 | end |
372 | 343 | end |
... | ... | @@ -380,5 +351,17 @@ class CmsController < MyProfileController |
380 | 351 | @selected_locale = @article.language || FastGettext.locale |
381 | 352 | end |
382 | 353 | |
354 | + def article_list_to_json(list) | |
355 | + list.map do |item| | |
356 | + { | |
357 | + 'title' => item.title, | |
358 | + 'url' => item.image? ? item.public_filename(:uploaded) : url_for(item.url), | |
359 | + :icon => icon_for_article(item), | |
360 | + :content_type => item.mime_type, | |
361 | + :error => item.errors.any? ? _('%s could not be uploaded') % item.title : nil, | |
362 | + } | |
363 | + end.to_json | |
364 | + end | |
365 | + | |
383 | 366 | end |
384 | 367 | ... | ... |
app/views/cms/_document_link.rhtml
... | ... | @@ -1,10 +0,0 @@ |
1 | -<div id='media-listing-folder-documents' > | |
2 | - <ul> | |
3 | - <% documents.each do |document| %> | |
4 | - <li><%= link_to(document.name, document.view_url, :class => icon_for_article(document)) %></li> | |
5 | - <% end %> | |
6 | - </ul> | |
7 | - <div id='pagination-documents'> | |
8 | - <%= pagination_links documents, :param_name => 'dpage', :params => {:document_folder_id => params[:document_folder_id]} %> | |
9 | - </div> | |
10 | -</div> |
app/views/cms/_image_thumb.rhtml
... | ... | @@ -1,10 +0,0 @@ |
1 | -<div id='media-listing-folder-images' > | |
2 | - <ul> | |
3 | - <% images.each do |image| %> | |
4 | - <li><%= image_tag image.public_filename %></li> | |
5 | - <% end %> | |
6 | - </ul> | |
7 | - <div id='pagination-images'> | |
8 | - <%= pagination_links images, :param_name => 'ipage', :params => {:image_folder_id => params[:image_folder_id]} %> | |
9 | - </div> | |
10 | -</div> |
app/views/cms/_media_listing.rhtml
app/views/cms/_select_folder.rhtml
... | ... | @@ -1 +0,0 @@ |
1 | -<%= select('folder', 'folder_id', @image_folders.collect {|f| [ f.name, f.id ] }, {:include_blank => "#{profile.identifier}"}, :onchange => remote_function(:update => 'media-listing-folder-images', :with => "'folder_id=' + value", :url => { :action => :get_images }) ) %> |
... | ... | @@ -0,0 +1,44 @@ |
1 | +<div class='text-editor-sidebar'> | |
2 | + <%= render(:partial => 'textile_quick_reference') if @article.is_a?(TextileArticle) %> | |
3 | + <div class='text-editor-sidebar-box' id='media-upload-box'> | |
4 | + <p><strong><%= _('Media upload') %></strong></p> | |
5 | + <div id='media-upload-form'> | |
6 | + <% form_tag({ :action => 'media_upload' }, :multipart => true) do %> | |
7 | + <div class='formfield'> | |
8 | + <%# TODO duplicated from partial upload_file_form %> | |
9 | + <%= labelled_form_field(_('Choose folder to upload files:'), select_tag('parent_id', options_for_select([[profile.identifier, '']] + profile.folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id ] }))) %> | |
10 | + </div> | |
11 | + <p><%= file_field_tag('file1') %></p> | |
12 | + <p><%= file_field_tag('file2') %></p> | |
13 | + <p><%= file_field_tag('file3') %></p> | |
14 | + <% button_bar do %> | |
15 | + <%= submit_button(:save, _('Upload')) %> | |
16 | + <% end %> | |
17 | + <% end %> | |
18 | + </div> | |
19 | + <div id='media-upload-results' style='display: none'> | |
20 | + <%= render :partial => 'drag_and_drop_note' %> | |
21 | + <div class='items'> | |
22 | + </div> | |
23 | + <p><%= link_to(_('Upload more files ...'), '#', :id => 'media-upload-more-files')%></p> | |
24 | + </div> | |
25 | + </div> | |
26 | + <div id='media-search-box' class='text-editor-sidebar-box'> | |
27 | + <p><strong><%= _('Media search') %></strong></p> | |
28 | + <p> | |
29 | + <% form_tag({ :action => 'search' }) do %> | |
30 | + <span class='formfield'> | |
31 | + <input name='q' type='text' id='media-search-query' style='width: 250px;'/> | |
32 | + </span> | |
33 | + <%= submit_button :search, _('Search'), :id => 'media-search-button' %> | |
34 | + <% end %> | |
35 | + </p> | |
36 | + <div id='media-search-results' style='display: none'> | |
37 | + <%= render :partial => 'drag_and_drop_note' %> | |
38 | + <div class='items'> | |
39 | + </div> | |
40 | + </div> | |
41 | + </div> | |
42 | +</div> | |
43 | + | |
44 | + | ... | ... |
app/views/cms/_textile_article.rhtml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | |
3 | 3 | <%# TODO add Textile help here %> |
4 | 4 | |
5 | -<%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '64')) %> | |
5 | +<%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '72')) %> | |
6 | 6 | |
7 | 7 | <%= render :partial => 'translatable' %> |
8 | 8 | <%= render :partial => 'shared/lead_and_body' %> | ... | ... |
... | ... | @@ -0,0 +1,28 @@ |
1 | +<div class='text-editor-sidebar-box'> | |
2 | + <p> | |
3 | + <strong><%= _('Textile markup quick reference') %></strong> | |
4 | + <%= link_to(_('(show)'), '#', :id => 'textile-quickref-show') %> | |
5 | + <%= link_to(_('(hide)'), '#', :id => 'textile-quickref-hide', :style => 'display: none') %> | |
6 | + </p> | |
7 | + <div id='textile-quickref' style='display: none;'> | |
8 | + <p><%= _('Simple formatting:') %> <code>_<%= _('italics') %>_</code> <code>*<%= _('bold') %>*</code>, <code>-<%= _('striked')%>-</code>.</p> | |
9 | + <p><%= _('Links:') %> <code>"Noosfero":http://noosfero.org/</code></p> | |
10 | + <p><%= _('Images:') %> <code>!http://example.com/image.png!</code></p> | |
11 | + <p><%= _('Bullet lists:') %></p> | |
12 | + <pre>* <%= _('first item') %> | |
13 | +* <%= _('second item') %></pre> | |
14 | + <p><%= _('Numbered lists:') %></p> | |
15 | + <pre># <%= _('first item') %> | |
16 | +# <%= _('second item') %></pre> | |
17 | + <p><%= h(_('For code, use HTML tags <pre> and <code>, and indent the code inside them:')) %> | |
18 | + <pre> | |
19 | +<pre> | |
20 | +<code> | |
21 | + a.gsub!( /</, '' ) | |
22 | +</code> | |
23 | +</pre> | |
24 | +</pre> | |
25 | + <p><%= _('See also a more complete <a href="%s">Textile Reference</a>.') % 'http://redcloth.org/hobix.com/textile/' %></p> | |
26 | + </div> | |
27 | +</div> | |
28 | + | ... | ... |
app/views/cms/_upload_file_form.rhtml
1 | 1 | <% if @parent %> |
2 | 2 | <%= hidden_field_tag('parent_id', @parent.id) %> |
3 | 3 | <% else %> |
4 | - <h4><%= _('Choose folder to upload files:') %></h4> | |
5 | - <%= select_tag('parent_id', options_for_select([[profile.identifier, '']] + @folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id ] })) %> | |
4 | + <%= labelled_form_field(_('Choose folder to upload files:'), select_tag('parent_id', options_for_select([[profile.identifier, '']] + @folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id ] }))) %> | |
6 | 5 | <% end %> |
7 | 6 | |
8 | 7 | <div id='uploaded_files'> |
... | ... | @@ -15,9 +14,7 @@ |
15 | 14 | |
16 | 15 | <% button_bar do %> |
17 | 16 | <%= add_upload_file_field(_('More files'), {:size => size}) %> |
18 | - <% if @media_listing %> | |
19 | - <%= submit_button :save, _('Upload') %> | |
20 | - <% elsif @back_to %> | |
17 | + <% if @back_to %> | |
21 | 18 | <%= submit_button :save, _('Upload'), :cancel => @back_to %> |
22 | 19 | <% else %> |
23 | 20 | <%= submit_button :save, _('Upload'), :cancel => {:action => (@parent ? 'view' : 'index'), :id => @parent } %> | ... | ... |
app/views/cms/edit.rhtml
... | ... | @@ -49,8 +49,8 @@ |
49 | 49 | <% end %> |
50 | 50 | </div> |
51 | 51 | |
52 | -<% if environment.enabled?('media_panel') && [TinyMceArticle, Event, EnterpriseHomepage].any?{|klass| @article.kind_of?(klass)} %> | |
53 | - <%= render :partial => 'media_listing' %> | |
52 | +<% if environment.enabled?('media_panel') && [TinyMceArticle, TextileArticle, Event, EnterpriseHomepage].any?{|klass| @article.kind_of?(klass)} %> | |
53 | + <%= render :partial => 'text_editor_sidebar' %> | |
54 | 54 | <% end %> |
55 | 55 | |
56 | 56 | <br style='clear: both'/> | ... | ... |
app/views/cms/media_listing.rhtml
... | ... | @@ -1,75 +0,0 @@ |
1 | -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= html_language %>" lang="<%= html_language %>"> | |
2 | -<head> | |
3 | - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
4 | - <%= stylesheet_link_tag 'application', 'media_listing', :cache => 'cache-media-listing' %> | |
5 | - <%= stylesheet_import 'button', :themed_source => true %> | |
6 | - <%= javascript_include_tag :defaults %> | |
7 | - <%= javascript_include_tag 'lowpro' %> | |
8 | - <%= stylesheet_link_tag icon_theme_stylesheet_path %> | |
9 | -</head> | |
10 | -<body class='noosfero'> | |
11 | - <script type="text/javascript"> | |
12 | - /* Adds a class to "msie" to the body element if a Microsoft browser is | |
13 | - * detected. This is needed to workaround several of their limitations. | |
14 | - */ | |
15 | - if ( navigator.appVersion.indexOf("MSIE") > -1 ) { | |
16 | - document.body.className += " msie msie" + | |
17 | - navigator.appVersion.replace(/^.*MSIE\s+([0-9]+).*$/, "$1"); | |
18 | - } | |
19 | - function registerDocumentSize() { | |
20 | - document.body.className = document.body.className.replace(/(^| )docSize.+( |$)/g, " "); | |
21 | - for ( var x=100; x<=1500; x+=100 ) { | |
22 | - if ( document.body.clientWidth > x ) { | |
23 | - document.body.className += " docSize-GT-" + x; | |
24 | - } else { | |
25 | - document.body.className += " docSize-LT-" + x; | |
26 | - } | |
27 | - } | |
28 | - } | |
29 | - registerDocumentSize(); | |
30 | - </script> | |
31 | - <div id='media-listing-upload'> | |
32 | - <p><%= _("Include files in some folder or select from the list below to add images and documents to the text editor beside (max size %s)") % UploadedFile.max_size.to_humanreadable %></p> | |
33 | - | |
34 | - <div id="notice" onclick="Element.hide('notice');" style="display:none"> | |
35 | - <% unless flash[:notice].nil? %> | |
36 | - <%= flash[:notice] %> | |
37 | - <%= javascript_tag(visual_effect( :appear, 'notice')) %> | |
38 | - <% end %> | |
39 | - </div> | |
40 | - | |
41 | - <% form_for('uploaded_file', :url => {:action => 'upload_files'}, :html => {:multipart => true}) do |f| %> | |
42 | - <%= hidden_field_tag('media_listing', @media_listing) %> | |
43 | - <%= render :partial => 'upload_file_form', :locals => { :size => '30' } %> | |
44 | - <% end %> | |
45 | - </div><!-- id='media-listing-upload' --> | |
46 | - <hr/> | |
47 | - | |
48 | - <script type='text/javascript'> | |
49 | - document.observe("dom:loaded", function() { | |
50 | - Event.addBehavior.reassignAfterAjax = true; | |
51 | - Event.addBehavior({ | |
52 | - 'div#pagination-images .pagination a' : Remote.Link, | |
53 | - 'div#pagination-documents .pagination a' : Remote.Link | |
54 | - }) | |
55 | - }); | |
56 | - </script> | |
57 | - | |
58 | - <div id='media-listing'> | |
59 | - <h3><%= _('Folders') %></h3> | |
60 | - <p><%= _('Drag images and documents to add them to the text. If needed, resize images by clicking the tree icon on editor.') %></p> | |
61 | - | |
62 | - <div id='media-listing-images'> | |
63 | - <h4><%= _('Images') %></h4> | |
64 | - <%= select_folder('', 'folder', 'image_folder_id', @image_folders, {}, :onchange => remote_function(:with => "'image_folder_id=' + value + '&ipage=1'", :url => { :action => :media_listing, :format => 'js' }) ) %> | |
65 | - <%= render :partial => 'image_thumb', :locals => { :images => @images } %> | |
66 | - </div><!-- id='media-listing-images' --> | |
67 | - <div id='media-listing-documents'> | |
68 | - <h4><%= _('Documents') %></h4> | |
69 | - <%= select_folder('', 'folder', 'document_folder_id', @document_folders, {}, :onchange => remote_function(:with => "'document_folder_id=' + value + '&dpage=1'", :url => { :action => :media_listing }) ) %> | |
70 | - <%= render :partial => 'document_link', :locals => { :documents => @documents } %> | |
71 | - </div><!-- id='media-listing-documents' --> | |
72 | - <br style="clear:both" /> | |
73 | - </div><!-- id='media-listing' --> | |
74 | -</body> | |
75 | -</html> |
lib/delayed_attachment_fu.rb
... | ... | @@ -38,7 +38,11 @@ module DelayedAttachmentFu |
38 | 38 | end |
39 | 39 | |
40 | 40 | def public_filename(size=nil) |
41 | - if !self.thumbnailable? || self.thumbnails_processed | |
41 | + force = (size == :uploaded) | |
42 | + if force | |
43 | + size = nil | |
44 | + end | |
45 | + if !self.thumbnailable? || self.thumbnails_processed || force | |
42 | 46 | super(size) |
43 | 47 | else |
44 | 48 | size ||= 'thumb' | ... | ... |
public/javascripts/article.js
1 | -(function($) { | |
1 | +jQuery(function($) { | |
2 | 2 | $(".lead-button").live('click', function(){ |
3 | 3 | article_id = this.getAttribute("article_id"); |
4 | 4 | $(this).toggleClass('icon-add').toggleClass('icon-remove'); |
... | ... | @@ -10,4 +10,67 @@ |
10 | 10 | $('#article-body-field').slideToggle(); |
11 | 11 | return false; |
12 | 12 | }) |
13 | -})(jQuery) | |
13 | + | |
14 | + $("#textile-quickref-show").click(function(){ | |
15 | + $('#textile-quickref-hide').show(); | |
16 | + $(this).hide(); | |
17 | + $('#textile-quickref').slideToggle(); | |
18 | + return false; | |
19 | + }) | |
20 | + $("#textile-quickref-hide").click(function(){ | |
21 | + $('#textile-quickref-show').show(); | |
22 | + $(this).hide(); | |
23 | + $('#textile-quickref').slideToggle(); | |
24 | + return false; | |
25 | + }) | |
26 | + function insert_items(items, selector) { | |
27 | + var html_for_items = ''; | |
28 | + $.each(items, function(i, item) { | |
29 | + if (item.error) { | |
30 | + html_for_items += '<div class="media-upload-error">' + item.error + '</div>'; | |
31 | + return; | |
32 | + } | |
33 | + if (item.content_type && item.content_type.match(/^image/)) { | |
34 | + html_for_items += '<div class="icon-photos"><img src="' + item.url + '"/><br/><a href="' + item.url + '">' + item.title + '</a></div>'; | |
35 | + } else { | |
36 | + html_for_items += '<div class="' + item.icon + '"><a href="' + item.url + '">' + item.title + '</a></div>'; | |
37 | + } | |
38 | + }); | |
39 | + $(selector).html(html_for_items); | |
40 | + } | |
41 | + $('#media-search-button').click(function() { | |
42 | + var query = '*' + $('#media-search-query').val() + '*'; | |
43 | + var $button = $(this); | |
44 | + $('#media-search-box').toggleClass('icon-loading'); | |
45 | + $.get($(this).parent().attr('action'), { 'q': query }, function(data) { | |
46 | + insert_items(data, '#media-search-results .items'); | |
47 | + if (data.length && data.length > 0) { | |
48 | + $('#media-search-results').slideDown(); | |
49 | + } | |
50 | + $('#media-search-box').toggleClass('icon-loading'); | |
51 | + }); | |
52 | + return false; | |
53 | + }); | |
54 | + $('#media-upload-form form').ajaxForm({ | |
55 | + dataType: 'json', | |
56 | + resetForm: true, | |
57 | + beforeSubmit: | |
58 | + function() { | |
59 | + $('#media-upload-form').slideUp(); | |
60 | + $('#media-upload-box').toggleClass('icon-loading'); | |
61 | + }, | |
62 | + success: | |
63 | + function(data) { | |
64 | + insert_items(data, '#media-upload-results .items'); | |
65 | + if (data.length && data.length > 0) { | |
66 | + $('#media-upload-results').slideDown(); | |
67 | + } | |
68 | + $('#media-upload-box').toggleClass('icon-loading'); | |
69 | + } | |
70 | + }); | |
71 | + $('#media-upload-more-files').click(function() { | |
72 | + $('#media-upload-results').hide(); | |
73 | + $('#media-upload-form').show(); | |
74 | + }); | |
75 | + | |
76 | +}); | ... | ... |
public/stylesheets/application.css
... | ... | @@ -2768,6 +2768,7 @@ div#activation_enterprise div { |
2768 | 2768 | border-top: none; |
2769 | 2769 | border-left: none; |
2770 | 2770 | color: #585858; |
2771 | + font-size: 11px; | |
2771 | 2772 | } |
2772 | 2773 | .formfield input { |
2773 | 2774 | text-indent: 5px; |
... | ... | @@ -3343,21 +3344,7 @@ table.cms-articles .icon:hover { |
3343 | 3344 | display: block; |
3344 | 3345 | } |
3345 | 3346 | |
3346 | -/* Media listing */ | |
3347 | - | |
3348 | -.controller-cms #media-listing-iframe { | |
3349 | - float: right; | |
3350 | - width: 380px; | |
3351 | - height: 630px; | |
3352 | - border: none; | |
3353 | - margin-top: 104px; | |
3354 | - padding: 0px; | |
3355 | - overflow: hidden; | |
3356 | -} | |
3357 | - | |
3358 | -.controller-cms .msie #media-listing-iframe { | |
3359 | - height: 610px; | |
3360 | -} | |
3347 | +/* Text editors sidebar */ | |
3361 | 3348 | |
3362 | 3349 | .controller-cms div.with_media_panel { |
3363 | 3350 | float: left; |
... | ... | @@ -3368,6 +3355,64 @@ div.with_media_panel .formfield input { |
3368 | 3355 | width: 100%; |
3369 | 3356 | } |
3370 | 3357 | |
3358 | +.text-editor-sidebar { | |
3359 | + position: absolute; | |
3360 | + width: 380px; | |
3361 | + right: 20px; | |
3362 | + top: 70px; | |
3363 | +} | |
3364 | + | |
3365 | +.text-editor-sidebar-box { | |
3366 | + background: #eeeeec; | |
3367 | + border: 1px solid #d3d7cf; | |
3368 | + padding: 10px 10px 0px 10px; | |
3369 | + margin-bottom: 10px; | |
3370 | +} | |
3371 | +.text-editor-sidebar-box p { | |
3372 | + margin-top: 0px; | |
3373 | +} | |
3374 | +.text-editor-sidebar code, | |
3375 | +.text-editor-sidebar pre { | |
3376 | + border: 1px solid #d3d7cf; | |
3377 | + color: black; | |
3378 | + padding: 2px; | |
3379 | +} | |
3380 | +.text-editor-sidebar .icon-loading { | |
3381 | + background-image: url(../images/loading-small.gif); | |
3382 | +} | |
3383 | +.text-editor-sidebar .items { | |
3384 | + margin-bottom: 10px; | |
3385 | +} | |
3386 | +.text-editor-sidebar .items div { | |
3387 | + background-repeat: no-repeat; | |
3388 | + background-position: 0px 0px; | |
3389 | + padding-left: 20px; | |
3390 | + padding-top: 2px; | |
3391 | + padding-bottom: 2px; | |
3392 | + border: none; | |
3393 | + margin-bottom: 2px; | |
3394 | +} | |
3395 | +.text-editor-sidebar .items :hover { | |
3396 | + background-color: transparent; | |
3397 | + border: none; | |
3398 | +} | |
3399 | +.text-editor-sidebar #media-upload-box, | |
3400 | +.text-editor-sidebar #media-search-box { | |
3401 | + background-repeat: no-repeat; | |
3402 | + background-position: 98% 10px; | |
3403 | +} | |
3404 | +.text-editor-sidebar img { | |
3405 | + max-height: 96px; | |
3406 | + max-width: 96px; | |
3407 | + border: 1px solid #d3d7cf; | |
3408 | +} | |
3409 | +.text-editor-sidebar .media-upload-error { | |
3410 | + color: red; | |
3411 | +} | |
3412 | +.text-editor-sidebar select { | |
3413 | + max-width: 355px; | |
3414 | +} | |
3415 | + | |
3371 | 3416 | /* ==> public/stylesheets/controller_contact.css <== */ |
3372 | 3417 | /*** SELECT CITY ***/ |
3373 | 3418 | ... | ... |
public/stylesheets/media_listing.css
... | ... | @@ -1,167 +0,0 @@ |
1 | -body { | |
2 | - padding: 0px; | |
3 | - margin: 0px; | |
4 | - font-family: Verdana, sans-serif; | |
5 | - font-size: 14px; | |
6 | - color: #444; | |
7 | - background-color: #F0F0EE; | |
8 | - overflow: hidden; | |
9 | -} | |
10 | - | |
11 | -h3, h4, h5 { | |
12 | - margin: 5px 0px; | |
13 | -} | |
14 | - | |
15 | -h3 { | |
16 | - font-size: 18px; | |
17 | -} | |
18 | - | |
19 | -h4 { | |
20 | - font-size: 16px; | |
21 | -} | |
22 | - | |
23 | -#media-listing { | |
24 | - width: 100%; | |
25 | - height: 48%; | |
26 | - margin: 0px; | |
27 | - padding: 0px; | |
28 | - padding-bottom: 5px; | |
29 | -} | |
30 | - | |
31 | -#media-listing-upload p, | |
32 | -#media-listing p { | |
33 | - font-size: 13px; | |
34 | - font-weight: bold; | |
35 | - margin: 5px 5px; | |
36 | -} | |
37 | - | |
38 | -#media-listing li { | |
39 | - list-style: none; | |
40 | - margin: 0px; | |
41 | -} | |
42 | - | |
43 | -#media-listing li:hover { | |
44 | - background-color: #CCC; | |
45 | -} | |
46 | - | |
47 | -#media-listing a { | |
48 | - text-decoration: none; | |
49 | -} | |
50 | - | |
51 | -#media-listing select { | |
52 | - width: 80%; | |
53 | -} | |
54 | - | |
55 | -#media-listing-images { | |
56 | - width: 46%; | |
57 | - float: left; | |
58 | - text-align: center; | |
59 | -} | |
60 | - | |
61 | -#media-listing-images img { | |
62 | - max-width: 80px; | |
63 | - max-height: 60px; | |
64 | -} | |
65 | - | |
66 | -.msie6 #media-listing-images img, | |
67 | -.msie7 #media-listing-images img { | |
68 | - width: 80px; | |
69 | - height: 60px; | |
70 | -} | |
71 | - | |
72 | -#media-listing-folder-images, | |
73 | -#media-listing-folder-documents { | |
74 | - height: 80%; | |
75 | -} | |
76 | - | |
77 | -#media-listing ul { | |
78 | - padding: 0px; | |
79 | - margin: 5px; | |
80 | - height: 40%; | |
81 | - overflow: auto; | |
82 | - width: 98%; | |
83 | -} | |
84 | - | |
85 | -#media-listing ul { | |
86 | - height: 85%; | |
87 | -} | |
88 | - | |
89 | -#media-listing-images, | |
90 | -#media-listing-documents { | |
91 | - height: 55%; | |
92 | -} | |
93 | - | |
94 | -#media-listing-documents ul { | |
95 | - text-align: left; | |
96 | -} | |
97 | - | |
98 | -#media-listing-documents { | |
99 | - width: 52%; | |
100 | - float: left; | |
101 | - text-align: center; | |
102 | -} | |
103 | - | |
104 | -#media-listing-documents li { | |
105 | - padding-bottom: 5px; | |
106 | -} | |
107 | - | |
108 | -#media-listing-folder-documents a.icon { | |
109 | - background-repeat: no-repeat; | |
110 | - padding-left: 20px; | |
111 | - border: none; | |
112 | -} | |
113 | - | |
114 | -#media-listing-folder-documents .icon:hover { | |
115 | - background-color: transparent; | |
116 | -} | |
117 | - | |
118 | -#media-listing .icon-rss-feed { | |
119 | - background-image: url(../images/icons-mime/rss-feed-16.png); | |
120 | -} | |
121 | - | |
122 | -#media-listing-upload { | |
123 | - width: 98%; | |
124 | - padding: 3px; | |
125 | -} | |
126 | - | |
127 | -#media-listing-upload p { | |
128 | - margin: 5px 0px; | |
129 | -} | |
130 | - | |
131 | -#media-listing-upload select { | |
132 | - width: 90%; | |
133 | -} | |
134 | - | |
135 | -#uploaded_files { | |
136 | - overflow-x: hidden; | |
137 | - overflow-y: scroll; | |
138 | - height: 100px; | |
139 | - margin-top: 5px; | |
140 | -} | |
141 | - | |
142 | -.msie #uploaded_files { | |
143 | - height: 100px; | |
144 | - padding: 0px; | |
145 | -} | |
146 | - | |
147 | -.formlabel { | |
148 | - font-size: 11px; | |
149 | - display: block; | |
150 | -} | |
151 | - | |
152 | -/* Notice */ | |
153 | - | |
154 | -div#notice { | |
155 | - background: #fee; | |
156 | - border: 1px solid #933; | |
157 | - top: 150px; | |
158 | - color: black; | |
159 | - cursor: pointer; | |
160 | - font-weight: bold; | |
161 | - left: 50%; | |
162 | - margin-left: -150px; | |
163 | - padding: 5px; | |
164 | - position: absolute; | |
165 | - text-align: center; | |
166 | - width: 300px; | |
167 | -} |
test/functional/cms_controller_test.rb
... | ... | @@ -1064,7 +1064,7 @@ class CmsControllerTest < Test::Unit::TestCase |
1064 | 1064 | assert_tag :tag => 'input', :attributes => { :name => 'article[external_feed_builder][only_once]', :checked => 'checked', :value => 'true' } |
1065 | 1065 | end |
1066 | 1066 | |
1067 | - should 'display iframe for media listing when it is TinyMceArticle and enabled on environment' do | |
1067 | + should 'display media listing when it is TinyMceArticle and enabled on environment' do | |
1068 | 1068 | e = Environment.default |
1069 | 1069 | e.enable('media_panel') |
1070 | 1070 | e.save! |
... | ... | @@ -1076,10 +1076,10 @@ class CmsControllerTest < Test::Unit::TestCase |
1076 | 1076 | file = UploadedFile.create!(:profile => profile, :parent => non_image_folder, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) |
1077 | 1077 | |
1078 | 1078 | get :new, :profile => profile.identifier, :type => 'TinyMceArticle' |
1079 | - assert_tag :tag => 'iframe', :attributes => { :src => "/myprofile/#{profile.identifier}/cms/media_listing?type=TinyMceArticle" } | |
1079 | + assert_tag :div, :attributes => { :class => "text-editor-sidebar" } | |
1080 | 1080 | end |
1081 | 1081 | |
1082 | - should 'not display iframe for media listing when it is Folder' do | |
1082 | + should 'not display media listing when it is Folder' do | |
1083 | 1083 | image_folder = Folder.create(:profile => profile, :name => 'Image folder') |
1084 | 1084 | non_image_folder = Folder.create(:profile => profile, :name => 'Non image folder') |
1085 | 1085 | |
... | ... | @@ -1087,145 +1087,7 @@ class CmsControllerTest < Test::Unit::TestCase |
1087 | 1087 | file = UploadedFile.create!(:profile => profile, :parent => non_image_folder, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) |
1088 | 1088 | |
1089 | 1089 | get :new, :profile => profile.identifier, :type => 'Folder' |
1090 | - assert_no_tag :tag => 'iframe', :attributes => { :src => "/myprofile/#{profile.identifier}/cms/media_listing" } | |
1091 | - end | |
1092 | - | |
1093 | - should 'display list of images' do | |
1094 | - file = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | |
1095 | - process_delayed_job_queue | |
1096 | - get :media_listing, :profile => profile.identifier | |
1097 | - | |
1098 | - assert_tag :tag => 'div', :attributes => { :id => 'media-listing-images' }, :descendant => { :tag => 'img', :attributes => {:src => /rails.png/}} | |
1099 | - end | |
1100 | - | |
1101 | - should 'display loading image if not processed yet' do | |
1102 | - file = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | |
1103 | - get :media_listing, :profile => profile.identifier | |
1104 | - | |
1105 | - assert_tag :tag => 'div', :attributes => { :id => 'media-listing-images' }, :descendant => { :tag => 'img', :attributes => {:src => /image-loading-thumb.png/}} | |
1106 | - end | |
1107 | - | |
1108 | - | |
1109 | - should 'display list of documents' do | |
1110 | - file = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) | |
1111 | - get :media_listing, :profile => profile.identifier | |
1112 | - assert_tag :tag => 'div', :attributes => { :id => 'media-listing-documents' }, :descendant => { :tag => 'a', :attributes => {:href => /#{file.name}/}} | |
1113 | - end | |
1114 | - | |
1115 | - should 'list image folders to select' do | |
1116 | - image_folder = Folder.create(:profile => profile, :name => 'Image folder') | |
1117 | - non_image_folder = Folder.create(:profile => profile, :name => 'Non image folder') | |
1118 | - | |
1119 | - image = UploadedFile.create!(:profile => profile, :parent => image_folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | |
1120 | - file = UploadedFile.create!(:profile => profile, :parent => non_image_folder, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) | |
1121 | - | |
1122 | - get :media_listing, :profile => profile.identifier | |
1123 | - assert_tag :tag => 'div', :attributes => { :id => 'media-listing-images' }, :descendant => { :tag => 'option', :content => /#{image_folder.name}/, :attributes => { :value => image_folder.id}} | |
1124 | - assert_no_tag :tag => 'div', :attributes => { :id => 'media-listing-images' }, :descendant => { :tag => 'option', :content => /#{non_image_folder.name}/, :attributes => { :value => non_image_folder.id}} | |
1125 | - end | |
1126 | - | |
1127 | - should 'list documents folders to select' do | |
1128 | - image_folder = Folder.create(:profile => profile, :name => 'Image folder') | |
1129 | - non_image_folder = Folder.create(:profile => profile, :name => 'Non image folder') | |
1130 | - | |
1131 | - image = UploadedFile.create!(:profile => profile, :parent => image_folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | |
1132 | - file = UploadedFile.create!(:profile => profile, :parent => non_image_folder, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) | |
1133 | - | |
1134 | - get :media_listing, :profile => profile.identifier | |
1135 | - assert_no_tag :tag => 'div', :attributes => { :id => 'media-listing-documents' }, :descendant => { :tag => 'option', :content => /#{image_folder.name}/, :attributes => { :value => image_folder.id}} | |
1136 | - assert_tag :tag => 'div', :attributes => { :id => 'media-listing-documents' }, :descendant => { :tag => 'option', :content => /#{non_image_folder.name}/, :attributes => { :value => non_image_folder.id}} | |
1137 | - end | |
1138 | - | |
1139 | - should 'get a list of images from a image folder' do | |
1140 | - folder = Folder.create(:profile => profile, :name => 'Image folder') | |
1141 | - other_folder = Folder.create(:profile => profile, :name => 'Non image folder') | |
1142 | - image = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | |
1143 | - file_in_folder = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) | |
1144 | - image_in_other_folder = UploadedFile.create!(:profile => profile, :parent => other_folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | |
1145 | - | |
1146 | - get :media_listing, :profile => profile.identifier, :image_folder_id => folder.id, :format => 'js' | |
1147 | - | |
1148 | - assert_includes assigns(:images), image | |
1149 | - assert_not_includes assigns(:images), file_in_folder | |
1150 | - assert_not_includes assigns(:images), image_in_other_folder | |
1151 | - end | |
1152 | - | |
1153 | - should 'get a list of images from profile' do | |
1154 | - image = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | |
1155 | - folder = Folder.create(:profile => profile, :name => 'Image folder') | |
1156 | - image_in_folder = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | |
1157 | - get :media_listing, :profile => profile.identifier, :image_folder_id => '', :format => 'js' | |
1158 | - | |
1159 | - assert_includes assigns(:images), image | |
1160 | - assert_not_includes assigns(:images), image_in_folder | |
1161 | - end | |
1162 | - | |
1163 | - should 'get a list of documents from a document folder' do | |
1164 | - folder = Folder.create(:profile => profile, :name => 'Non images folder') | |
1165 | - other_folder = Folder.create(:profile => profile, :name => 'Image folder') | |
1166 | - file = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) | |
1167 | - image = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | |
1168 | - file_in_other_folder = UploadedFile.create!(:profile => profile, :parent => other_folder, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) | |
1169 | - | |
1170 | - get :media_listing, :profile => profile.identifier, :document_folder_id => folder.id, :format => 'js' | |
1171 | - | |
1172 | - assert_includes assigns(:documents), file | |
1173 | - assert_not_includes assigns(:documents), image | |
1174 | - assert_not_includes assigns(:documents), file_in_other_folder | |
1175 | - end | |
1176 | - | |
1177 | - should 'get a list of documents from profile' do | |
1178 | - file = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) | |
1179 | - folder = Folder.create(:profile => profile, :name => 'Image folder') | |
1180 | - file_in_folder = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) | |
1181 | - | |
1182 | - get :media_listing, :profile => profile.identifier, :document_folder_id => '', :format => 'js' | |
1183 | - | |
1184 | - assert_includes assigns(:documents), file | |
1185 | - assert_not_includes assigns(:documents), file_in_folder | |
1186 | - end | |
1187 | - | |
1188 | - should 'display pagination links of images' do | |
1189 | - @controller.stubs(:per_page).returns(1) | |
1190 | - | |
1191 | - image = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg')) | |
1192 | - image2 = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :created_at => 1.day.ago) | |
1193 | - image2.updated_at = 1.day.ago | |
1194 | - image2.send :update_without_callbacks | |
1195 | - | |
1196 | - get :media_listing, :profile => profile.identifier | |
1197 | - | |
1198 | - assert_includes assigns(:images), image | |
1199 | - assert_not_includes assigns(:images), image2 | |
1200 | - end | |
1201 | - | |
1202 | - should 'display pagination links of documents' do | |
1203 | - @controller.stubs(:per_page).returns(1) | |
1204 | - profile.articles.destroy_all | |
1205 | - file = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/feed.xml', 'text/xml')) | |
1206 | - file2 = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) | |
1207 | - file2.created_at = 1.day.ago | |
1208 | - file2.save! | |
1209 | - | |
1210 | - get :media_listing, :profile => profile.identifier | |
1211 | - | |
1212 | - assert_includes assigns(:documents), file | |
1213 | - assert_not_includes assigns(:documents), file2 | |
1214 | - end | |
1215 | - | |
1216 | - | |
1217 | - should 'redirect to media listing when upload files from there' do | |
1218 | - post :upload_files, :profile => profile.identifier, :media_listing => true, :uploaded_files => [fixture_file_upload('files/rails.png', 'image/png')] | |
1219 | - assert_template nil | |
1220 | - assert_redirected_to :action => 'media_listing' | |
1221 | - end | |
1222 | - | |
1223 | - should 'redirect to media listing when occur errors when upload files from there' do | |
1224 | - file = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('files/rails.png', 'image/png')) | |
1225 | - | |
1226 | - post :upload_files, :profile => profile.identifier, :media_listing => true, :uploaded_files => [fixture_file_upload('files/rails.png', 'image/png')] | |
1227 | - assert_template nil | |
1228 | - assert_redirected_to :action => 'media_listing' | |
1090 | + assert_no_tag :div, :attributes => { :id => "text-editor-sidebar" } | |
1229 | 1091 | end |
1230 | 1092 | |
1231 | 1093 | should "display 'Publish' when profile is a person" do |
... | ... | @@ -1618,4 +1480,67 @@ class CmsControllerTest < Test::Unit::TestCase |
1618 | 1480 | end |
1619 | 1481 | end |
1620 | 1482 | |
1483 | + should 'search for content for inclusion in articles' do | |
1484 | + file = UploadedFile.create!(:profile => @profile, :uploaded_data => fixture_file_upload('files/test.txt', 'text/plain')) | |
1485 | + get :search, :profile => @profile.identifier, :q => 'test.txt' | |
1486 | + assert_match /test.txt/, @response.body | |
1487 | + assert_equal 'application/json', @response.content_type | |
1488 | + | |
1489 | + data = parse_json_response | |
1490 | + assert_equal 'test.txt', data.first['title'] | |
1491 | + assert_match /\/testinguser\/test.txt$/, data.first['url'] | |
1492 | + assert_match /text/, data.first['icon'] | |
1493 | + assert_match /text/, data.first['content_type'] | |
1494 | + end | |
1495 | + | |
1496 | + should 'upload media by AJAX' do | |
1497 | + post :media_upload, :profile => profile.identifier, :file1 => fixture_file_upload('/files/test.txt', 'text/plain'), :file2 => fixture_file_upload('/files/rails.png', 'image/png'), :file3 => '' | |
1498 | + assert_match 'test.txt', @response.body | |
1499 | + assert_equal 'text/plain', @response.content_type | |
1500 | + | |
1501 | + data = parse_json_response | |
1502 | + | |
1503 | + assert_equal 'test.txt', data[0]['title'] | |
1504 | + assert_match /\/testinguser\/test.txt$/, data[0]['url'] | |
1505 | + assert_match /text/, data[0]['icon'] | |
1506 | + assert_match /text/, data[0]['content_type'] | |
1507 | + assert_nil data[0]['error'] | |
1508 | + | |
1509 | + assert_equal 'rails.png', data[1]['title'] | |
1510 | + assert_no_match /\/public\/articles\/.*\/rails.png$/, data[1]['url'] | |
1511 | + assert_match /png$/, data[1]['icon'] | |
1512 | + assert_match /image/, data[1]['content_type'] | |
1513 | + assert_nil data[1]['error'] | |
1514 | + | |
1515 | + end | |
1516 | + | |
1517 | + should 'not when media upload via AJAX contains empty files' do | |
1518 | + post :media_upload, :profile => @profile.identifier | |
1519 | + end | |
1520 | + | |
1521 | + should 'mark unsuccessfull uploads' do | |
1522 | + file = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('files/rails.png', 'image/png')) | |
1523 | + | |
1524 | + post :media_upload, :profile => profile.identifier, :media_listing => true, :file1 => fixture_file_upload('files/rails.png', 'image/png'), :file2 => fixture_file_upload('/files/test.txt', 'text/plain') | |
1525 | + | |
1526 | + assert_equal 'text/plain', @response.content_type | |
1527 | + data = parse_json_response | |
1528 | + | |
1529 | + assert_equal 'rails.png', data[0]['title'] | |
1530 | + assert_not_nil data[0]['error'] | |
1531 | + assert_match /rails.png/, data[0]['error'] | |
1532 | + | |
1533 | + assert_equal 'test.txt', data[1]['title'] | |
1534 | + assert_nil data[1]['error'] | |
1535 | + end | |
1536 | + | |
1537 | + protected | |
1538 | + | |
1539 | + # FIXME this is to avoid adding an extra dependency for a proper JSON parser. | |
1540 | + # For now we are assuming that the JSON is close enough to Ruby and just | |
1541 | + # making some adjustments. | |
1542 | + def parse_json_response | |
1543 | + eval(@response.body.gsub('":', '"=>').gsub('null', 'nil')) | |
1544 | + end | |
1545 | + | |
1621 | 1546 | end | ... | ... |