diff options
9 files changed, 110 insertions, 23 deletions
diff --git a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties index 33f4ff2e83e..c8b954cb92a 100644 --- a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -603,6 +603,8 @@ duplications.number_of_lines=Nb Lines duplications.from_line=From line duplications.file=File duplications.details=Details +duplications.expand=Expand +duplications.collapse=Collapse #------------------------------------------------------------------------------ diff --git a/sonar-server/pom.xml b/sonar-server/pom.xml index 2681bcd9229..e2ec8b14892 100644 --- a/sonar-server/pom.xml +++ b/sonar-server/pom.xml @@ -256,6 +256,7 @@ <include>**/dashboard-min.js</include> <include>**/protovis-min.js</include> <include>**/protovis-sonar-min.js</include> + <include>**/duplications-min.js</include> </includes> <output>${project.build.directory}/${project.build.finalName}/javascripts/sonar.js</output> </aggregation> @@ -301,7 +302,7 @@ <artifactId>maven-war-plugin</artifactId> <configuration> <packagingExcludes> - **/*.log,*.iml,WEB-INF/script/,WEB-INF/test/,javascripts/application*.js,javascripts/prototype*.js,javascripts/scriptaculous*.js,javascripts/tablekit*.js,javascripts/tablekit*.js,javascripts/prototip*.js,javascripts/dashboard*.js,javascripts/protovis.js,javascripts/protovis-min.js + **/*.log,*.iml,WEB-INF/script/,WEB-INF/test/,javascripts/application*.js,javascripts/prototype*.js,javascripts/scriptaculous*.js,javascripts/tablekit*.js,javascripts/tablekit*.js,javascripts/prototip*.js,javascripts/dashboard*.js,javascripts/protovis.js,javascripts/protovis-min.js,javascripts/duplications.js,javascripts/duplications-min.js </packagingExcludes> <warSourceExcludes> **/* diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb index 61c30b9aee9..6261b8333fe 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb @@ -56,9 +56,12 @@ class ResourceController < ApplicationController end def show_duplication_snippet - @resource = Project.by_key(params[:id]) - if (@resource && has_role?(:user, @resource)) - render :partial => 'duplications_source_snippet', :locals => {:resource => @resource, :from_line => params[:from_line].to_i, :to_line => params[:to_line].to_i} + resource = Project.by_key(params[:id]) + if (resource && has_role?(:user, resource)) + original_resource = Project.by_key(params[:original_resource_id]) + render :partial => 'duplications_source_snippet', + :locals => {:resource => resource, :original_resource => original_resource, :from_line => params[:from_line].to_i, :to_line => params[:to_line].to_i, :lines_count => params[:lines_count].to_i, + :source_div => params[:source_div], :external => resource.root_id != original_resource.root_id} else access_denied end @@ -185,6 +188,7 @@ class ResourceController < ApplicationController def render_duplications duplications_data = @snapshot.measure('duplications_data'); + # create duplication groups @duplication_groups = [] if duplications_data && duplications_data.measure_data && duplications_data.measure_data.data dups = Document.new duplications_data.measure_data.data.to_s @@ -196,6 +200,13 @@ class ResourceController < ApplicationController end end + # And sort them + # TODO => still needs to be sorted with inner dups before outer dups in a single block (can test only when new table available) + @duplication_groups.each do |group| + group.sort! {|dup1, dup2| dup1[:from_line].to_i <=> dup2[:from_line].to_i} + end + @duplication_groups.sort! {|group1, group2| group1[0][:from_line].to_i <=> group2[0][:from_line].to_i} + render :action => 'index', :layout => !request.xhr? end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb index 659920e9c2e..1745af879e9 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb @@ -333,7 +333,10 @@ module ApplicationHelper link_to(name || resource.name, {:overwrite_params => {:id => (resource.copy_resource_id||resource.id), :period => period_index, :tab => options[:tab], :rule => options[:rule]}}, :title => options[:title]) end else - link_to(name || resource.name, {:controller => 'resource', :action => 'index', :id => resource.id, :period => period_index, :tab => options[:tab], :rule => options[:rule]}, :popup => ['resource', 'height=800,width=900,scrollbars=1,resizable=1'], :title => options[:title]) + if options[:line] + anchor= 'L' + options[:line].to_s + end + link_to(name || resource.name, {:controller => 'resource', :action => 'index', :anchor => anchor, :id => resource.id, :period => period_index, :tab => options[:tab], :rule => options[:rule]}, :popup => ['resource', 'height=800,width=900,scrollbars=1,resizable=1'], :title => options[:title]) end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb index 50ee96547cb..9aabe2e583a 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb @@ -29,6 +29,7 @@ <%= javascript_include_tag 'dashboard' %> <%= javascript_include_tag 'protovis' %> <%= javascript_include_tag 'protovis-sonar' %> +<%= javascript_include_tag 'duplications' %> <% end %> <!--[if lte IE 6]> <link href="<%= ApplicationController.root_context -%>/ie6/index" media="all" rel="stylesheet" type="text/css" /> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications.html.erb index fc9bbb1b809..e55fb2f9e9b 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications.html.erb @@ -32,22 +32,25 @@ <% group.each_with_index do |dup, index| resource = dup[:resource] + external = resource.root_id != @resource.root_id + lines_count = dup[:lines_count].to_i from_line = dup[:from_line].to_i - to_line = from_line+5 - update_snippet_script = "new Ajax.Updater('source-#{group_index}', '#{url_for :action => :show_duplication_snippet, :params => {:id => resource.id, :from_line => from_line, :to_line => to_line}}', {asynchronous:true, evalScripts:true}); return false;" - groupClass = "group" + group_index.to_s - groupRowClass = "row" + group_index.to_s + "-" + index.to_s + to_line = from_line + (lines_count > 5 ? 5 : lines_count) + group_class = "group#{group_index}" + group_row_class = "row#{group_index}-#{index}" + source_div = "source-#{group_index}" + update_snippet_script = "updateDuplicationLines('#{url_for :action => :show_duplication_snippet, :params => {:id => resource.id, :original_resource_id => @resource.id, :from_line => from_line, :lines_count => lines_count, :source_div => source_div}}','#{group_class}', '#{group_row_class}', '#{source_div}', #{lines_count}, #{from_line}, #{to_line});" %> <tr class="hoverable <%= row_style -%>"> <td class="center group-item"> - <div class="<%= groupClass -%> <%= groupRowClass -%> clickable <%= 'selected' if resource==@resource -%>" - onclick="updateDuplicationLines(this, '<%= groupClass -%>', '<%= groupRowClass -%>'); <%= update_snippet_script -%>" style="border-right-width: 0px;"> - <%= dup[:lines_count] -%> + <div class="<%= group_class -%> <%= group_row_class -%> clickable <%= 'selected' if resource==@resource -%>" + onclick="<%= update_snippet_script -%>" style="border-right-width: 0px; margin-left: 2px;"> + <%= lines_count -%> <div> </td> <td class="center group-item"> - <div class="group<%= group_index -%> <%= groupRowClass -%> clickable <%= 'selected' if resource==@resource -%>" - onclick="updateDuplicationLines(this, '<%= groupClass -%>', '<%= groupRowClass -%>'); <%= update_snippet_script -%>" style="border-right-width: 0px;border-left-width: 0px;"> + <div class="<%= group_class -%> <%= group_row_class -%> clickable <%= 'selected' if resource==@resource -%>" + onclick="<%= update_snippet_script -%>" style="border-right-width: 0px;border-left-width: 0px;"> <%= from_line -%> </div> </td> @@ -55,19 +58,22 @@ <% if resource==@resource cell_content = resource.name else - cell_content = link_to_resource(resource, resource.name) + cell_content = link_to_resource(resource, resource.name, {:line => from_line}) end %> - <div class="group<%= group_index -%> <%= groupRowClass -%> clickable <%= 'selected' if resource==@resource -%>" - onclick="updateDuplicationLines(this, '<%= groupClass -%>', '<%= groupRowClass -%>'); <%= update_snippet_script -%>" style="padding-right: 20px; border-right-width: 0px;border-left-width: 0px;"> + <div class="<%= group_class -%> <%= group_row_class -%> clickable nowrap <%= 'selected' if resource==@resource -%>" + onclick="<%= update_snippet_script -%>" style="padding-right: 20px; border-right-width: 0px;border-left-width: 0px;"> <%= cell_content -%> - <div> + <% if external %> + <%= image_tag "links/external.png" -%> + <% end %> + </div> </td> <% if index==0 %> <td rowspan="<%= group_size+1 -%>" class="source-snippet"> - <div id="source-<%= group_index -%>"> - <%= render :partial => 'duplications_source_snippet', :locals => {:resource => resource, :from_line => from_line, :to_line => to_line} -%> + <div id="<%= source_div -%>"> + <%= render :partial => 'duplications_source_snippet', :locals => {:resource => resource, :original_resource => @resource, :from_line => from_line, :to_line => to_line, :lines_count => lines_count, :source_div => source_div, :external => external} -%> </div> </td> <% end %> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications_source_snippet.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications_source_snippet.html.erb index 7b4faa9a565..511cc1c1f3c 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications_source_snippet.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications_source_snippet.html.erb @@ -1,2 +1,36 @@ -<%= resource.key -%> -<%= snapshot_source_to_html(resource.last_snapshot, {:line_range => (from_line)..(to_line)}) -%> +<div class="<%= 'expanded' if to_line == from_line + lines_count -%>"> + <div style="line-height:20px; margin-left:24px;"> + <% + if external + parent_project = resource.project + %> + <%= link_to_resource(parent_project, parent_project.path_name, {:dashboard => true}) -%> + <%= image_tag "links/external.png" -%> + <br/> + <% + end + %> + <b><%= resource.name(true) -%></b> + </div> + + <%= snapshot_source_to_html(resource.last_snapshot, {:line_range => (from_line)..(to_line)}) -%> + + <% if lines_count > 5 %> + <div class="small" style="line-height:20px; margin-left:24px;"> + <% + if to_line < from_line + lines_count + link_text = message('duplications.expand') + to_line = from_line + lines_count + else + link_text = message('duplications.collapse') + to_line = from_line + 5 + end + %> + <%= link_to_remote link_text, + :url => {:action => :show_duplication_snippet, :params => {:id => resource.id, :original_resource_id => original_resource.id, :from_line => from_line, :to_line => to_line, :lines_count => lines_count, :source_div => source_div}}, + :update => source_div, + :before => "$('#{source_div}').addClassName('loading');", + :complete => "$('#{source_div}').removeClassName('loading');" -%> + </div> + <% end %> +</div>
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/javascripts/duplications.js b/sonar-server/src/main/webapp/javascripts/duplications.js new file mode 100644 index 00000000000..642ca55f5d4 --- /dev/null +++ b/sonar-server/src/main/webapp/javascripts/duplications.js @@ -0,0 +1,25 @@ +// JS scripts used in the duplication tab of the resource viewer + +function updateDuplicationLines(url, groupClass, groupRowClass, sourceDivId, linesCount, fromLine, toLine) { + // handle first the style of the selectable rows + divs = $$('.'+groupClass); + for ( i = 0; i < divs.size(); i++) { + divs[i].removeClassName('selected'); + } + divs = $$('.'+groupRowClass); + for ( i = 0; i < divs.size(); i++) { + divs[i].addClassName('selected'); + } + + // then show that a request is pending + $(sourceDivId).addClassName('loading'); + + // and send the Ajax request + if ($(sourceDivId).childElements()[0].hasClassName('expanded')) { + toLine = fromLine + linesCount; + } + + new Ajax.Updater(sourceDivId, url + "&to_line=" + toLine, {asynchronous:true, evalScripts:true, onComplete:function(request){$(sourceDivId).removeClassName('loading');}}); + + return false; +}
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/stylesheets/style.css b/sonar-server/src/main/webapp/stylesheets/style.css index 24ed0b4dd7e..f2a5f0ec921 100644 --- a/sonar-server/src/main/webapp/stylesheets/style.css +++ b/sonar-server/src/main/webapp/stylesheets/style.css @@ -255,6 +255,10 @@ div#sidebar .selected a, div#sidebar .selected a:hover, div#sidebar.selected a:v text-align: center; } +.nowrap { + white-space: nowrap; +} + code { font-size: 93%; } @@ -641,7 +645,7 @@ table.form td { } table.form td.keyCell { width: 1%; - white-space: nowrap; + white-space: nowrap; text-align: right; font-weight: bold; vertical-align: top; |