Commit a739edce1f172e39cbd3ca8a6a1e43bae8279171
Exists in
master
and in
28 other branches
Merge branch 'article-version' of https://gitlab.com/juniorsilva1001/noosfero in…
…to juniorsilva1001/noosfero-article-version Conflicts: app/views/content_viewer/versioned_article.rhtml db/schema.rb public/stylesheets/application.css
Showing
9 changed files
with
274 additions
and
20 deletions
Show diff stats
app/controllers/public/content_viewer_controller.rb
1 | +require 'diffy' | ||
2 | + | ||
1 | class ContentViewerController < ApplicationController | 3 | class ContentViewerController < ApplicationController |
2 | 4 | ||
3 | needs_profile | 5 | needs_profile |
@@ -117,6 +119,13 @@ class ContentViewerController < ApplicationController | @@ -117,6 +119,13 @@ class ContentViewerController < ApplicationController | ||
117 | end | 119 | end |
118 | end | 120 | end |
119 | 121 | ||
122 | + def versions_diff | ||
123 | + path = params[:page].join('/') | ||
124 | + @page = profile.articles.find_by_path(path) | ||
125 | + @v1, @v2 = @page.versions.find_by_version(params[:v1]), @page.versions.find_by_version(params[:v2]) | ||
126 | + p params | ||
127 | + end | ||
128 | + | ||
120 | def article_versions | 129 | def article_versions |
121 | path = params[:page].join('/') | 130 | path = params[:page].join('/') |
122 | @page = profile.articles.find_by_path(path) | 131 | @page = profile.articles.find_by_path(path) |
@@ -184,3 +193,7 @@ class ContentViewerController < ApplicationController | @@ -184,3 +193,7 @@ class ContentViewerController < ApplicationController | ||
184 | end | 193 | end |
185 | 194 | ||
186 | end | 195 | end |
196 | + | ||
197 | + | ||
198 | + | ||
199 | + |
app/views/content_viewer/article_versions.rhtml
1 | +<div class="article-versions"> | ||
2 | + <%= button(:back, _('Go back to post'), {:action => 'view_page'}) %> | ||
3 | +</div> | ||
4 | + | ||
1 | <%= article_title(@page, :no_link => true) %> | 5 | <%= article_title(@page, :no_link => true) %> |
2 | 6 | ||
3 | <p><%= _('This is the list of all versions of this content. Select a version to see it and then revert to it.') %>.</p> | 7 | <p><%= _('This is the list of all versions of this content. Select a version to see it and then revert to it.') %>.</p> |
4 | 8 | ||
5 | -<ul class='article-versions'> | ||
6 | - <% @versions.each do |v| %> | ||
7 | - <li> | ||
8 | - <%= link_to(_("Version #{v.version}"), @page.url.merge(:version => v.version)) %> | ||
9 | - <%= @page.version == v.version ? _('(current)') : '' %> | ||
10 | - <span class='updated-by'><%= _('by %{author}') % {:author => link_to(@page.author_name(v.version), @page.author_url)} %></span> | ||
11 | - <div class='updated-on'><%= show_time(v.updated_at) %></div> | ||
12 | - </li> | ||
13 | - <% end %> | ||
14 | -</ul> | 9 | +<% form_tag({:controller => 'content_viewer', :action => 'versions_diff', :profile => profile.identifier, :page => @page.path.split('/')}, :method => 'get') do %> |
10 | + <ul id="article-versions"> | ||
11 | + <% @versions.each do |v| %> | ||
12 | + <li> | ||
13 | + <%= radio_button_tag 'v1', v.version, false, :onclick => 'versionInputClicked(this)' %> | ||
14 | + <%= radio_button_tag 'v2', v.version, false, :onclick => 'versionInputClicked(this)' %> | ||
15 | + <%= link_to(_("Version #{v.version}"), @page.url.merge(:version => v.version)) %> | ||
16 | + <%= @page.version == v.version ? _('(current)') : '' %> | ||
17 | + <span class='updated-by'><%= _('by %{author}') % {:author => link_to(@page.author_name(v.version), @page.author_url)} %></span> | ||
18 | + <span class='updated-on'><%= show_time(v.updated_at) %></span> | ||
19 | + </li> | ||
20 | + <% end %> | ||
21 | + </ul> | ||
22 | + | ||
23 | +<script> | ||
24 | + function versionInputClicked(input) { | ||
25 | + var selectedColumn = input.name; | ||
26 | + var sisterColumn = (selectedColumn == 'v1') ? 'v2' : 'v1'; | ||
27 | + var li = input.parentNode; | ||
28 | + var checkedBrotherLi = jQuery('#article-versions input[name=' + sisterColumn + ']:checked').parent()[0]; | ||
29 | + updateColumn(selectedColumn, li); | ||
30 | + updateColumn(sisterColumn, checkedBrotherLi); | ||
31 | + } | ||
15 | 32 | ||
33 | + function updateColumn(selectedColumn, startLi){ | ||
34 | + var sisterColumn = (selectedColumn == 'v1') ? 'v2' : 'v1'; | ||
35 | + var walkMethod = (selectedColumn == 'v1') ? 'prev' : 'next'; | ||
36 | + var li = startLi; | ||
37 | + var foundCheckedBrother = false; | ||
38 | + while(li = jQuery(li)[walkMethod]()[0]) { | ||
39 | + li.className = ''; | ||
40 | + if (!foundCheckedBrother){ | ||
41 | + li.className = 'selected'; | ||
42 | + foundCheckedBrother = jQuery('input[name=' + sisterColumn + ']', li)[0].checked; | ||
43 | + } | ||
44 | + jQuery('input[name=' + selectedColumn + ']', li)[0].disabled = foundCheckedBrother; | ||
45 | + } | ||
46 | + } | ||
47 | + | ||
48 | + var penultVersion = jQuery('#article-versions input[name=v1]')[1]; | ||
49 | + var lastVersion = jQuery('#article-versions input[name=v2]')[0]; | ||
50 | + jQuery('#article-versions input').attr('disabled', false); | ||
51 | + if (penultVersion && lastVersion) { | ||
52 | + penultVersion.checked = lastVersion.checked = true; | ||
53 | + lastVersion.onclick(); | ||
54 | + } | ||
55 | +</script> | ||
56 | + <%= submit_button(:clock, _('Show differences between selected versions')) %> | ||
57 | +<% end %> | ||
16 | <%= pagination_links @versions, :param_name => 'npage' %> | 58 | <%= pagination_links @versions, :param_name => 'npage' %> |
59 | + |
app/views/content_viewer/versioned_article.rhtml
1 | +<div class="article-versions"> | ||
2 | + <%= button(:back, _('Back to the versions'), {:action => 'article_versions'}) %> | ||
3 | +</div> | ||
4 | + | ||
1 | <div id="article" class="<%= @page.css_class_name %>"> | 5 | <div id="article" class="<%= @page.css_class_name %>"> |
2 | 6 | ||
3 | <div id="article-actions"> | 7 | <div id="article-actions"> |
4 | <%= button(:clock, _('All versions'), {:controller => 'content_viewer', :profile => profile.identifier, :action => 'article_versions'}, :id => 'article-versions-link') %> | 8 | <%= button(:clock, _('All versions'), {:controller => 'content_viewer', :profile => profile.identifier, :action => 'article_versions'}, :id => 'article-versions-link') %> |
5 | 9 | ||
6 | - <% if @page.allow_edit?(user) && !remove_content_button(:edit) %> | 10 | + <% if @page.allow_edit?(user) && !remove_content_button(:undo) %> |
7 | <% content = content_tag('span', _('Revert to this version')) %> | 11 | <% content = content_tag('span', _('Revert to this version')) %> |
8 | <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'edit', :id => @page.id, :version => @version }) %> | 12 | <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'edit', :id => @page.id, :version => @version }) %> |
9 | - <%= expirable_button @page, :edit, content, url, :id => 'article-revert-version-link' %> | 13 | + <%= expirable_button @page, :undo, content, url, :id => 'article-revert-version-link' %> |
10 | <% end %> | 14 | <% end %> |
11 | - </div> | ||
12 | 15 | ||
16 | + <%= button(:forward, _('Go to latest version'), {:action => 'view_page'}) %> | ||
17 | +</div> | ||
13 | <div id="article-header"> | 18 | <div id="article-header"> |
14 | <h1 class='title'><%= @versioned_article.name %></h1> | 19 | <h1 class='title'><%= @versioned_article.name %></h1> |
15 | <%= _("Version %{version} - %{author} on %{date}") % {:version => @version, :author => @page.author_name(@version), :date => show_time(@versioned_article.updated_at) } %> | 20 | <%= _("Version %{version} - %{author} on %{date}") % {:version => @version, :author => @page.author_name(@version), :date => show_time(@versioned_article.updated_at) } %> |
16 | </div> | 21 | </div> |
17 | 22 | ||
23 | + <p id="no-current-version"> | ||
24 | + <%= _('This is not the latest version of this content.') %> | ||
25 | + </p> | ||
26 | +</div> | ||
27 | + | ||
18 | <% version_license = @page.version_license(@version) %> | 28 | <% version_license = @page.version_license(@version) %> |
19 | <%# This seemingly doubled verification exists because the article-sub-header | 29 | <%# This seemingly doubled verification exists because the article-sub-header |
20 | - div must appear only if at least one content inside it will appeart. | 30 | + div must appear only if at least one content inside it will appear. |
21 | Although we have only one content now, we might have others in the future. | 31 | Although we have only one content now, we might have others in the future. |
22 | So we're keeping it like that to avoid mistakes. %> | 32 | So we're keeping it like that to avoid mistakes. %> |
23 | <% if version_license.present? %> | 33 | <% if version_license.present? %> |
@@ -0,0 +1,16 @@ | @@ -0,0 +1,16 @@ | ||
1 | +<div class="article-versions"> | ||
2 | +<%= button(:back, _('Back to the versions'), {:action => 'article_versions'}) %> | ||
3 | +</div> | ||
4 | + | ||
5 | +<h1><%= _('Changes on "%s"') % @page.title %></h1> | ||
6 | + | ||
7 | +<p> <%= _('Changes from %s → %s') % [show_time(@v1.updated_at), show_time(@v2.updated_at)] %> </p> | ||
8 | + | ||
9 | +<% diffContent = Diffy::Diff.new(@v1.body, @v2.body, :context => 1) %> | ||
10 | +<% if diffContent.to_s(:text).blank? %> | ||
11 | + <p id="article-versions-no-diff"> | ||
12 | + <%= _('These versions range have no differences.')%> | ||
13 | + </p> | ||
14 | +<% else %> | ||
15 | + <%= diffContent.to_s(:html) %> | ||
16 | +<% end %> |
config/routes.rb
@@ -129,6 +129,9 @@ ActionController::Routing::Routes.draw do |map| | @@ -129,6 +129,9 @@ ActionController::Routing::Routes.draw do |map| | ||
129 | map.connect ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format}/, :conditions => { :if => lambda { |env| !Domain.hosting_profile_at(env[:host]) } } | 129 | map.connect ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format}/, :conditions => { :if => lambda { |env| !Domain.hosting_profile_at(env[:host]) } } |
130 | map.connect '*page/versions', :controller => 'content_viewer', :action => 'article_versions' | 130 | map.connect '*page/versions', :controller => 'content_viewer', :action => 'article_versions' |
131 | 131 | ||
132 | + map.connect ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format}/, :conditions => { :if => lambda { |env| !Domain.hosting_profile_at(env[:host]) } } | ||
133 | + map.connect '*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff' | ||
134 | + | ||
132 | # match requests for profiles that don't have a custom domain | 135 | # match requests for profiles that don't have a custom domain |
133 | map.homepage ':profile/*page', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format}/, :conditions => { :if => lambda { |env| !Domain.hosting_profile_at(env[:host]) } } | 136 | map.homepage ':profile/*page', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format}/, :conditions => { :if => lambda { |env| !Domain.hosting_profile_at(env[:host]) } } |
134 | 137 |
db/schema.rb
@@ -10,7 +10,6 @@ | @@ -10,7 +10,6 @@ | ||
10 | # It's strongly recommended to check this file into your version control system. | 10 | # It's strongly recommended to check this file into your version control system. |
11 | 11 | ||
12 | ActiveRecord::Schema.define(:version => 20140314200103) do | 12 | ActiveRecord::Schema.define(:version => 20140314200103) do |
13 | - | ||
14 | create_table "abuse_reports", :force => true do |t| | 13 | create_table "abuse_reports", :force => true do |t| |
15 | t.integer "reporter_id" | 14 | t.integer "reporter_id" |
16 | t.integer "abuse_complaint_id" | 15 | t.integer "abuse_complaint_id" |
@@ -148,6 +147,7 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -148,6 +147,7 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
148 | add_index "articles", ["profile_id"], :name => "index_articles_on_profile_id" | 147 | add_index "articles", ["profile_id"], :name => "index_articles_on_profile_id" |
149 | add_index "articles", ["slug"], :name => "index_articles_on_slug" | 148 | add_index "articles", ["slug"], :name => "index_articles_on_slug" |
150 | add_index "articles", ["translation_of_id"], :name => "index_articles_on_translation_of_id" | 149 | add_index "articles", ["translation_of_id"], :name => "index_articles_on_translation_of_id" |
150 | + add_index "articles", [nil], :name => "pg_search_plugin_article" | ||
151 | 151 | ||
152 | create_table "articles_categories", :id => false, :force => true do |t| | 152 | create_table "articles_categories", :id => false, :force => true do |t| |
153 | t.integer "article_id" | 153 | t.integer "article_id" |
@@ -201,6 +201,8 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -201,6 +201,8 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
201 | t.string "abbreviation" | 201 | t.string "abbreviation" |
202 | end | 202 | end |
203 | 203 | ||
204 | + add_index "categories", [nil], :name => "pg_search_plugin_category" | ||
205 | + | ||
204 | create_table "categories_profiles", :id => false, :force => true do |t| | 206 | create_table "categories_profiles", :id => false, :force => true do |t| |
205 | t.integer "profile_id" | 207 | t.integer "profile_id" |
206 | t.integer "category_id" | 208 | t.integer "category_id" |
@@ -219,6 +221,8 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -219,6 +221,8 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
219 | t.datetime "updated_at" | 221 | t.datetime "updated_at" |
220 | end | 222 | end |
221 | 223 | ||
224 | + add_index "certifiers", [nil], :name => "pg_search_plugin_certifier" | ||
225 | + | ||
222 | create_table "comments", :force => true do |t| | 226 | create_table "comments", :force => true do |t| |
223 | t.string "title" | 227 | t.string "title" |
224 | t.text "body" | 228 | t.text "body" |
@@ -233,9 +237,11 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -233,9 +237,11 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
233 | t.string "source_type" | 237 | t.string "source_type" |
234 | t.string "user_agent" | 238 | t.string "user_agent" |
235 | t.string "referrer" | 239 | t.string "referrer" |
240 | + t.integer "group_id" | ||
236 | end | 241 | end |
237 | 242 | ||
238 | add_index "comments", ["source_id", "spam"], :name => "index_comments_on_source_id_and_spam" | 243 | add_index "comments", ["source_id", "spam"], :name => "index_comments_on_source_id_and_spam" |
244 | + add_index "comments", [nil], :name => "pg_search_plugin_comment" | ||
239 | 245 | ||
240 | create_table "contact_lists", :force => true do |t| | 246 | create_table "contact_lists", :force => true do |t| |
241 | t.text "list" | 247 | t.text "list" |
@@ -245,6 +251,50 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -245,6 +251,50 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
245 | t.datetime "updated_at" | 251 | t.datetime "updated_at" |
246 | end | 252 | end |
247 | 253 | ||
254 | + create_table "custom_forms_plugin_answers", :force => true do |t| | ||
255 | + t.text "value" | ||
256 | + t.integer "field_id" | ||
257 | + t.integer "submission_id" | ||
258 | + end | ||
259 | + | ||
260 | + create_table "custom_forms_plugin_fields", :force => true do |t| | ||
261 | + t.string "name" | ||
262 | + t.string "slug" | ||
263 | + t.string "type" | ||
264 | + t.string "default_value" | ||
265 | + t.string "choices" | ||
266 | + t.float "minimum" | ||
267 | + t.float "maximum" | ||
268 | + t.integer "form_id" | ||
269 | + t.boolean "mandatory", :default => false | ||
270 | + t.boolean "multiple" | ||
271 | + t.boolean "list" | ||
272 | + t.integer "position", :default => 0 | ||
273 | + end | ||
274 | + | ||
275 | + create_table "custom_forms_plugin_forms", :force => true do |t| | ||
276 | + t.string "name" | ||
277 | + t.string "slug" | ||
278 | + t.text "description" | ||
279 | + t.integer "profile_id" | ||
280 | + t.datetime "begining" | ||
281 | + t.datetime "ending" | ||
282 | + t.boolean "report_submissions", :default => false | ||
283 | + t.boolean "on_membership", :default => false | ||
284 | + t.string "access" | ||
285 | + t.datetime "created_at" | ||
286 | + t.datetime "updated_at" | ||
287 | + end | ||
288 | + | ||
289 | + create_table "custom_forms_plugin_submissions", :force => true do |t| | ||
290 | + t.string "author_name" | ||
291 | + t.string "author_email" | ||
292 | + t.integer "profile_id" | ||
293 | + t.integer "form_id" | ||
294 | + t.datetime "created_at" | ||
295 | + t.datetime "updated_at" | ||
296 | + end | ||
297 | + | ||
248 | create_table "delayed_jobs", :force => true do |t| | 298 | create_table "delayed_jobs", :force => true do |t| |
249 | t.integer "priority", :default => 0 | 299 | t.integer "priority", :default => 0 |
250 | t.integer "attempts", :default => 0 | 300 | t.integer "attempts", :default => 0 |
@@ -311,6 +361,10 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -311,6 +361,10 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
311 | t.integer "enterprise_id" | 361 | t.integer "enterprise_id" |
312 | end | 362 | end |
313 | 363 | ||
364 | + create_table "foo_plugin_bars", :force => true do |t| | ||
365 | + t.string "name" | ||
366 | + end | ||
367 | + | ||
314 | create_table "friendships", :force => true do |t| | 368 | create_table "friendships", :force => true do |t| |
315 | t.integer "person_id" | 369 | t.integer "person_id" |
316 | t.integer "friend_id" | 370 | t.integer "friend_id" |
@@ -356,6 +410,8 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -356,6 +410,8 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
356 | t.integer "environment_id", :null => false | 410 | t.integer "environment_id", :null => false |
357 | end | 411 | end |
358 | 412 | ||
413 | + add_index "licenses", [nil], :name => "pg_search_plugin_license" | ||
414 | + | ||
359 | create_table "mailing_sents", :force => true do |t| | 415 | create_table "mailing_sents", :force => true do |t| |
360 | t.integer "mailing_id" | 416 | t.integer "mailing_id" |
361 | t.integer "person_id" | 417 | t.integer "person_id" |
@@ -390,6 +446,7 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -390,6 +446,7 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
390 | 446 | ||
391 | add_index "national_regions", ["name"], :name => "name_index" | 447 | add_index "national_regions", ["name"], :name => "name_index" |
392 | add_index "national_regions", ["national_region_code"], :name => "code_index" | 448 | add_index "national_regions", ["national_region_code"], :name => "code_index" |
449 | + add_index "national_regions", [nil], :name => "pg_search_plugin_nationalregion" | ||
393 | 450 | ||
394 | create_table "price_details", :force => true do |t| | 451 | create_table "price_details", :force => true do |t| |
395 | t.decimal "price", :default => 0.0 | 452 | t.decimal "price", :default => 0.0 |
@@ -488,6 +545,7 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -488,6 +545,7 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
488 | add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier" | 545 | add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier" |
489 | add_index "profiles", ["members_count"], :name => "index_profiles_on_members_count" | 546 | add_index "profiles", ["members_count"], :name => "index_profiles_on_members_count" |
490 | add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id" | 547 | add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id" |
548 | + add_index "profiles", [nil], :name => "pg_search_plugin_profile" | ||
491 | 549 | ||
492 | create_table "qualifier_certifiers", :force => true do |t| | 550 | create_table "qualifier_certifiers", :force => true do |t| |
493 | t.integer "qualifier_id" | 551 | t.integer "qualifier_id" |
@@ -501,6 +559,8 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -501,6 +559,8 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
501 | t.datetime "updated_at" | 559 | t.datetime "updated_at" |
502 | end | 560 | end |
503 | 561 | ||
562 | + add_index "qualifiers", [nil], :name => "pg_search_plugin_qualifier" | ||
563 | + | ||
504 | create_table "refused_join_community", :id => false, :force => true do |t| | 564 | create_table "refused_join_community", :id => false, :force => true do |t| |
505 | t.integer "person_id" | 565 | t.integer "person_id" |
506 | t.integer "community_id" | 566 | t.integer "community_id" |
@@ -547,6 +607,8 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -547,6 +607,8 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
547 | t.integer "context_id" | 607 | t.integer "context_id" |
548 | end | 608 | end |
549 | 609 | ||
610 | + add_index "scraps", [nil], :name => "pg_search_plugin_scrap" | ||
611 | + | ||
550 | create_table "sessions", :force => true do |t| | 612 | create_table "sessions", :force => true do |t| |
551 | t.string "session_id", :null => false | 613 | t.string "session_id", :null => false |
552 | t.text "data" | 614 | t.text "data" |
@@ -606,6 +668,19 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | @@ -606,6 +668,19 @@ ActiveRecord::Schema.define(:version => 20140314200103) do | ||
606 | t.string "thumbnail" | 668 | t.string "thumbnail" |
607 | end | 669 | end |
608 | 670 | ||
671 | + create_table "tolerance_time_plugin_publications", :force => true do |t| | ||
672 | + t.integer "target_id" | ||
673 | + t.string "target_type" | ||
674 | + t.datetime "created_at" | ||
675 | + t.datetime "updated_at" | ||
676 | + end | ||
677 | + | ||
678 | + create_table "tolerance_time_plugin_tolerances", :force => true do |t| | ||
679 | + t.integer "profile_id" | ||
680 | + t.integer "content_tolerance" | ||
681 | + t.integer "comment_tolerance" | ||
682 | + end | ||
683 | + | ||
609 | create_table "units", :force => true do |t| | 684 | create_table "units", :force => true do |t| |
610 | t.string "singular", :null => false | 685 | t.string "singular", :null => false |
611 | t.string "plural", :null => false | 686 | t.string "plural", :null => false |
public/designs/icons/tango/style.css
1 | /******************SMALL ICONS********************/ | 1 | /******************SMALL ICONS********************/ |
2 | .icon-edit { background-image: url(Tango/16x16/apps/text-editor.png) } | 2 | .icon-edit { background-image: url(Tango/16x16/apps/text-editor.png) } |
3 | +.icon-undo { background-image: url(Tango/16x16/actions/edit-undo.png) } | ||
3 | .icon-home { background-image: url(Tango/16x16/actions/go-home.png) } | 4 | .icon-home { background-image: url(Tango/16x16/actions/go-home.png) } |
4 | .icon-home-not { background-image: url(mod/16x16/actions/go-home-not.png) } | 5 | .icon-home-not { background-image: url(mod/16x16/actions/go-home-not.png) } |
5 | .icon-new, | 6 | .icon-new, |
public/stylesheets/application.css
@@ -6510,11 +6510,6 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { | @@ -6510,11 +6510,6 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { | ||
6510 | text-align: center; | 6510 | text-align: center; |
6511 | } | 6511 | } |
6512 | 6512 | ||
6513 | -ul.article-versions li { | ||
6514 | - font-size: 13px; | ||
6515 | - padding: 3px 0px; | ||
6516 | -} | ||
6517 | - | ||
6518 | /* * * Admin manage fields * * */ | 6513 | /* * * Admin manage fields * * */ |
6519 | 6514 | ||
6520 | .controller-features .manage-fields-batch-actions, | 6515 | .controller-features .manage-fields-batch-actions, |
@@ -6526,3 +6521,90 @@ ul.article-versions li { | @@ -6526,3 +6521,90 @@ ul.article-versions li { | ||
6526 | .controller-features .manage-fields-batch-actions td { | 6521 | .controller-features .manage-fields-batch-actions td { |
6527 | font-style: italic; | 6522 | font-style: italic; |
6528 | } | 6523 | } |
6524 | + | ||
6525 | +/* * * Article versions * * */ | ||
6526 | + | ||
6527 | +#article-versions { | ||
6528 | + margin: 0 0 15px 0; | ||
6529 | + padding: 0; | ||
6530 | +} | ||
6531 | + | ||
6532 | +#article-versions li { | ||
6533 | + list-style: none; | ||
6534 | + margin: 0; | ||
6535 | + padding: 3px 0px; | ||
6536 | +} | ||
6537 | + | ||
6538 | +#article-versions input:disabled { | ||
6539 | + opacity: 0.3; | ||
6540 | +} | ||
6541 | + | ||
6542 | +#article-versions .selected { | ||
6543 | + background: #ff9; | ||
6544 | +} | ||
6545 | + | ||
6546 | +#article-versions-no-diff { | ||
6547 | + text-align: center; | ||
6548 | + font-style: italic; | ||
6549 | +} | ||
6550 | + | ||
6551 | +#no-current-version { | ||
6552 | + text-align: center; | ||
6553 | + font-style: italic; | ||
6554 | + background: #faa; | ||
6555 | + padding: 3px; | ||
6556 | +} | ||
6557 | + | ||
6558 | +.article-versions { | ||
6559 | + margin: 5px 0px; | ||
6560 | + text-align: right; | ||
6561 | +} | ||
6562 | + | ||
6563 | +.action-content_viewer-versions_diff .diff { | ||
6564 | + text-align: justify; | ||
6565 | +} | ||
6566 | + | ||
6567 | +.diff ul { | ||
6568 | + list-style: none; | ||
6569 | + margin: 0; | ||
6570 | + padding: 0; | ||
6571 | +} | ||
6572 | + | ||
6573 | +.diff del, .diff ins { | ||
6574 | + display: block; | ||
6575 | + text-decoration: none; | ||
6576 | +} | ||
6577 | + | ||
6578 | +.diff li { | ||
6579 | + padding: 5px 10px; | ||
6580 | + margin: 0; | ||
6581 | + line-height: 150%; | ||
6582 | +} | ||
6583 | + | ||
6584 | +.diff li.ins { | ||
6585 | + background: #dfd; | ||
6586 | +} | ||
6587 | + | ||
6588 | +.diff li.del { | ||
6589 | + background: #fee; | ||
6590 | +} | ||
6591 | + | ||
6592 | +.diff li.ins:hover { | ||
6593 | + background: #8f8; | ||
6594 | +} | ||
6595 | + | ||
6596 | +.diff li.del:hover { | ||
6597 | + background: #f99; | ||
6598 | +} | ||
6599 | + | ||
6600 | +.diff strong { | ||
6601 | + background: rgba(255, 255, 0, 0.2); | ||
6602 | +} | ||
6603 | + | ||
6604 | +.diff li.diff-comment { | ||
6605 | + display: none; | ||
6606 | +} | ||
6607 | + | ||
6608 | +.diff li.diff-block-info { | ||
6609 | + background: none repeat scroll 0 0 gray; | ||
6610 | +} |
test/functional/content_viewer_controller_test.rb
@@ -396,6 +396,17 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -396,6 +396,17 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
396 | assert_tag :tag => 'div', :attributes => { :class => /article-body/ }, :content => /edited article/ | 396 | assert_tag :tag => 'div', :attributes => { :class => /article-body/ }, :content => /edited article/ |
397 | end | 397 | end |
398 | 398 | ||
399 | + should "display differences between article's versions" do | ||
400 | + page = TextArticle.create!(:name => 'myarticle', :body => 'original article', :display_versions => true, :profile => profile) | ||
401 | + page.body = 'edited article'; page.save | ||
402 | + | ||
403 | + get :versions_diff, :profile => profile.identifier, :page => [ 'myarticle' ], :v1 => 1, :v2 => 2; | ||
404 | + | ||
405 | + assert_tag :tag => 'li', :attributes => { :class => /del/ }, :content => /original article/ | ||
406 | + assert_tag :tag => 'li', :attributes => { :class => /ins/ }, :content => /edited article/ | ||
407 | + assert_response :success | ||
408 | + end | ||
409 | + | ||
399 | should 'not return an article of a different user' do | 410 | should 'not return an article of a different user' do |
400 | p1 = create_user('test_user').person | 411 | p1 = create_user('test_user').person |
401 | a = p1.articles.create!(:name => 'old-name') | 412 | a = p1.articles.create!(:name => 'old-name') |