summaryrefslogtreecommitdiffstats
path: root/sonar-server
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2011-12-22 12:23:41 +0100
committerSimon Brandhof <simon.brandhof@gmail.com>2011-12-22 12:35:55 +0100
commit181b2f8504f684d709ca79acfb3055e7e9d9dae1 (patch)
tree3cf4be986ce857b3bc1f571f4b6be19f24b667c0 /sonar-server
parent7f861f1403794ee1d5711c00a5a64914840c5e47 (diff)
downloadsonarqube-181b2f8504f684d709ca79acfb3055e7e9d9dae1.tar.gz
sonarqube-181b2f8504f684d709ca79acfb3055e7e9d9dae1.zip
SONAR-983 Display resource viewers when selecting a file
* New javascript global variable : baseUrl. Examples : '/dev' or ''
Diffstat (limited to 'sonar-server')
-rw-r--r--sonar-server/pom.xml5
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java12
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb25
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/search_controller.rb17
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb14
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb17
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/_header.html.erb26
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/violations.html.erb73
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/gwt/_base.html.erb38
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb9
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb2
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/resource/_javascript.html.erb161
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb156
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/resource/_tabs.html.erb49
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/resource/index.html.erb1
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/lib/resourceable.rb7
-rw-r--r--sonar-server/src/main/webapp/javascripts/application.js6
-rw-r--r--sonar-server/src/main/webapp/javascripts/duplication.js (renamed from sonar-server/src/main/webapp/javascripts/duplications.js)2
-rwxr-xr-xsonar-server/src/main/webapp/javascripts/protovis-sonar.js827
-rw-r--r--sonar-server/src/main/webapp/javascripts/resource.js181
21 files changed, 858 insertions, 774 deletions
diff --git a/sonar-server/pom.xml b/sonar-server/pom.xml
index 98c21266162..d2540db4111 100644
--- a/sonar-server/pom.xml
+++ b/sonar-server/pom.xml
@@ -256,7 +256,8 @@
<include>**/dashboard-min.js</include>
<include>**/protovis-min.js</include>
<include>**/protovis-sonar-min.js</include>
- <include>**/duplications-min.js</include>
+ <include>**/duplication-min.js</include>
+ <include>**/resource-min.js</include>
</includes>
<output>${project.build.directory}/${project.build.finalName}/javascripts/sonar.js</output>
</aggregation>
@@ -305,7 +306,7 @@
**/*.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/protovis-sonar*.js,
- javascripts/protovis-msie-min.js,javascripts/duplications*.js,protovis-msie-min.js,
+ javascripts/protovis-msie-min.js,javascripts/duplication*.js,protovis-msie-min.js,resource*.js,
stylesheets/yui-2.6.0*.css,stylesheets/calendar*.css,stylesheets/style*.css,stylesheets/sonar-colorizer*.css,stylesheets/dashboard*.css
</packagingExcludes>
<warSourceExcludes>
diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
index ece45af6db9..0514b55e8b7 100644
--- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
+++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
@@ -29,8 +29,6 @@ import org.sonar.api.platform.PluginRepository;
import org.sonar.api.profiles.ProfileExporter;
import org.sonar.api.profiles.ProfileImporter;
import org.sonar.api.resources.Language;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.RuleRepository;
import org.sonar.api.utils.ValidationMessages;
@@ -39,8 +37,6 @@ import org.sonar.core.i18n.RuleI18nManager;
import org.sonar.markdown.Markdown;
import org.sonar.persistence.Database;
import org.sonar.persistence.DatabaseMigrator;
-import org.sonar.persistence.resource.ResourceIndexerDao;
-import org.sonar.persistence.resource.ResourceIndexerFilter;
import org.sonar.server.configuration.Backup;
import org.sonar.server.configuration.ProfilesManager;
import org.sonar.server.filters.Filter;
@@ -382,12 +378,4 @@ public final class JRubyFacade {
public ComponentContainer getContainer() {
return Platform.getInstance().getContainer();
}
-
-
- // RESOURCE SEARCH ENGINE
- public void indexResources() {
- getContainer().getComponentByType(ResourceIndexerDao.class).index(ResourceIndexerFilter.create()
- .setQualifiers(new String[]{Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.SUBVIEW, Qualifiers.FILE, Qualifiers.CLASS, Qualifiers.UNIT_TEST_FILE})
- .setScopes(new String[]{Scopes.PROJECT, Scopes.FILE}));
- }
}
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb
index aa37b23de42..16db07a5da0 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/dashboard_controller.rb
@@ -27,10 +27,23 @@ class DashboardController < ApplicationController
def index
# TODO display error page if no dashboard or no resource
load_resource()
- load_dashboard()
- load_authorized_widget_definitions()
- unless @dashboard
- redirect_to home_path
+ if @resource.display_dashboard?
+ load_dashboard()
+ load_authorized_widget_definitions()
+ unless @dashboard
+ redirect_to home_path
+ end
+ else
+ # display the layout of the parent, usually the directory, but display the file viewers
+ @file = @resource
+ @snapshot = @snapshot.parent_snapshot
+ if @snapshot
+ @resource = @snapshot.resource
+ @project = @resource
+ render :action => 'no_dashboard'
+ else
+ redirect_to home_path
+ end
end
end
@@ -138,8 +151,6 @@ class DashboardController < ApplicationController
end
-
-
private
def load_dashboard
@@ -173,6 +184,8 @@ class DashboardController < ApplicationController
not_found("Resource not found") unless @resource
access_denied unless has_role?(:user, @resource)
@snapshot = @resource.last_snapshot
+ not_found("Snapshot not found") unless @snapshot
+
@project=@resource # variable name used in old widgets
end
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/search_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/search_controller.rb
index 83cb45e7d79..7aa2cde96d7 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/search_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/search_controller.rb
@@ -21,11 +21,9 @@ class SearchController < ApplicationController
SECTION=Navigation::SECTION_HOME
- verify :method => :post, :only => [:reset]
- before_filter :admin_required, :except => ['index']
-
# Do not exceed 1000 because of the Oracle limition on IN statements
MAX_RESULTS = 6
+
MIN_SEARCH_SIZE=3
def index
@@ -64,19 +62,6 @@ class SearchController < ApplicationController
render :partial => 'search/autocomplete'
end
- #
- # TO DELETE !!!!!
- #
- #
- # Start indexing resources
- #
- # curl -v -u admin:admin -X POST http://localhost:9000/search/reset
- def reset
- java_facade.indexResources()
- render :text => 'indexing'
- end
-
-
private
def fix_qualifier(q)
case q
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 62f4d8b44f2..871d6041a0b 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
@@ -341,20 +341,6 @@ module ApplicationHelper
end
- def link_to_resource_home(resource, options={})
- period_index=options[:period]
- period_index=nil if period_index && period_index<=0
- if resource.display_dashboard?
- link_to(options[:name] || resource.name, {:controller => 'dashboard', :action => 'index', :id => (resource.copy_resource_id||resource.id), :period => period_index, :tab => options[:tab], :rule => options[:rule]}, :title => options[:title])
- else
- if options[:line]
- anchor= 'L' + options[:line].to_s
- end
- link_to(options[:name] || resource.name, {:controller => 'resource', :action => 'index', :anchor => anchor, :id => resource.id, :period => period_index, :tab => options[:tab], :rule => options[:rule], :metric => options[:metric]}, :popup => ['resource', 'height=800,width=900,scrollbars=1,resizable=1'], :title => options[:title])
- end
- end
-
-
#
#
# JFree Eastwood is a partial implementation of Google Chart Api
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb
new file mode 100644
index 00000000000..6d99650df91
--- /dev/null
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/no_dashboard.html.erb
@@ -0,0 +1,17 @@
+<%= render :partial => 'gwt/base', :locals => {:resource => nil, :popup => false, :metric => nil} -%>
+<%= render :partial => 'gwt/resource_viewers' -%>
+
+<img id="page_loading" src="<%= ApplicationController.root_context -%>/images/loading.gif">
+<div id="resource_container"></div>
+
+<script type="text/javascript">
+ new Ajax.Updater('resource_container', '<%= ApplicationController.root_context-%>/resource/index/<%= @file.id -%>',
+ {
+ asynchronous:true,
+ evalScripts:true,
+ onComplete:function (transport) {
+ $('page_loading').hide()
+ }
+ });
+
+</script> \ No newline at end of file
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/_header.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/_header.html.erb
index 0545dff41c7..104d8671a08 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/_header.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/_header.html.erb
@@ -1,32 +1,16 @@
-<%= render :partial => 'gwt/base', :locals => {:resource => nil, :popup => false, :metric => @metric.key} -%>
+<%= render :partial => 'gwt/base', :locals => {:resource => nil, :popup => false, :metric => (@metric ? @metric.key : nil)} -%>
<%= render :partial => 'gwt/resource_viewers' -%>
<script type="text/javascript">
/* display resource */
function d(resourceId, display_title) {
var loading = new Image();
- loading.src = "<%= ApplicationController.root_context-%>/images/loading.gif";
+ loading.src = baseUrl + "/images/loading.gif";
$('resource_container').update(loading);
- if (display_title==undefined) {
- display_title=true;
+ if (display_title == undefined) {
+ display_title = true;
}
- new Ajax.Updater('resource_container', '<%= ApplicationController.root_context-%>/resource/index/' + resourceId + '?metric=<%= @metric.id if @metric -%>&rule=<%= @rule ? @rule.id : @severity -%>&period=<%= @period -%>&display_title=' + display_title, {asynchronous:true, evalScripts:true});
+ new Ajax.Updater('resource_container', baseUrl + '/resource/index/' + resourceId + '?metric=<%= @metric.id if @metric -%>&rule=<%= @rule ? @rule.id : @severity -%>&period=<%= @period -%>&display_title=' + display_title, {asynchronous:true, evalScripts:true});
return false;
}
-
- function loadAjaxTab(resourceId, tab, display_title) {
- $('resource-loading').show();
- if (display_title==undefined) {
- display_title=true;
- }
- new Ajax.Updater('resource_container', '<%= ApplicationController.root_context-%>/resource/index/' + resourceId + '?tab=' + tab + '&display_title=' + display_title, {asynchronous:true, evalScripts:true});
- return false;
- }
-
- /* display GWT component, executed from tabs */
- function loadGWT(gwtId, resourceId, resourceKey, resourceName, resourceScope, resourceQualifier, resourceLanguage) {
- config["resource"]=[{"id": resourceId, "key": resourceKey, "name" : resourceName, "scope": resourceScope, "qualifier": resourceQualifier, "lang": resourceLanguage}];
- config["resource_key"]=resourceId;
- modules[gwtId]();
- }
</script>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb
index b68fdbdf113..0d2dc97ed29 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/measures.html.erb
@@ -1,4 +1,3 @@
-<%= render :partial => 'resource/javascript' -%>
<%= render :partial => 'header' -%>
<% if params[:period] && @snapshot.project_snapshot.periods? %>
@@ -37,7 +36,8 @@
<table id="drilldown" class="width100" style="clear:left">
<% if @highlighted_metric!=@metric %>
<tr>
- <td colspan="<%= @drilldown.columns.size -%>"><%= message('drilldown.drilldown_on') -%> <b><%= format_measure(@metric.key, :period => @period) -%> <%= @metric.short_name -%></b></td>
+ <td colspan="<%= @drilldown.columns.size -%>"><%= message('drilldown.drilldown_on') -%>
+ <b><%= format_measure(@metric.key, :period => @period) -%> <%= @metric.short_name -%></b></td>
</tr>
<tr>
<% end
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/violations.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/violations.html.erb
index e6523a83ffa..3e4232c3633 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/violations.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/drilldown/violations.html.erb
@@ -1,4 +1,3 @@
-<%= render :partial => 'resource/javascript' -%>
<%= render :partial => 'header' -%>
<div id="snapshot_title" class="page_title">
@@ -126,43 +125,43 @@
@drilldown.columns.each_with_index do |column, index|
%>
<td class="column <%= 'first' if index==0 -%>" nowrap width="<%= column_width -%>%">
- <div class="scrollable" id="col_<%= column.scope -%>">
- <table class="spaced">
- <%
- column.measures.each do |measure|
- resource=column.resource(measure)
- clazz = cycle('even', 'odd', :name => "col_#{column.scope}")
- selected = column.selected_snapshot && column.selected_snapshot.project_id==resource.id
- if selected
- clazz += ' selected'
- paths << [h(resource.name), @selected_rids-[resource.id]]
- end
- %>
- <tr class="<%= clazz -%>">
- <td nowrap>
- <%
- if resource.entity?
- if resource.copy_resource_id %>
- <%= qualifier_icon(resource) -%>
- <%= link_to(h(resource.name), {:only_path => true, :overwrite_params => {:rids => nil, :id => resource.copy_resource_id}}) -%>
- <% else %>
- <%= qualifier_icon(resource) -%>
- <a href="#" onclick="d(<%= resource.id -%>, '<%= @period_index -%>', '<%= @rule ? @rule.key : @severity -%>');" alt="<%= resource.name(true) -%>" title="<%= resource.name(true) -%>"><%= resource.name(false) %></a>
+ <div class="scrollable" id="col_<%= column.scope -%>">
+ <table class="spaced">
+ <%
+ column.measures.each do |measure|
+ resource=column.resource(measure)
+ clazz = cycle('even', 'odd', :name => "col_#{column.scope}")
+ selected = column.selected_snapshot && column.selected_snapshot.project_id==resource.id
+ if selected
+ clazz += ' selected'
+ paths << [h(resource.name), @selected_rids-[resource.id]]
+ end
+ %>
+ <tr class="<%= clazz -%>">
+ <td nowrap>
<%
- end
- else %>
- <%= link_to(image_tag('zoom.png'), {:id => resource.id}, {:class => 'nolink'}) %>
- <%= qualifier_icon(resource) %>
- <%= link_to(h(resource.name), {:only_path => true, :overwrite_params => {:rids => (selected ? rids-[resource.id] : rids+[resource.id])}}) -%>
- <% end %>
- </td>
- <td class="right last" nowrap>
- <%= @period ? format_variation(measure, :period => @period, :style => 'light') : measure.formatted_value -%>
- </td>
- </tr>
- <% end %>
- </table>
- </div>
+ if resource.entity?
+ if resource.copy_resource_id %>
+ <%= qualifier_icon(resource) -%>
+ <%= link_to(h(resource.name), {:only_path => true, :overwrite_params => {:rids => nil, :id => resource.copy_resource_id}}) -%>
+ <% else %>
+ <%= qualifier_icon(resource) -%>
+ <a href="#" onclick="d(<%= resource.id -%>, '<%= @period_index -%>', '<%= @rule ? @rule.key : @severity -%>');" alt="<%= resource.name(true) -%>" title="<%= resource.name(true) -%>"><%= resource.name(false) %></a>
+ <%
+ end
+ else %>
+ <%= link_to(image_tag('zoom.png'), {:id => resource.id}, {:class => 'nolink'}) %>
+ <%= qualifier_icon(resource) %>
+ <%= link_to(h(resource.name), {:only_path => true, :overwrite_params => {:rids => (selected ? rids-[resource.id] : rids+[resource.id])}}) -%>
+ <% end %>
+ </td>
+ <td class="right last" nowrap>
+ <%= @period ? format_variation(measure, :period => @period, :style => 'light') : measure.formatted_value -%>
+ </td>
+ </tr>
+ <% end %>
+ </table>
+ </div>
</td>
<%
rids<<column.selected_snapshot.project_id if column.selected_snapshot
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/gwt/_base.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/gwt/_base.html.erb
index 242ac153fae..a7c83fa0c8c 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/gwt/_base.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/gwt/_base.html.erb
@@ -1,30 +1,30 @@
<script type="text/javascript">
var config = {
- "sonar_url":"<%= url_for(:controller => '/', :action => '', :only_path => true, :trailing_slash => false)[0...-2] -%>",
+ "sonar_url":baseUrl,
"version":"<%= sonar_version -%>",
- "popup": "<%= popup -%>"
-<% if metric %>
- ,"metric": "<%= metric -%>"
-<% end %>
+ "popup":"<%= popup -%>"
+ <% if metric %>, "metric":"<%= metric -%>"
+ <% end %>
-<%
- if resource
-%>
- ,"resource_key": "<%= resource.id -%>",
- "resource":[{"id": <%= resource.id -%>, "key":"<%= resource.key -%>","scope": "<%= resource.scope -%>", "qualifier": "<%= resource.qualifier -%>", "name": "<%= resource.name -%>", "lang":"<%= resource.language -%>"}]
-<% end %>
+ <%
+ if resource
+ %>, "resource_key":"<%= resource.id -%>",
+ "resource":[
+ {"id": <%= resource.id -%>, "key":"<%= resource.key -%>", "scope":"<%= resource.scope -%>", "qualifier":"<%= resource.qualifier -%>", "name":"<%= resource.name -%>", "lang":"<%= resource.language -%>"}
+ ]
+ <% end %>
};
var rp = {
- <%
- index=0
- params.each do |key,value|
- %>
+ <%
+ index=0
+ params.each do |key,value|
+ %>
<%= ',' if index>0 -%>"<%= key -%>":"<%= value -%>"
- <%
- index+=1
- end
- %>
+ <%
+ index+=1
+ end
+ %>
};
var modules = new Object();
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 637ec62a561..83360313865 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,7 +29,8 @@
<%= javascript_include_tag 'dashboard' %>
<%= javascript_include_tag 'protovis' %>
<%= javascript_include_tag 'protovis-sonar' %>
-<%= javascript_include_tag 'duplications' %>
+<%= javascript_include_tag 'duplication' %>
+<%= javascript_include_tag 'resource' %>
<% end %>
<!--[if lte IE 6]><link href="<%= ApplicationController.root_context -%>/ie6/index" media="all" rel="stylesheet" type="text/css" /><![endif]-->
<!--[if lte IE 8]><%= javascript_include_tag 'protovis-msie' -%><![endif]-->
@@ -37,7 +38,7 @@
<%
if @project %>
<link rel="alternate" title="Sonar Alerts on <%= @project.name -%>" href="<%= ApplicationController.root_context -%>/feeds/project/<%= @project.key -%>?category=<%= EventCategory::KEY_ALERT -%>" type="application/atom+xml">
-<% else %>
-<link rel="alternate" title="Sonar Alerts" href="<%= ApplicationController.root_context -%>/feeds/projects/<%= EventCategory::KEY_ALERT -%>" type="application/atom+xml">
-<% end %>
+<% else
+%><link rel="alternate" title="Sonar Alerts" href="<%= ApplicationController.root_context -%>/feeds/projects/<%= EventCategory::KEY_ALERT -%>" type="application/atom+xml"><%
+end %><script>var baseUrl = '<%= ApplicationController.root_context -%>';</script>
</head><body> \ No newline at end of file
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb
index 1434e3c1975..6a83896baa1 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb
@@ -7,7 +7,7 @@
<%= render :partial => 'layouts/breadcrumb' %>
<ol id="nav">
<li>
- <input type="text" size="15" name="search" id="searchResourcesInput" onFocus="autocompleteResources('<%= ApplicationController.root_context -%>')" accesskey="/" value="<%= message('search_verb') -%>"/>
+ <input type="text" size="15" name="search" id="searchResourcesInput" onFocus="autocompleteResources()" value="<%= message('search_verb') -%>"/>
<img src="<%= ApplicationController.root_context -%>/images/loading-black.gif" id="searchingResources" style="display: none">
</li>
<li>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_javascript.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_javascript.html.erb
deleted file mode 100644
index a4e72396f74..00000000000
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_javascript.html.erb
+++ /dev/null
@@ -1,161 +0,0 @@
-<script type="text/javascript">
- // show violation actions
- function sVA(violation_id) {
- var elt = $('vMsg' + violation_id);
- if (elt != null) {
- elt.hide();
- }
- elt = $('vActions' + violation_id);
- if (elt != null) {
- elt.show();
- }
- return false;
- }
-
- // hide violation actions
- function hVA(violation_id) {
- var elt = $('vMsg' + violation_id);
- if (elt != null) {
- elt.show();
- }
- elt = $('vActions' + violation_id);
- if (elt != null) {
- elt.hide();
- }
- return false;
- }
-
- // cancel action : hide form and refresh violation
- function cancelViolationAction(violation_id) {
- new Ajax.Updater(
- 'vId' + violation_id,
- '<%= ApplicationController.root_context -%>/reviews/display_violation/' + violation_id,
- {
- asynchronous:true,
- evalScripts:true
- });
- return false;
- }
-
- // show the form to comment violation
- function sCF(violation_id) {
- new Ajax.Updater('reviewForm' + violation_id,
- '<%= ApplicationController.root_context -%>/reviews/violation_comment_form/' + violation_id,
- {
- asynchronous:true,
- evalScripts:true,
- onComplete:function (request) {
- $('vBody' + violation_id).remove();
- $('reviewForm' + violation_id).show();
- $('commentText' + violation_id).focus();
- }
- });
- return false;
- }
-
- // show the form to change severity
- function sCSF(violation_id) {
- new Ajax.Updater('reviewForm' + violation_id,
- '<%= ApplicationController.root_context -%>/reviews/violation_change_severity_form/' + violation_id,
- {
- asynchronous:true,
- evalScripts:true,
- onComplete:function (request) {
- $('vBody' + violation_id).remove();
- $('reviewForm' + violation_id).show();
- $('selectSeverity' + violation_id).focus();
- }
- });
- return false;
- }
-
- // show the form to change status
- function sCStF(violation_id) {
- new Ajax.Updater('reviewForm' + violation_id,
- '<%= ApplicationController.root_context -%>/reviews/violation_change_status_form/' + violation_id,
- {
- asynchronous:true,
- evalScripts:true,
- onComplete:function (request) {
- $('vBody' + violation_id).remove();
- $('reviewForm' + violation_id).show();
- $('commentText' + violation_id).focus();
- }
- });
- return false;
- }
-
- // show the form to flag as false-positive
- function sFPF(violation_id) {
- new Ajax.Updater('reviewForm' + violation_id,
- '<%= ApplicationController.root_context -%>/reviews/violation_false_positive_form/' + violation_id,
- {
- asynchronous:true,
- evalScripts:true,
- onComplete:function (request) {
- $('vBody' + violation_id).remove();
- $('reviewForm' + violation_id).show();
- $('commentText' + violation_id).focus();
- }
- });
- return false;
- }
-
- // show the form to assign violation
- function sAF(violation_id) {
- new Ajax.Updater('reviewForm' + violation_id,
- '<%= ApplicationController.root_context -%>/reviews/violation_assign_form/' + violation_id,
- {
- asynchronous:true,
- evalScripts:true,
- onComplete:function (request) {
- $('vBody' + violation_id).remove();
- $('reviewForm' + violation_id).show();
- $('assignee_login').focus();
- }
- });
- return false;
- }
-
- // show the form to link a review to an action plan
- function sAPF(violation_id) {
- new Ajax.Updater('reviewForm' + violation_id,
- '<%= ApplicationController.root_context -%>/reviews/violation_action_plan_form/' + violation_id,
- {
- asynchronous:true,
- evalScripts:true,
- onComplete:function (request) {
- $('vBody' + violation_id).remove();
- $('reviewForm' + violation_id).show();
- $('action_plan').focus();
- }
- });
- return false;
- }
-
- // show the form to create violation
- function sVF(resource, line, gray_colspan, white_colspan) {
- row = $('createViolationForm' + line);
- if (row == null) {
- new Ajax.Updater(
- 'pos' + line,
- '<%= ApplicationController.root_context -%>/resource/show_create_violation_form',
- {
- parameters:{resource:resource, line:line, gray_colspan:gray_colspan, white_colspan:white_colspan},
- asynchronous:true,
- evalScripts:true,
- insertion:'after'
- });
- }
- return false;
- }
-
- // hide review form
- function hVF(line) {
- row = $('createViolationRow' + line);
- if (row != null) {
- row.remove();
- }
- return false;
- }
-</script> \ No newline at end of file
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb
index 221c1b3680f..c0754df974b 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb
@@ -2,91 +2,91 @@
if display_options
%>
-<div id="source_options">
- <script>
- applyOptions=function() {
- $('resource-loading').show();
- <% if request.xhr? %>
+ <div id="source_options">
+ <script>
+ applyOptions = function () {
+ $('resource_loading').show();
+ <% if request.xhr? %>
var params = Form.serialize($('options-form'));
new Ajax.Updater('resource_container', '<%= url_for :controller => 'resource', :action => 'index', :id => @resource.key -%>', {asynchronous:true, parameters:params});
return true;
- <% else %>
+ <% else %>
$('options-form').submit();
return false;
- <% end %>
- };
- </script>
- <form method="GET" action="<%= url_for :controller => 'resource', :action => 'index', :id => @resource.key -%>" id="options-form">
- <input type="hidden" name="tab" value="<%= params[:tab] -%>"/>
- <input type="hidden" name="metric" value="<%= params[:metric] -%>"/>
- <input type="hidden" name="period" value="<%= params[:period] -%>"/>
+ <% end %>
+ };
+ </script>
+ <form method="GET" action="<%= url_for :controller => 'resource', :action => 'index', :id => @resource.key -%>" id="options-form">
+ <input type="hidden" name="tab" value="<%= params[:tab] -%>"/>
+ <input type="hidden" name="metric" value="<%= params[:metric] -%>"/>
+ <input type="hidden" name="period" value="<%= params[:period] -%>"/>
- <table>
- <tr>
- <%
- first=true
- if @expandable %>
- <td class="<%= 'first' if first -%>">
- <input type="checkbox" value="true" name="expand" id="expand" <%= 'checked' if @expanded -%> onclick="applyOptions()"/>
- <label for="expand"><%= message('full_source') -%></label>
- </td>
- <% first=false
- end %>
-
- <% if @scm_available && !@display_violations && @snapshot.project_snapshot.periods? %>
- <td class="<%= 'first' if first -%>">
- <select id="period" name="period" onchange="applyOptions()">
- <option value=""><%= message('time_changes') -%>...</option>
- <%= period_select_options(@snapshot, 1) -%>
- <%= period_select_options(@snapshot, 2) -%>
- <%= period_select_options(@snapshot, 3) -%>
- <%= period_select_options(@snapshot, 4) -%>
- <%= period_select_options(@snapshot, 5) -%>
- </select>
- </td>
- <%
- first=false
- end %>
+ <table>
+ <tr>
+ <%
+ first=true
+ if @expandable %>
+ <td class="<%= 'first' if first -%>">
+ <input type="checkbox" value="true" name="expand" id="expand" <%= 'checked' if @expanded -%> onclick="applyOptions()"/>
+ <label for="expand"><%= message('full_source') -%></label>
+ </td>
+ <% first=false
+ end %>
- <% if @display_violations %>
- <td class="<%= 'first' if first -%>">
- <select id="period" name="period" onchange="applyOptions()">
- <option value=""><%= message('time_changes') -%>...</option>
- <%= violation_period_select_options(@snapshot, 1) -%>
- <%= violation_period_select_options(@snapshot, 2) -%>
- <%= violation_period_select_options(@snapshot, 3) -%>
- <%= violation_period_select_options(@snapshot, 4) -%>
- <%= violation_period_select_options(@snapshot, 5) -%>
- </select>
- </td>
+ <% if @scm_available && !@display_violations && @snapshot.project_snapshot.periods? %>
+ <td class="<%= 'first' if first -%>">
+ <select id="period" name="period" onchange="applyOptions()">
+ <option value=""><%= message('time_changes') -%>...</option>
+ <%= period_select_options(@snapshot, 1) -%>
+ <%= period_select_options(@snapshot, 2) -%>
+ <%= period_select_options(@snapshot, 3) -%>
+ <%= period_select_options(@snapshot, 4) -%>
+ <%= period_select_options(@snapshot, 5) -%>
+ </select>
+ </td>
+ <%
+ first=false
+ end %>
- <td class="<%= 'first' if first -%>"><%= render :partial => 'rules_filter' -%></td>
- <% first=false
- end %>
+ <% if @display_violations %>
+ <td class="<%= 'first' if first -%>">
+ <select id="period" name="period" onchange="applyOptions()">
+ <option value=""><%= message('time_changes') -%>...</option>
+ <%= violation_period_select_options(@snapshot, 1) -%>
+ <%= violation_period_select_options(@snapshot, 2) -%>
+ <%= violation_period_select_options(@snapshot, 3) -%>
+ <%= violation_period_select_options(@snapshot, 4) -%>
+ <%= violation_period_select_options(@snapshot, 5) -%>
+ </select>
+ </td>
- <% if @display_coverage %>
- <td class="<%= 'first' if first -%>">
- <select id="coverage_filter" name="coverage_filter" onchange="applyOptions()">
- <optgroup label="<%= h message('coverage_viewer.unit_tests') -%>">
- <option value="lines_to_cover" <%= 'selected' if @coverage_filter=='lines_to_cover' -%>><%= Metric.name_for('lines_to_cover') -%></option>
- <option value="uncovered_lines" <%= 'selected' if @coverage_filter=='uncovered_lines' -%>><%= Metric.name_for('uncovered_lines') -%></option>
- <option value="conditions_to_cover" <%= 'selected' if @coverage_filter=='conditions_to_cover' -%>><%= Metric.name_for('conditions_to_cover') -%></option>
- <option value="uncovered_conditions" <%= 'selected' if @coverage_filter=='uncovered_conditions' -%>><%= Metric.name_for('uncovered_conditions') -%></option>
- </optgroup>
- <% if @display_it_coverage %>
- <optgroup label="<%= h message('coverage_viewer.integration_tests') -%>">
- <option value="it_lines_to_cover" <%= 'selected' if @coverage_filter=='it_lines_to_cover' -%>><%= Metric.name_for('it_lines_to_cover') -%></option>
- <option value="it_uncovered_lines" <%= 'selected' if @coverage_filter=='it_uncovered_lines' -%>><%= Metric.name_for('it_uncovered_lines') -%></option>
- <option value="it_conditions_to_cover" <%= 'selected' if @coverage_filter=='it_conditions_to_cover' -%>><%= Metric.name_for('it_conditions_to_cover') -%></option>
- <option value="it_uncovered_conditions" <%= 'selected' if @coverage_filter=='it_uncovered_conditions' -%>><%= Metric.name_for('it_uncovered_conditions') -%></option>
- </optgroup>
- <% end %>
- </select>
- </td>
- <% first=false
- end %>
- </tr>
- </table>
- </form>
-</div>
+ <td class="<%= 'first' if first -%>"><%= render :partial => 'rules_filter' -%></td>
+ <% first=false
+ end %>
+
+ <% if @display_coverage %>
+ <td class="<%= 'first' if first -%>">
+ <select id="coverage_filter" name="coverage_filter" onchange="applyOptions()">
+ <optgroup label="<%= h message('coverage_viewer.unit_tests') -%>">
+ <option value="lines_to_cover" <%= 'selected' if @coverage_filter=='lines_to_cover' -%>><%= Metric.name_for('lines_to_cover') -%></option>
+ <option value="uncovered_lines" <%= 'selected' if @coverage_filter=='uncovered_lines' -%>><%= Metric.name_for('uncovered_lines') -%></option>
+ <option value="conditions_to_cover" <%= 'selected' if @coverage_filter=='conditions_to_cover' -%>><%= Metric.name_for('conditions_to_cover') -%></option>
+ <option value="uncovered_conditions" <%= 'selected' if @coverage_filter=='uncovered_conditions' -%>><%= Metric.name_for('uncovered_conditions') -%></option>
+ </optgroup>
+ <% if @display_it_coverage %>
+ <optgroup label="<%= h message('coverage_viewer.integration_tests') -%>">
+ <option value="it_lines_to_cover" <%= 'selected' if @coverage_filter=='it_lines_to_cover' -%>><%= Metric.name_for('it_lines_to_cover') -%></option>
+ <option value="it_uncovered_lines" <%= 'selected' if @coverage_filter=='it_uncovered_lines' -%>><%= Metric.name_for('it_uncovered_lines') -%></option>
+ <option value="it_conditions_to_cover" <%= 'selected' if @coverage_filter=='it_conditions_to_cover' -%>><%= Metric.name_for('it_conditions_to_cover') -%></option>
+ <option value="it_uncovered_conditions" <%= 'selected' if @coverage_filter=='it_uncovered_conditions' -%>><%= Metric.name_for('it_uncovered_conditions') -%></option>
+ </optgroup>
+ <% end %>
+ </select>
+ </td>
+ <% first=false
+ end %>
+ </tr>
+ </table>
+ </form>
+ </div>
<% end %> \ No newline at end of file
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_tabs.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_tabs.html.erb
index f2fb607c2ca..7f62bb968e9 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_tabs.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_tabs.html.erb
@@ -2,9 +2,9 @@
display_title=(params[:display_title]!='false')
if display_title
%>
-<div id="source_title">
- <span class="h1"><%= qualifier_icon(@resource) -%> <%= @resource.long_name -%></span>
-</div>
+ <div id="source_title">
+ <span class="h1"><%= qualifier_icon(@resource) -%> <%= @resource.name(true) -%></span>
+ </div>
<% end %>
<div id="source_tabs">
@@ -13,26 +13,37 @@
first=true
if @snapshot.source
%>
- <li class="<%= 'first' if first -%>"><a href="<%= ApplicationController.root_context -%>/api/sources?resource=<%= @resource.key -%>&amp;format=txt"><%= message('raw') -%></a></li>
- <% first=false
+ <li class="<%= 'first' if first -%>"><a href="<%= ApplicationController.root_context -%>/api/sources?resource=<%= @resource.key -%>&amp;format=txt"><%= message('raw') -%></a>
+ </li>
+ <% first=false
end
if request.xhr? %>
- <li class="<%= 'first' if first -%>"><a href="<%= ApplicationController.root_context -%>/resource/index/<%= @resource.key -%>" onclick="window.open(this.href,'resource','height=800,width=900,scrollbars=1,resizable=1');return false;"><%= message('new_window') -%></a></li>
+ <li class="<%= 'first' if first -%>">
+ <a href="<%= ApplicationController.root_context -%>/resource/index/<%= @resource.key -%>" onclick="window.open(this.href,'resource','height=800,width=900,scrollbars=1,resizable=1');return false;"><%= message('new_window') -%></a>
+ </li>
<% end %>
</ul>
- <ul class="tabs" >
- <% if request.xhr? %>
- <% @extensions.each do |extension| %>
- <li><a href="#" onclick="return loadAjaxTab('<%= @resource.id -%>','<%= extension.getId() -%>',<%= display_title -%>)" class="<%= 'selected' if @extension && @extension.getId()==extension.getId() -%>"><%= message(extension.getId() + '.page', :default => extension.getTitle()) %></a></li>
- <% end %>
- <% else %>
- <script>function loadTab(url) {$('resource-loading').show();document.location.href=url;return false;}</script>
- <% @extensions.each do |extension| %>
- <li><a href="#" onClick="return loadTab('<%= url_for(:overwrite_params => {:tab => extension.getId(), :metric => nil}) -%>')" class="<%= 'selected' if @extension && @extension.getId()==extension.getId() -%>"><%= message(extension.getId() + '.page', :default => extension.getTitle()) %></a></li>
+ <ul class="tabs">
+ <% if request.xhr? %>
+ <% @extensions.each do |extension| %>
+ <li>
+ <a href="#" onclick="return loadResourceViewer('<%= @resource.id -%>','<%= extension.getId() -%>',<%= display_title -%>)" class="<%= 'selected' if @extension && @extension.getId()==extension.getId() -%>"><%= message(extension.getId() + '.page', :default => extension.getTitle()) %></a>
+ </li>
+ <% end %>
+ <% else %>
+ <script>function loadTab(url) {
+ $('resource_loading').show();
+ document.location.href = url;
+ return false;
+ }</script>
+ <% @extensions.each do |extension| %>
+ <li>
+ <a href="#" onClick="return loadTab('<%= url_for(:overwrite_params => {:tab => extension.getId(), :metric => nil}) -%>')" class="<%= 'selected' if @extension && @extension.getId()==extension.getId() -%>"><%= message(extension.getId() + '.page', :default => extension.getTitle()) %></a>
+ </li>
+ <% end %>
<% end %>
- <% end %>
- <li>
- <img src="<%= ApplicationController.root_context -%>/images/loading.gif" id="resource-loading" style="display:none"/>
- </li>
+ <li>
+ <img src="<%= ApplicationController.root_context -%>/images/loading.gif" id="resource_loading" style="display:none"/>
+ </li>
</ul>
</div>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/index.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/index.html.erb
index 103503bbbc7..1dae1f827f9 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/index.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/index.html.erb
@@ -1,5 +1,4 @@
<%= render :partial => 'tabs' -%>
-<%= render :partial => 'resource/javascript' -%>
<%= render :partial => "resource/header_#{@extension.getId()}" -%>
<% if @display_violations && @global_violations && @global_violations.size>0 -%>
diff --git a/sonar-server/src/main/webapp/WEB-INF/lib/resourceable.rb b/sonar-server/src/main/webapp/WEB-INF/lib/resourceable.rb
index 341d249bbcc..606b3d3e3d8 100644
--- a/sonar-server/src/main/webapp/WEB-INF/lib/resourceable.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/lib/resourceable.rb
@@ -35,7 +35,7 @@ module Resourceable
QUALIFIER_CLASS='CLA'
QUALIFIER_UNIT_TEST_CLASS='UTS'
QUALIFIER_LIB='LIB'
- QUALIFIERS=[QUALIFIER_VIEW,QUALIFIER_SUBVIEW,QUALIFIER_PROJECT,QUALIFIER_MODULE,QUALIFIER_DIRECTORY,QUALIFIER_PACKAGE,QUALIFIER_FILE,QUALIFIER_CLASS,QUALIFIER_UNIT_TEST_CLASS,QUALIFIER_LIB]
+ QUALIFIERS=[QUALIFIER_VIEW, QUALIFIER_SUBVIEW, QUALIFIER_PROJECT, QUALIFIER_MODULE, QUALIFIER_DIRECTORY, QUALIFIER_PACKAGE, QUALIFIER_FILE, QUALIFIER_CLASS, QUALIFIER_UNIT_TEST_CLASS, QUALIFIER_LIB]
QUALIFIER_NAMES={
QUALIFIER_VIEW => 'view',
QUALIFIER_SUBVIEW => 'sub_view',
@@ -48,6 +48,7 @@ module Resourceable
QUALIFIER_UNIT_TEST_CLASS => 'unit_test',
QUALIFIER_LIB => 'library'
}
+
def set?
scope==SCOPE_SET
end
@@ -88,8 +89,8 @@ module Resourceable
qualifier==QUALIFIER_FILE
end
- NO_DASHBOARD_QUALIFIERS=[QUALIFIER_FILE,QUALIFIER_CLASS,QUALIFIER_UNIT_TEST_CLASS]
-
+ NO_DASHBOARD_QUALIFIERS=[QUALIFIER_FILE, QUALIFIER_CLASS, QUALIFIER_UNIT_TEST_CLASS]
+
def display_dashboard?
!NO_DASHBOARD_QUALIFIERS.include?(qualifier)
end
diff --git a/sonar-server/src/main/webapp/javascripts/application.js b/sonar-server/src/main/webapp/javascripts/application.js
index b61673c0b77..973b49254b7 100644
--- a/sonar-server/src/main/webapp/javascripts/application.js
+++ b/sonar-server/src/main/webapp/javascripts/application.js
@@ -12,16 +12,16 @@ function info(message) {
showMessage('info', message);
}
-function autocompleteResources(base_url) {
+function autocompleteResources() {
$('searchResourcesInput').value = '';
- new Ajax.Autocompleter('searchResourcesInput', 'searchResourcesResults', base_url + '/search', {
+ new Ajax.Autocompleter('searchResourcesInput', 'searchResourcesResults', baseUrl + '/search', {
method:'post',
minChars:3,
indicator:'searchingResources',
paramName:'s',
updateElement:function (item) {
if (item.id) {
- window.location = base_url + '/dashboard/index/' + item.id;
+ window.location = baseUrl + '/dashboard/index/' + item.id;
}
},
onShow:function (element, update) { /* no update */
diff --git a/sonar-server/src/main/webapp/javascripts/duplications.js b/sonar-server/src/main/webapp/javascripts/duplication.js
index d8664f19cce..b563873dafa 100644
--- a/sonar-server/src/main/webapp/javascripts/duplications.js
+++ b/sonar-server/src/main/webapp/javascripts/duplication.js
@@ -8,7 +8,7 @@ function updateDuplicationLines(url, groupId, itemId, linesCount, fromLine, toLi
$('duplLoading-' + groupId).addClassName('loading');
if ($('source-' + groupId).childElements()[0].hasClassName('expanded')) {
- toLine = fromLine + linesCount -1;
+ toLine = fromLine + linesCount - 1;
}
new Ajax.Updater('source-' + groupId, url + "&to_line=" + toLine + "&from_line=" + fromLine + "&lines_count=" + linesCount + "&group_index=" + groupId, {asynchronous:true, evalScripts:true});
diff --git a/sonar-server/src/main/webapp/javascripts/protovis-sonar.js b/sonar-server/src/main/webapp/javascripts/protovis-sonar.js
index 9b415412add..022c58b11ca 100755
--- a/sonar-server/src/main/webapp/javascripts/protovis-sonar.js
+++ b/sonar-server/src/main/webapp/javascripts/protovis-sonar.js
@@ -1,210 +1,250 @@
-window.SonarWidgets = {}
+window.SonarWidgets = {};
//******************* STACK AREA CHART ******************* //
SonarWidgets.StackArea = function (divId) {
- this.wDivId = divId;
- this.wHeight;
- this.wData;
- this.wSnapshots;
- this.wMetrics;
- this.wColors;
- this.height = function(height) {
- this.wHeight = height;
- return this;
- }
- this.data = function(data) {
- this.wData = data;
- return this;
- }
- this.snapshots = function(snapshots) {
- this.wSnapshots = snapshots;
- return this;
- }
- this.metrics = function(metrics) {
- this.wMetrics = metrics;
- return this;
- }
- this.colors = function(colors) {
- this.wColors = colors;
- return this;
- }
-}
-
-SonarWidgets.StackArea.prototype.render = function() {
-
- var trendData = this.wData;
- var metrics = this.wMetrics;
- var snapshots = this.wSnapshots;
- var colors = this.wColors;
-
- var widgetDiv = $(this.wDivId);
- var headerFont = "10.5px Arial,Helvetica,sans-serif";
-
- /* Computes the total of the trendData of each date */
- var total = [];
- for (i=0; i<trendData[0].size(); i++) {
- total[i] = 0;
- for (j=0; j<metrics.size();j++) {
- total[i] += trendData[j][i].y;
- }
- total[i] = "" + Math.round(total[i]*10)/10
- }
-
- /* Computes the highest Y value */
- var maxY = 0;
- for (i=0; i<trendData[0].size(); i++) {
- var currentYSum = 0;
- for (j=0; j<trendData.size(); j++) {
- currentYSum += trendData[j][i].y;
- }
- if (currentYSum > maxY) { maxY = currentYSum;}
- }
-
- /* Computes minimum width of left margin according to the max Y value so that the Y-axis is correctly displayed */
- var leftMargin = 25;
- var maxYLength = (Math.round(maxY) + "").length;
- minMargin = maxYLength * 7 + Math.floor(maxYLength /3) * 2; // first part is for numbers and second for commas (1000-separator)
- if (minMargin > leftMargin) { leftMargin = minMargin; }
-
- /* Sizing and scales. */
- var headerHeight = 40;
- var w = widgetDiv.getOffsetParent().getWidth() - leftMargin - 40;
- var h = (this.wHeight == null ? 200 : this.wHeight) + headerHeight;
-
- var x = pv.Scale.linear(pv.blend(pv.map(trendData, function(d) {return d;})), function(d) {return d.x}).range(0, w);
- var y = pv.Scale.linear(0, maxY).range(0, h-headerHeight);
- var idx_numbers = trendData[0].size();
- var idx = idx_numbers - 1;
-
- function computeIdx(xPixels) {
- var mx = x.invert(xPixels);
- var i = pv.search(trendData[0].map(function(d) {return d.x;}), mx);
- i = i < 0 ? (-i - 2) : i;
- i = i < 0 ? 0 : i;
- return i;
- }
-
- /* The root panel. */
- var vis = new pv.Panel()
- .canvas(widgetDiv)
- .width(w)
- .height(h)
- .left(leftMargin)
- .right(20)
- .bottom(30)
- .top(20)
- .strokeStyle("#CCC");
-
- /* X-axis */
- vis.add(pv.Rule)
- .data(x.ticks())
- .left(x)
- .bottom(-10)
- .height(10)
- .anchor("bottom")
- .add(pv.Label)
- .text(x.tickFormat);
-
- /* Y-axis and ticks. */
- vis.add(pv.Rule)
- .data(y.ticks(6))
- .bottom(y)
- .strokeStyle("rgba(128,128,128,.2)")
- .anchor("left")
- .add(pv.Label)
- .text(y.tickFormat);
-
- /* The stack layout */
- var area = vis.add(pv.Layout.Stack)
- .layers(trendData)
- .x(function(d) {return x(d.x);})
- .y(function(d) {return y(d.y);})
- .layer
- .add(pv.Area)
- .fillStyle(function() {return colors[this.parent.index % colors.size()][0];})
- .strokeStyle("rgba(128,128,128,.8)");
-
- /* Stack labels. */
- var firstIdx = computeIdx(w/5);
- var lastIdx = computeIdx(w*4/5);
- vis.add(pv.Panel)
- .extend(area.parent)
- .add(pv.Area)
- .extend(area)
- .fillStyle(null)
- .strokeStyle(null)
- .anchor(function() {return (idx==idx_numbers-1 || idx > lastIdx) ? "right" : ((idx==0 || idx < firstIdx) ? "left" : "center");})
- .add(pv.Label)
- .visible(function(d) {return this.index == idx && d.y != 0;})
- .font(function(d) { return Math.round(5 + Math.sqrt(y(d.y))) + "px sans-serif";})
- .textStyle("#DDD")
- .text(function(d) {return metrics[this.parent.index] + ": " + d.y;});
-
- /* The total cost of the selected dot in the header. */
- vis.add(pv.Label)
- .left(8)
- .top(16)
- .font(headerFont)
- .text(function() {return "Total: " + total[idx];});
-
- /* The date of the selected dot in the header. */
- vis.add(pv.Label)
- .left(w/2)
- .top(16)
- .font(headerFont)
- .text(function() {return snapshots[idx].ld;});
-
-
- /* The event labels */
+ this.wDivId = divId;
+ this.wHeight;
+ this.wData;
+ this.wSnapshots;
+ this.wMetrics;
+ this.wColors;
+ this.height = function (height) {
+ this.wHeight = height;
+ return this;
+ };
+ this.data = function (data) {
+ this.wData = data;
+ return this;
+ };
+ this.snapshots = function (snapshots) {
+ this.wSnapshots = snapshots;
+ return this;
+ };
+ this.metrics = function (metrics) {
+ this.wMetrics = metrics;
+ return this;
+ };
+ this.colors = function (colors) {
+ this.wColors = colors;
+ return this;
+ }
+};
+
+SonarWidgets.StackArea.prototype.render = function () {
+
+ var trendData = this.wData;
+ var metrics = this.wMetrics;
+ var snapshots = this.wSnapshots;
+ var colors = this.wColors;
+
+ var widgetDiv = $(this.wDivId);
+ var headerFont = "10.5px Arial,Helvetica,sans-serif";
+
+ /* Computes the total of the trendData of each date */
+ var total = [];
+ for (i = 0; i < trendData[0].size(); i++) {
+ total[i] = 0;
+ for (j = 0; j < metrics.size(); j++) {
+ total[i] += trendData[j][i].y;
+ }
+ total[i] = "" + Math.round(total[i] * 10) / 10
+ }
+
+ /* Computes the highest Y value */
+ var maxY = 0;
+ for (i = 0; i < trendData[0].size(); i++) {
+ var currentYSum = 0;
+ for (j = 0; j < trendData.size(); j++) {
+ currentYSum += trendData[j][i].y;
+ }
+ if (currentYSum > maxY) {
+ maxY = currentYSum;
+ }
+ }
+
+ /* Computes minimum width of left margin according to the max Y value so that the Y-axis is correctly displayed */
+ var leftMargin = 25;
+ var maxYLength = (Math.round(maxY) + "").length;
+ minMargin = maxYLength * 7 + Math.floor(maxYLength / 3) * 2; // first part is for numbers and second for commas (1000-separator)
+ if (minMargin > leftMargin) {
+ leftMargin = minMargin;
+ }
+
+ /* Sizing and scales. */
+ var headerHeight = 40;
+ var w = widgetDiv.getOffsetParent().getWidth() - leftMargin - 40;
+ var h = (this.wHeight == null ? 200 : this.wHeight) + headerHeight;
+
+ var x = pv.Scale.linear(pv.blend(pv.map(trendData, function (d) {
+ return d;
+ })),
+ function (d) {
+ return d.x
+ }).range(0, w);
+ var y = pv.Scale.linear(0, maxY).range(0, h - headerHeight);
+ var idx_numbers = trendData[0].size();
+ var idx = idx_numbers - 1;
+
+ function computeIdx(xPixels) {
+ var mx = x.invert(xPixels);
+ var i = pv.search(trendData[0].map(function (d) {
+ return d.x;
+ }), mx);
+ i = i < 0 ? (-i - 2) : i;
+ i = i < 0 ? 0 : i;
+ return i;
+ }
+
+ /* The root panel. */
+ var vis = new pv.Panel()
+ .canvas(widgetDiv)
+ .width(w)
+ .height(h)
+ .left(leftMargin)
+ .right(20)
+ .bottom(30)
+ .top(20)
+ .strokeStyle("#CCC");
+
+ /* X-axis */
+ vis.add(pv.Rule)
+ .data(x.ticks())
+ .left(x)
+ .bottom(-10)
+ .height(10)
+ .anchor("bottom")
+ .add(pv.Label)
+ .text(x.tickFormat);
+
+ /* Y-axis and ticks. */
+ vis.add(pv.Rule)
+ .data(y.ticks(6))
+ .bottom(y)
+ .strokeStyle("rgba(128,128,128,.2)")
+ .anchor("left")
+ .add(pv.Label)
+ .text(y.tickFormat);
+
+ /* The stack layout */
+ var area = vis.add(pv.Layout.Stack)
+ .layers(trendData)
+ .x(function (d) {
+ return x(d.x);
+ })
+ .y(function (d) {
+ return y(d.y);
+ })
+ .layer
+ .add(pv.Area)
+ .fillStyle(function () {
+ return colors[this.parent.index % colors.size()][0];
+ })
+ .strokeStyle("rgba(128,128,128,.8)");
+
+ /* Stack labels. */
+ var firstIdx = computeIdx(w / 5);
+ var lastIdx = computeIdx(w * 4 / 5);
+ vis.add(pv.Panel)
+ .extend(area.parent)
+ .add(pv.Area)
+ .extend(area)
+ .fillStyle(null)
+ .strokeStyle(null)
+ .anchor(function () {
+ return (idx == idx_numbers - 1 || idx > lastIdx) ? "right" : ((idx == 0 || idx < firstIdx) ? "left" : "center");
+ })
+ .add(pv.Label)
+ .visible(function (d) {
+ return this.index == idx && d.y != 0;
+ })
+ .font(function (d) {
+ return Math.round(5 + Math.sqrt(y(d.y))) + "px sans-serif";
+ })
+ .textStyle("#DDD")
+ .text(function (d) {
+ return metrics[this.parent.index] + ": " + d.y;
+ });
+
+ /* The total cost of the selected dot in the header. */
+ vis.add(pv.Label)
+ .left(8)
+ .top(16)
+ .font(headerFont)
+ .text(function () {
+ return "Total: " + total[idx];
+ });
+
+ /* The date of the selected dot in the header. */
+ vis.add(pv.Label)
+ .left(w / 2)
+ .top(16)
+ .font(headerFont)
+ .text(function () {
+ return snapshots[idx].ld;
+ });
+
+
+ /* The event labels */
eventColor = "rgba(75,159,213,1)";
eventHoverColor = "rgba(202,227,242,1)";
vis.add(pv.Line)
- .strokeStyle("rgba(0,0,0,.001)")
- .data(snapshots)
- .left(function(s) {return x(s.d);})
- .bottom(0)
- .anchor("top")
- .add(pv.Dot)
- .bottom(-6)
- .shape("triangle")
- .angle(pv.radians(180))
- .strokeStyle("grey")
- .visible(function(s) {return s.e.size() > 0;})
- .fillStyle(function() {return this.index == idx ? eventHoverColor : eventColor;})
- .add(pv.Dot)
- .radius(3)
- .visible(function(s) {return s.e.size() > 0 && this.index == idx;})
- .left(w/2+8)
- .top(24)
- .shape("triangle")
- .fillStyle(function() {return this.index == idx ? eventHoverColor : eventColor;})
- .strokeStyle("grey")
- .anchor("right")
- .add(pv.Label)
- .font(headerFont)
- .text(function(s) {return s.e.size() == 0 ? "" : s.e[0] + ( s.e[1] ? " (... +" + (s.e.size()-1) + ")" : "");});
-
- /* An invisible bar to capture events (without flickering). */
- vis.add(pv.Bar)
- .fillStyle("rgba(0,0,0,.001)")
- .width(w+30)
- .height(h+30)
- .event("mouseout", function() {
- i = -1;
- return vis;
- })
- .event("mousemove", function() {
- idx = computeIdx(vis.mouse().x);
- return vis;
- });
-
- vis.render();
+ .strokeStyle("rgba(0,0,0,.001)")
+ .data(snapshots)
+ .left(function (s) {
+ return x(s.d);
+ })
+ .bottom(0)
+ .anchor("top")
+ .add(pv.Dot)
+ .bottom(-6)
+ .shape("triangle")
+ .angle(pv.radians(180))
+ .strokeStyle("grey")
+ .visible(function (s) {
+ return s.e.size() > 0;
+ })
+ .fillStyle(function () {
+ return this.index == idx ? eventHoverColor : eventColor;
+ })
+ .add(pv.Dot)
+ .radius(3)
+ .visible(function (s) {
+ return s.e.size() > 0 && this.index == idx;
+ })
+ .left(w / 2 + 8)
+ .top(24)
+ .shape("triangle")
+ .fillStyle(function () {
+ return this.index == idx ? eventHoverColor : eventColor;
+ })
+ .strokeStyle("grey")
+ .anchor("right")
+ .add(pv.Label)
+ .font(headerFont)
+ .text(function (s) {
+ return s.e.size() == 0 ? "" : s.e[0] + ( s.e[1] ? " (... +" + (s.e.size() - 1) + ")" : "");
+ });
+
+ /* An invisible bar to capture events (without flickering). */
+ vis.add(pv.Bar)
+ .fillStyle("rgba(0,0,0,.001)")
+ .width(w + 30)
+ .height(h + 30)
+ .event("mouseout", function () {
+ i = -1;
+ return vis;
+ })
+ .event("mousemove", function () {
+ idx = computeIdx(vis.mouse().x);
+ return vis;
+ });
+
+ vis.render();
};
-
//******************* TIMELINE CHART ******************* //
/*
* Displays the evolution of metrics on a line chart, displaying related events.
@@ -221,187 +261,226 @@ SonarWidgets.StackArea.prototype.render = function() {
*
* Example: displays 2 metrics:
*
-<code>
-function d(y,m,d,h,min,s) {
- return new Date(y,m,d,h,min,s);
-}
-var data = [
- [{x:d(2011,5,15,0,1,0),y:912.00,yl:"912"},{x:d(2011,6,21,0,1,0),y:152.10,yl:"152.10"}],
- [{x:d(2011,5,15,0,1,0),y:52.20,yi:"52.20"},{x:d(2011,6,21,0,1,0),y:1452.10,yi:"1,452.10"}]
- ];
-var metrics = ["Lines of code","Rules compliance"];
-var snapshots = [{sid:1,d:"June 15, 2011 00:01"},{sid:30,d:"July 21, 2011 00:01"}];
-var events = [
- {sid:1,d:d(2011,5,15,0,1,0),l:[{n:"0.6-SNAPSHOT"},{n:"Sun checks"}]},
- {sid:30,d:d(2011,6,21,0,1,0),l:[{n:"0.7-SNAPSHOT"}]}
- ];
-
-var timeline = new SonarWidgets.Timeline('timeline-chart-20')
- .height(160)
- .data(data)
- .snapshots(snapshots)
- .metrics(metrics)
- .events(events);
-timeline.render();
-</code>
+ <code>
+ function d(y,m,d,h,min,s) {
+ return new Date(y,m,d,h,min,s);
+ }
+ var data = [
+ [{x:d(2011,5,15,0,1,0),y:912.00,yl:"912"},{x:d(2011,6,21,0,1,0),y:152.10,yl:"152.10"}],
+ [{x:d(2011,5,15,0,1,0),y:52.20,yi:"52.20"},{x:d(2011,6,21,0,1,0),y:1452.10,yi:"1,452.10"}]
+ ];
+ var metrics = ["Lines of code","Rules compliance"];
+ var snapshots = [{sid:1,d:"June 15, 2011 00:01"},{sid:30,d:"July 21, 2011 00:01"}];
+ var events = [
+ {sid:1,d:d(2011,5,15,0,1,0),l:[{n:"0.6-SNAPSHOT"},{n:"Sun checks"}]},
+ {sid:30,d:d(2011,6,21,0,1,0),l:[{n:"0.7-SNAPSHOT"}]}
+ ];
+
+ var timeline = new SonarWidgets.Timeline('timeline-chart-20')
+ .height(160)
+ .data(data)
+ .snapshots(snapshots)
+ .metrics(metrics)
+ .events(events);
+ timeline.render();
+ </code>
*
*/
SonarWidgets.Timeline = function (divId) {
- this.wDivId = divId;
- this.wHeight;
- this.wData;
- this.wSnapshots;
- this.wMetrics;
- this.wEvents;
- this.height = function(height) {
- this.wHeight = height;
- return this;
- };
- this.data = function(data) {
- this.wData = data;
- return this;
- };
- this.snapshots = function(snapshots) {
- this.wSnapshots = snapshots;
- return this;
- };
- this.metrics = function(metrics) {
- this.wMetrics = metrics;
- return this;
- };
- this.events = function(events) {
- this.wEvents = events;
- return this;
- };
+ this.wDivId = divId;
+ this.wHeight;
+ this.wData;
+ this.wSnapshots;
+ this.wMetrics;
+ this.wEvents;
+ this.height = function (height) {
+ this.wHeight = height;
+ return this;
+ };
+ this.data = function (data) {
+ this.wData = data;
+ return this;
+ };
+ this.snapshots = function (snapshots) {
+ this.wSnapshots = snapshots;
+ return this;
+ };
+ this.metrics = function (metrics) {
+ this.wMetrics = metrics;
+ return this;
+ };
+ this.events = function (events) {
+ this.wEvents = events;
+ return this;
+ };
};
-SonarWidgets.Timeline.prototype.render = function() {
-
- var trendData = this.wData;
- var metrics = this.wMetrics;
- var snapshots = this.wSnapshots;
- var events = this.wEvents;
-
- var widgetDiv = $(this.wDivId);
- var headerFont = "10.5px Arial,Helvetica,sans-serif";
-
- /* Sizing and scales. */
- var headerHeight = 4 + Math.max(this.wMetrics.size(), events ? 2 : 1) * 18;
- var w = widgetDiv.getOffsetParent().getWidth() - 60;
- var h = (this.wHeight==null || this.wHeight<=0 ? 80 : this.wHeight) + headerHeight;
- var yMaxHeight = h-headerHeight;
-
- var x = pv.Scale.linear(pv.blend(pv.map(trendData, function(d) {return d;})), function(d) {return d.x}).range(0, w);
- var y = new Array(trendData.size());
- for(var i = 0; i < trendData.size(); i++){
- y[i]=pv.Scale.linear(trendData[i], function(d) {return d.y;}).range(20, yMaxHeight);
- }
- var interpolate = "linear"; /* cardinal or linear */
- var idx = trendData[0].size() - 1;
-
- /* The root panel. */
- var vis = new pv.Panel()
- .canvas(widgetDiv)
- .width(w)
- .height(h)
- .left(20)
- .right(20)
- .bottom(30)
- .top(5)
- .strokeStyle("#CCC");
-
- /* X-axis */
- vis.add(pv.Rule)
- .data(x.ticks())
- .left(x)
- .bottom(-10)
- .height(10)
- .anchor("bottom")
- .add(pv.Label)
- .text(x.tickFormat);
-
- /* A panel for each data series. */
- var panel = vis.add(pv.Panel)
- .data(trendData);
-
- /* The line. */
- var line = panel.add(pv.Line)
- .data(function(array) {return array;})
- .left(function(d) {return x(d.x);})
- .bottom(function(d) {var yAxis = y[this.parent.index](d.y); return isNaN(yAxis) ? yMaxHeight : yAxis;})
- .interpolate(function() {return interpolate;})
- .lineWidth(2);
-
- /* The mouseover dots and label in header. */
- line.add(pv.Dot)
- .data(function(d) {return [d[idx]];})
- .fillStyle(function() {return line.strokeStyle();})
- .strokeStyle("#000")
- .size(20)
- .lineWidth(1)
- .add(pv.Dot)
- .radius(3)
- .left(10)
- .top(function() {return 10 + this.parent.index * 14;})
- .anchor("right").add(pv.Label)
- .font(headerFont)
- .text(function(d) {return metrics[this.parent.index] + ": " + d.yl;});
-
- /* The date of the selected dot in the header. */
- vis.add(pv.Label)
- .left(w/2)
- .top(16)
- .font(headerFont)
- .text(function() {return snapshots[idx].d;});
-
- /* The event labels */
- if (events) {
- eventColor = "rgba(75,159,213,1)";
- eventHoverColor = "rgba(202,227,242,1)";
- vis.add(pv.Line)
- .strokeStyle("rgba(0,0,0,.001)")
- .data(events)
- .left(function(e) {return x(e.d);})
- .bottom(0)
- .anchor("top")
- .add(pv.Dot)
- .bottom(-6)
- .shape("triangle")
- .angle(pv.radians(180))
- .strokeStyle("grey")
- .fillStyle(function(e) {return e.sid == snapshots[idx].sid ? eventHoverColor : eventColor;})
- .add(pv.Dot)
- .radius(3)
- .visible(function(e) { return e.sid == snapshots[idx].sid;})
- .left(w/2+8)
- .top(24)
- .shape("triangle")
- .fillStyle(function(e) {return e.sid == snapshots[idx].sid ? eventHoverColor : eventColor;})
- .strokeStyle("grey")
- .anchor("right")
- .add(pv.Label)
- .font(headerFont)
- .text(function(e) {return e.l[0].n + ( e.l[1] ? " (... +" + (e.l.size()-1) + ")" : "");});
- }
-
- /* An invisible bar to capture events (without flickering). */
- vis.add(pv.Bar)
- .fillStyle("rgba(0,0,0,.001)")
- .width(w+30)
- .height(h+30)
- .event("mouseout", function() {
- i = -1;
- return vis;
- })
- .event("mousemove", function() {
- var mx = x.invert(vis.mouse().x);
- idx = pv.search(trendData[0].map(function(d) {return d.x;}), mx);
- idx = idx < 0 ? (-idx - 2) : idx;
- idx = idx < 0 ? 0 : idx;
- return vis;
- });
-
- vis.render();
-
-} \ No newline at end of file
+SonarWidgets.Timeline.prototype.render = function () {
+
+ var trendData = this.wData;
+ var metrics = this.wMetrics;
+ var snapshots = this.wSnapshots;
+ var events = this.wEvents;
+
+ var widgetDiv = $(this.wDivId);
+ var headerFont = "10.5px Arial,Helvetica,sans-serif";
+
+ /* Sizing and scales. */
+ var headerHeight = 4 + Math.max(this.wMetrics.size(), events ? 2 : 1) * 18;
+ var w = widgetDiv.getOffsetParent().getWidth() - 60;
+ var h = (this.wHeight == null || this.wHeight <= 0 ? 80 : this.wHeight) + headerHeight;
+ var yMaxHeight = h - headerHeight;
+
+ var x = pv.Scale.linear(pv.blend(pv.map(trendData, function (d) {
+ return d;
+ })),
+ function (d) {
+ return d.x
+ }).range(0, w);
+ var y = new Array(trendData.size());
+ for (var i = 0; i < trendData.size(); i++) {
+ y[i] = pv.Scale.linear(trendData[i],
+ function (d) {
+ return d.y;
+ }).range(20, yMaxHeight);
+ }
+ var interpolate = "linear";
+ /* cardinal or linear */
+ var idx = trendData[0].size() - 1;
+
+ /* The root panel. */
+ var vis = new pv.Panel()
+ .canvas(widgetDiv)
+ .width(w)
+ .height(h)
+ .left(20)
+ .right(20)
+ .bottom(30)
+ .top(5)
+ .strokeStyle("#CCC");
+
+ /* X-axis */
+ vis.add(pv.Rule)
+ .data(x.ticks())
+ .left(x)
+ .bottom(-10)
+ .height(10)
+ .anchor("bottom")
+ .add(pv.Label)
+ .text(x.tickFormat);
+
+ /* A panel for each data series. */
+ var panel = vis.add(pv.Panel)
+ .data(trendData);
+
+ /* The line. */
+ var line = panel.add(pv.Line)
+ .data(function (array) {
+ return array;
+ })
+ .left(function (d) {
+ return x(d.x);
+ })
+ .bottom(function (d) {
+ var yAxis = y[this.parent.index](d.y);
+ return isNaN(yAxis) ? yMaxHeight : yAxis;
+ })
+ .interpolate(function () {
+ return interpolate;
+ })
+ .lineWidth(2);
+
+ /* The mouseover dots and label in header. */
+ line.add(pv.Dot)
+ .data(function (d) {
+ return [d[idx]];
+ })
+ .fillStyle(function () {
+ return line.strokeStyle();
+ })
+ .strokeStyle("#000")
+ .size(20)
+ .lineWidth(1)
+ .add(pv.Dot)
+ .radius(3)
+ .left(10)
+ .top(function () {
+ return 10 + this.parent.index * 14;
+ })
+ .anchor("right").add(pv.Label)
+ .font(headerFont)
+ .text(function (d) {
+ return metrics[this.parent.index] + ": " + d.yl;
+ });
+
+ /* The date of the selected dot in the header. */
+ vis.add(pv.Label)
+ .left(w / 2)
+ .top(16)
+ .font(headerFont)
+ .text(function () {
+ return snapshots[idx].d;
+ });
+
+ /* The event labels */
+ if (events) {
+ eventColor = "rgba(75,159,213,1)";
+ eventHoverColor = "rgba(202,227,242,1)";
+ vis.add(pv.Line)
+ .strokeStyle("rgba(0,0,0,.001)")
+ .data(events)
+ .left(function (e) {
+ return x(e.d);
+ })
+ .bottom(0)
+ .anchor("top")
+ .add(pv.Dot)
+ .bottom(-6)
+ .shape("triangle")
+ .angle(pv.radians(180))
+ .strokeStyle("grey")
+ .fillStyle(function (e) {
+ return e.sid == snapshots[idx].sid ? eventHoverColor : eventColor;
+ })
+ .add(pv.Dot)
+ .radius(3)
+ .visible(function (e) {
+ return e.sid == snapshots[idx].sid;
+ })
+ .left(w / 2 + 8)
+ .top(24)
+ .shape("triangle")
+ .fillStyle(function (e) {
+ return e.sid == snapshots[idx].sid ? eventHoverColor : eventColor;
+ })
+ .strokeStyle("grey")
+ .anchor("right")
+ .add(pv.Label)
+ .font(headerFont)
+ .text(function (e) {
+ return e.l[0].n + ( e.l[1] ? " (... +" + (e.l.size() - 1) + ")" : "");
+ });
+ }
+
+ /* An invisible bar to capture events (without flickering). */
+ vis.add(pv.Bar)
+ .fillStyle("rgba(0,0,0,.001)")
+ .width(w + 30)
+ .height(h + 30)
+ .event("mouseout", function () {
+ i = -1;
+ return vis;
+ })
+ .event("mousemove", function () {
+ var mx = x.invert(vis.mouse().x);
+ idx = pv.search(trendData[0].map(function (d) {
+ return d.x;
+ }), mx);
+ idx = idx < 0 ? (-idx - 2) : idx;
+ idx = idx < 0 ? 0 : idx;
+ return vis;
+ });
+
+ vis.render();
+}; \ No newline at end of file
diff --git a/sonar-server/src/main/webapp/javascripts/resource.js b/sonar-server/src/main/webapp/javascripts/resource.js
new file mode 100644
index 00000000000..11e8627b59f
--- /dev/null
+++ b/sonar-server/src/main/webapp/javascripts/resource.js
@@ -0,0 +1,181 @@
+/*
+ Functions used in resource viewers
+ */
+
+function loadResourceViewer(resourceId, tab, display_title) {
+ $('resource_loading').show();
+ if (display_title == undefined) {
+ display_title = true;
+ }
+ new Ajax.Updater('resource_container', baseUrl + '/resource/index/' + resourceId + '?tab=' + tab + '&display_title=' + display_title, {asynchronous:true, evalScripts:true});
+ return false;
+}
+
+// Display GWT component
+function loadGWT(gwtId, resourceId, resourceKey, resourceName, resourceScope, resourceQualifier, resourceLanguage) {
+ config["resource"] = [
+ {"id":resourceId, "key":resourceKey, "name":resourceName, "scope":resourceScope, "qualifier":resourceQualifier, "lang":resourceLanguage}
+ ];
+ config["resource_key"] = resourceId;
+ modules[gwtId]();
+}
+
+// show violation actions
+function sVA(violation_id) {
+ var elt = $('vMsg' + violation_id);
+ if (elt != null) {
+ elt.hide();
+ }
+ elt = $('vActions' + violation_id);
+ if (elt != null) {
+ elt.show();
+ }
+ return false;
+}
+
+// hide violation actions
+function hVA(violation_id) {
+ var elt = $('vMsg' + violation_id);
+ if (elt != null) {
+ elt.show();
+ }
+ elt = $('vActions' + violation_id);
+ if (elt != null) {
+ elt.hide();
+ }
+ return false;
+}
+
+// cancel action : hide form and refresh violation
+function cancelViolationAction(violation_id) {
+ new Ajax.Updater(
+ 'vId' + violation_id,
+ baseUrl + '/reviews/display_violation/' + violation_id,
+ {
+ asynchronous:true,
+ evalScripts:true
+ });
+ return false;
+}
+
+// show the form to comment violation
+function sCF(violation_id) {
+ new Ajax.Updater('reviewForm' + violation_id,
+ baseUrl + '/reviews/violation_comment_form/' + violation_id,
+ {
+ asynchronous:true,
+ evalScripts:true,
+ onComplete:function (request) {
+ $('vBody' + violation_id).remove();
+ $('reviewForm' + violation_id).show();
+ $('commentText' + violation_id).focus();
+ }
+ });
+ return false;
+}
+
+// show the form to change severity
+function sCSF(violation_id) {
+ new Ajax.Updater('reviewForm' + violation_id,
+ baseUrl + '/reviews/violation_change_severity_form/' + violation_id,
+ {
+ asynchronous:true,
+ evalScripts:true,
+ onComplete:function (request) {
+ $('vBody' + violation_id).remove();
+ $('reviewForm' + violation_id).show();
+ $('selectSeverity' + violation_id).focus();
+ }
+ });
+ return false;
+}
+
+// show the form to change status
+function sCStF(violation_id) {
+ new Ajax.Updater('reviewForm' + violation_id,
+ baseUrl + '/reviews/violation_change_status_form/' + violation_id,
+ {
+ asynchronous:true,
+ evalScripts:true,
+ onComplete:function (request) {
+ $('vBody' + violation_id).remove();
+ $('reviewForm' + violation_id).show();
+ $('commentText' + violation_id).focus();
+ }
+ });
+ return false;
+}
+
+// show the form to flag as false-positive
+function sFPF(violation_id) {
+ new Ajax.Updater('reviewForm' + violation_id,
+ baseUrl + '/reviews/violation_false_positive_form/' + violation_id,
+ {
+ asynchronous:true,
+ evalScripts:true,
+ onComplete:function (request) {
+ $('vBody' + violation_id).remove();
+ $('reviewForm' + violation_id).show();
+ $('commentText' + violation_id).focus();
+ }
+ });
+ return false;
+}
+
+// show the form to assign violation
+function sAF(violation_id) {
+ new Ajax.Updater('reviewForm' + violation_id,
+ baseUrl + '/reviews/violation_assign_form/' + violation_id,
+ {
+ asynchronous:true,
+ evalScripts:true,
+ onComplete:function (request) {
+ $('vBody' + violation_id).remove();
+ $('reviewForm' + violation_id).show();
+ $('assignee_login').focus();
+ }
+ });
+ return false;
+}
+
+// show the form to link a review to an action plan
+function sAPF(violation_id) {
+ new Ajax.Updater('reviewForm' + violation_id,
+ baseUrl + '/reviews/violation_action_plan_form/' + violation_id,
+ {
+ asynchronous:true,
+ evalScripts:true,
+ onComplete:function (request) {
+ $('vBody' + violation_id).remove();
+ $('reviewForm' + violation_id).show();
+ $('action_plan').focus();
+ }
+ });
+ return false;
+}
+
+// show the form to create violation
+function sVF(resource, line, gray_colspan, white_colspan) {
+ row = $('createViolationForm' + line);
+ if (row == null) {
+ new Ajax.Updater(
+ 'pos' + line,
+ baseUrl + '/resource/show_create_violation_form',
+ {
+ parameters:{resource:resource, line:line, gray_colspan:gray_colspan, white_colspan:white_colspan},
+ asynchronous:true,
+ evalScripts:true,
+ insertion:'after'
+ });
+ }
+ return false;
+}
+
+// hide review form
+function hVF(line) {
+ row = $('createViolationRow' + line);
+ if (row != null) {
+ row.remove();
+ }
+ return false;
+} \ No newline at end of file