aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabrice Bellingard <bellingard@gmail.com>2011-10-27 17:51:55 +0200
committerFabrice Bellingard <bellingard@gmail.com>2011-10-27 17:52:53 +0200
commita679de21723b04cbb6ed1e1b02bb1726125cc855 (patch)
tree2f89fb9ea12d395a7ee88de5c95c748c88ca0b4b
parent9ca0e7dfd87934fba1ea49923c4d922fdbad2ba5 (diff)
downloadsonarqube-a679de21723b04cbb6ed1e1b02bb1726125cc855.tar.gz
sonarqube-a679de21723b04cbb6ed1e1b02bb1726125cc855.zip
SONAR-2733 Display duplicated blocks by group in the resource viewer
Now waiting for the new table to feed the data that is displayed by this new duplication tab.
-rw-r--r--plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties2
-rw-r--r--sonar-server/pom.xml3
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb17
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb5
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb1
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications.html.erb36
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/resource/_duplications_source_snippet.html.erb38
-rw-r--r--sonar-server/src/main/webapp/javascripts/duplications.js25
-rw-r--r--sonar-server/src/main/webapp/stylesheets/style.css6
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;