| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  | # Redmine - project management software | 
					
						
							| 
									
										
										
										
											2016-03-13 10:30:10 +00:00
										 |  |  | # Copyright (C) 2006-2016  Jean-Philippe Lang | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | # modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | # as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | # of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2011-08-20 06:51:36 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  | # This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | # GNU General Public License for more details. | 
					
						
							| 
									
										
										
										
											2011-08-20 06:51:36 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  | # You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | # along with this program; if not, write to the Free Software | 
					
						
							|  |  |  | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-11 17:37:38 +00:00
										 |  |  | require 'diff' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  | module Redmine | 
					
						
							|  |  |  |   module Helpers | 
					
						
							|  |  |  |     class Diff | 
					
						
							|  |  |  |       include ERB::Util | 
					
						
							|  |  |  |       include ActionView::Helpers::TagHelper | 
					
						
							|  |  |  |       include ActionView::Helpers::TextHelper | 
					
						
							| 
									
										
										
										
											2016-03-26 10:20:10 +00:00
										 |  |  |       include ActionView::Helpers::OutputSafetyHelper | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  |       attr_reader :diff, :words | 
					
						
							| 
									
										
										
										
											2011-08-20 06:51:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  |       def initialize(content_to, content_from) | 
					
						
							|  |  |  |         @words = content_to.to_s.split(/(\s+)/) | 
					
						
							|  |  |  |         @words = @words.select {|word| word != ' '} | 
					
						
							|  |  |  |         words_from = content_from.to_s.split(/(\s+)/) | 
					
						
							| 
									
										
										
										
											2011-08-20 06:51:36 +00:00
										 |  |  |         words_from = words_from.select {|word| word != ' '} | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  |         @diff = words_from.diff @words | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2011-08-20 06:51:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  |       def to_html | 
					
						
							|  |  |  |         words = self.words.collect{|word| h(word)} | 
					
						
							|  |  |  |         words_add = 0
 | 
					
						
							|  |  |  |         words_del = 0
 | 
					
						
							|  |  |  |         dels = 0
 | 
					
						
							|  |  |  |         del_off = 0
 | 
					
						
							|  |  |  |         diff.diffs.each do |diff| | 
					
						
							|  |  |  |           add_at = nil | 
					
						
							|  |  |  |           add_to = nil | 
					
						
							|  |  |  |           del_at = nil | 
					
						
							| 
									
										
										
										
											2011-08-20 06:51:36 +00:00
										 |  |  |           deleted = "" | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  |           diff.each do |change| | 
					
						
							|  |  |  |             pos = change[1] | 
					
						
							|  |  |  |             if change[0] == "+" | 
					
						
							|  |  |  |               add_at = pos + dels unless add_at | 
					
						
							|  |  |  |               add_to = pos + dels | 
					
						
							|  |  |  |               words_add += 1
 | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |               del_at = pos unless del_at | 
					
						
							| 
									
										
										
										
											2012-06-26 16:57:09 +00:00
										 |  |  |               deleted << ' ' unless deleted.empty? | 
					
						
							| 
									
										
										
										
											2016-03-26 10:20:10 +00:00
										 |  |  |               deleted << change[2] | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  |               words_del  += 1
 | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |           if add_at | 
					
						
							| 
									
										
										
										
											2012-06-26 16:57:09 +00:00
										 |  |  |             words[add_at] = '<span class="diff_in">'.html_safe + words[add_at] | 
					
						
							|  |  |  |             words[add_to] = words[add_to] + '</span>'.html_safe | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  |           end | 
					
						
							|  |  |  |           if del_at | 
					
						
							| 
									
										
										
										
											2016-03-26 10:20:10 +00:00
										 |  |  |             # deleted is not safe html at this point | 
					
						
							|  |  |  |             words.insert del_at - del_off + dels + words_add, '<span class="diff_out">'.html_safe + h(deleted) + '</span>'.html_safe | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  |             dels += 1
 | 
					
						
							|  |  |  |             del_off += words_del | 
					
						
							|  |  |  |             words_del = 0
 | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2016-03-26 10:20:10 +00:00
										 |  |  |         safe_join(words, ' ') | 
					
						
							| 
									
										
										
										
											2011-02-27 12:35:31 +00:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |