diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2012-12-04 22:35:33 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2012-12-04 22:51:19 +0100 |
commit | f5e7cabed70e681245a70da35700124ca805af76 (patch) | |
tree | 11747766bc236c1d75b851a080e0bbeff50de9c9 | |
parent | 2baa5c84dff8b707c5d745e2a2a8cbdc7e028bf1 (diff) | |
download | sonarqube-f5e7cabed70e681245a70da35700124ca805af76.tar.gz sonarqube-f5e7cabed70e681245a70da35700124ca805af76.zip |
SONAR-3825 move treemap from prototypejs to jquery
11 files changed, 176 insertions, 192 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DefaultResourceTypes.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DefaultResourceTypes.java index 72bd2cb244e..4cbe473af28 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DefaultResourceTypes.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DefaultResourceTypes.java @@ -38,28 +38,28 @@ public final class DefaultResourceTypes extends ExtensionProvider implements Bat .setProperty("modifiable_history", true) .setProperty("hasRolePolicy", true) .setProperty("updatable_key", true) - .setProperty("supports_measure_filters", true) + .setProperty("supportsMeasureFilters", true) .setProperty("comparable", true) .build()) .addType(ResourceType.builder(Qualifiers.MODULE) .setProperty("updatable_key", true) - .setProperty("supports_measure_filters", true) + .setProperty("supportsMeasureFilters", true) .build()) .addType(ResourceType.builder(Qualifiers.DIRECTORY) - .setProperty("supports_measure_filters", true) + .setProperty("supportsMeasureFilters", true) .build()) .addType(ResourceType.builder(Qualifiers.PACKAGE) .build()) .addType(ResourceType.builder(Qualifiers.FILE) .hasSourceCode() - .setProperty("supports_measure_filters", true) + .setProperty("supportsMeasureFilters", true) .build()) .addType(ResourceType.builder(Qualifiers.CLASS) .hasSourceCode() .build()) .addType(ResourceType.builder(Qualifiers.UNIT_TEST_FILE) .hasSourceCode() - .setProperty("supports_measure_filters", true) + .setProperty("supportsMeasureFilters", true) .build()) .addRelations(Qualifiers.PROJECT, Qualifiers.MODULE) diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceType.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceType.java index bda5124bff6..93b6a0da86b 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceType.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceType.java @@ -40,7 +40,7 @@ import java.util.Map; * </p> * <ul> * <li>"deletable": if set to "true", then this resource can be deleted/purged.</li> - * <li>"supports_measure_filters": if set to "true", then this resource can be displayed in measure filters</li> + * <li>"supportsMeasureFilters": if set to "true", then this resource can be displayed in measure filters</li> * <li>"modifiable_history": if set to "true", then the history of this resource may be modified (deletion of snapshots, modification of events, ...)</li> * <li>"updatable_key" (since 3.2): if set to "true", then it is possible to update the key of this resource</li> * <li>"supportsGlobalDashboards" (since 3.2): if true, this resource can be displayed in global dashboards</li> @@ -84,11 +84,11 @@ public final class ResourceType { } /** - * @deprecated since 3.0. Use {@link #setProperty(String, String)} with "supports_measure_filters" set to "true". + * @deprecated since 3.0. Use {@link #setProperty(String, String)} with "supportsMeasureFilters" set to "true". */ @Deprecated public Builder availableForFilters() { - setProperty("supports_measure_filters", "true"); + setProperty("supportsMeasureFilters", "true"); return this; } @@ -112,7 +112,7 @@ public final class ResourceType { // for backward-compatibility since version 3.4 if (key.equals("availableForFilters")) { - properties.put("supports_measure_filters", value); + properties.put("supportsMeasureFilters", value); } return this; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java index f3494e963c2..4834fa61848 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java @@ -45,7 +45,7 @@ public final class ResourceTypes implements BatchComponent, ServerComponent { public static final Predicate<ResourceType> AVAILABLE_FOR_FILTERS = new Predicate<ResourceType>() { public boolean apply(@Nullable ResourceType input) { - return input != null && input.getBooleanProperty("supports_measure_filters"); + return input != null && input.getBooleanProperty("supportsMeasureFilters"); } }; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypeTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypeTest.java index 98e11c609d3..9d38bdb852d 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypeTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypeTest.java @@ -40,13 +40,13 @@ public class ResourceTypeTest { ResourceType def = ResourceType.builder("qualifier") .setIconPath("/custom-icon.png") .hasSourceCode() - .setProperty("supports_measure_filters", "true") + .setProperty("supportsMeasureFilters", "true") .setProperty("anotherProperty", "foo") .build(); assertThat(def.getQualifier()).isEqualTo("qualifier"); assertThat(def.getIconPath()).isEqualTo("/custom-icon.png"); assertThat(def.hasSourceCode()).isTrue(); - assertThat(def.getBooleanProperty("supports_measure_filters")).isTrue(); + assertThat(def.getBooleanProperty("supportsMeasureFilters")).isTrue(); assertThat(def.getStringProperty("anotherProperty")).isEqualTo("foo"); } @@ -71,32 +71,32 @@ public class ResourceTypeTest { @Test public void testDeprecatedIsAvailableForFiltesCompatibility() { ResourceType def = ResourceType.builder("qualifier").build(); - assertThat(def.getBooleanProperty("supports_measure_filters")).isFalse(); + assertThat(def.getBooleanProperty("supportsMeasureFilters")).isFalse(); def = ResourceType.builder("qualifier").availableForFilters().build(); - assertThat(def.getBooleanProperty("supports_measure_filters")).isTrue(); + assertThat(def.getBooleanProperty("supportsMeasureFilters")).isTrue(); } @Test public void getBooleanProperty_is_set() { // set with boolean parameter - ResourceType def = ResourceType.builder("qualifier").setProperty("supports_measure_filters", true).build(); - assertThat(def.getBooleanProperty("supports_measure_filters")).isTrue(); + ResourceType def = ResourceType.builder("qualifier").setProperty("supportsMeasureFilters", true).build(); + assertThat(def.getBooleanProperty("supportsMeasureFilters")).isTrue(); - def = ResourceType.builder("qualifier").setProperty("supports_measure_filters", false).build(); - assertThat(def.getBooleanProperty("supports_measure_filters")).isFalse(); + def = ResourceType.builder("qualifier").setProperty("supportsMeasureFilters", false).build(); + assertThat(def.getBooleanProperty("supportsMeasureFilters")).isFalse(); - def = ResourceType.builder("qualifier").setProperty("supports_measure_filters", "true").build(); - assertThat(def.getBooleanProperty("supports_measure_filters")).isTrue(); + def = ResourceType.builder("qualifier").setProperty("supportsMeasureFilters", "true").build(); + assertThat(def.getBooleanProperty("supportsMeasureFilters")).isTrue(); - def = ResourceType.builder("qualifier").setProperty("supports_measure_filters", "false").build(); - assertThat(def.getBooleanProperty("supports_measure_filters")).isFalse(); + def = ResourceType.builder("qualifier").setProperty("supportsMeasureFilters", "false").build(); + assertThat(def.getBooleanProperty("supportsMeasureFilters")).isFalse(); } @Test public void getBooleanProperty_is_not_set() { ResourceType def = ResourceType.builder("qualifier").build(); - assertThat(def.getBooleanProperty("supports_measure_filters")).isFalse(); + assertThat(def.getBooleanProperty("supportsMeasureFilters")).isFalse(); } @Test diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypesTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypesTest.java index 1d73ddcc550..673a60a70b3 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypesTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypesTest.java @@ -30,14 +30,14 @@ import static org.fest.assertions.Assertions.assertThat; public class ResourceTypesTest { private ResourceTypeTree viewsTree = ResourceTypeTree.builder() - .addType(ResourceType.builder(Qualifiers.VIEW).setProperty("supports_measure_filters", "true").build()) + .addType(ResourceType.builder(Qualifiers.VIEW).setProperty("supportsMeasureFilters", "true").build()) .addType(ResourceType.builder(Qualifiers.SUBVIEW).build()) .addRelations(Qualifiers.VIEW, Qualifiers.SUBVIEW) .addRelations(Qualifiers.SUBVIEW, Qualifiers.PROJECT) .build(); private ResourceTypeTree defaultTree = ResourceTypeTree.builder() - .addType(ResourceType.builder(Qualifiers.PROJECT).setProperty("supports_measure_filters", "true").build()) + .addType(ResourceType.builder(Qualifiers.PROJECT).setProperty("supportsMeasureFilters", "true").build()) .addType(ResourceType.builder(Qualifiers.DIRECTORY).build()) .addType(ResourceType.builder(Qualifiers.FILE).build()) .addRelations(Qualifiers.PROJECT, Qualifiers.DIRECTORY) @@ -67,14 +67,14 @@ public class ResourceTypesTest { @Test public void getAllWithPropertyKey() { - assertThat(qualifiers(types.getAllWithPropertyKey("supports_measure_filters"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT); + assertThat(qualifiers(types.getAllWithPropertyKey("supportsMeasureFilters"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT); } @Test public void getAllWithPropertyValue() { - assertThat(qualifiers(types.getAllWithPropertyValue("supports_measure_filters", "true"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT); - assertThat(qualifiers(types.getAllWithPropertyValue("supports_measure_filters", true))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT); - assertThat(qualifiers(types.getAllWithPropertyValue("supports_measure_filters", false))).containsOnly(Qualifiers.SUBVIEW, Qualifiers.DIRECTORY, Qualifiers.FILE); + assertThat(qualifiers(types.getAllWithPropertyValue("supportsMeasureFilters", "true"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT); + assertThat(qualifiers(types.getAllWithPropertyValue("supportsMeasureFilters", true))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT); + assertThat(qualifiers(types.getAllWithPropertyValue("supportsMeasureFilters", false))).containsOnly(Qualifiers.SUBVIEW, Qualifiers.DIRECTORY, Qualifiers.FILE); } @Test diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/treemap_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/treemap_controller.rb index ea63d438747..a2db5e892e8 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/treemap_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/treemap_controller.rb @@ -20,51 +20,35 @@ class TreemapController < ApplicationController helper :metrics - SECTION=Navigation::SECTION_HOME - def index - html_id = params[:id] - bad_request('Missing required property: id') if html_id.blank? - - height = params[:height] - bad_request('Missing required property: height') if height.blank? - bad_request('Bad height') if height.to_i<=0 - - size_metric=Metric.by_key(params[:size_metric]||'lines') - bad_request('Unknown metric: ' + params[:size_metric]) unless size_metric - - color_metric=Metric.by_key(params[:color_metric]) - bad_request('Unknown metric: ' + params[:color_metric]) unless color_metric + verify_ajax_request + require_parameters :html_id, :resource - if params[:resource] - resource = Project.by_key(params[:resource]) - bad_request('Unknown resource: ' + params[:resource]) unless resource - bad_request('Data not available') unless resource.last_snapshot - access_denied unless has_role?(:user, resource) - resource = resource.permanent_resource - - elsif params[:filter] - filter=::Filter.find(params[:filter]) - bad_request('Unknown filter: ' + params[:filter]) unless filter - access_denied unless filter.authorized_to_execute?(self) - params[:metric_ids]=[size_metric.id, color_metric.id] - filter_context=Filters.execute(filter, self, params) - else - bad_request('Missing parameter: resource or filter') + if params[:size_metric].present? + size_metric=Metric.by_key(params[:size_metric]) + bad_request('Unknown metric: ' + params[:size_metric]) unless size_metric end - treemap = Sonar::Treemap.new(html_id, size_metric, height.to_i, { - :color_metric => color_metric, - :root_snapshot => (resource ? resource.last_snapshot : nil), - :measures_by_snapshot => (filter_context ? filter_context.measures_by_snapshot : nil), - :period_index => params[:period_index].to_i - }) - - render :update do |page| - page.replace_html "tm-#{html_id}", :partial => 'treemap', :object => treemap - page.replace_html "tm-gradient-#{html_id}", :partial => 'gradient', :locals => {:metric => color_metric} - page.hide "tm-loading-#{html_id}" + if params[:color_metric].present? + color_metric=Metric.by_key(params[:color_metric]) + bad_request('Unknown metric: ' + params[:color_metric]) unless color_metric end + + resource = Project.by_key(params[:resource]) + bad_request('Unknown resource: ' + params[:resource]) unless resource + bad_request('Data not available') unless resource.last_snapshot + access_denied unless has_role?(:user, resource) + resource = resource.permanent_resource + + filter = MeasureFilter.new + filter.set_criteria_value('baseId', resource.id) + filter.set_criteria_value('onBaseComponents', 'true') + filter.set_criteria_value('display', 'treemap') + filter.set_criteria_value('tmSize', size_metric.key) if size_metric + filter.set_criteria_value('tmColor', color_metric.key) if color_metric + filter.execute(self, :user => current_user) + + render :text => filter.display.html end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/measure_filter_display_treemap.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/measure_filter_display_treemap.rb index 961672facaa..d672ed5dc19 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/measure_filter_display_treemap.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/measure_filter_display_treemap.rb @@ -29,7 +29,6 @@ class MeasureFilterDisplayTreemap < MeasureFilterDisplay @size_metric = Metric.by_key(@filter.criteria('tmSize')||'ncloc') @color_metric = Metric.by_key(@filter.criteria('tmColor')) - @html_id = options[:html_id] @filter.metrics=([@size_metric, @color_metric].compact) @id_count = 0 @@ -51,8 +50,7 @@ class MeasureFilterDisplayTreemap < MeasureFilterDisplay o.full_html = false o.details_at_depth = 1 end - html = output.to_html(root) - html + "<script>treemapById(#{@html_id}).onLoaded(#{@filter.results.size});</script>" + output.to_html(root) end end @@ -69,8 +67,7 @@ class MeasureFilterDisplayTreemap < MeasureFilterDisplay if size_measure color_measure=(@color_metric ? result.measure(@color_metric) : nil) resource = result.snapshot.resource - child = Treemap::Node.new(:id => "#{@html_id}-#{@id_count += 1}", - :size => size_value(size_measure), + child = Treemap::Node.new(:size => size_value(size_measure), :label => resource.name(false), :title => escape_javascript(resource.name(true)), :tooltip => tooltip(resource, size_measure, color_measure), @@ -117,12 +114,16 @@ class Sonar::HtmlOutput < Treemap::HtmlOutput html += "left:#{node.bounds.x1}%; top:#{node.bounds.y1}%;" html += "width:#{node.bounds.width}%;height: #{node.bounds.height}%;" html += "background-color:#FFF;\">" - html += "<div rid='#{node.rid}' id=\"tm-node-#{node.id}\" style='margin: 1px;background-color: #{node.color}; height: 100%; -border: 1px solid #{node.color};' alt=\"#{node.tooltip}\" title=\"#{node.tooltip}\"" - if node.leaf - html += "l=1 " + if node.rid + html += "<div rid='#{node.rid}' id=\"tm-node-#{node.id}\" style='margin: 1px;background-color: #{node.color}; height: 100%; + border: 1px solid #{node.color};' alt=\"#{node.tooltip}\" title=\"#{node.tooltip}\"" + if node.leaf + html += "l=1 " + end + html += ' >' + else + html += '<div>' end - html += ' >' html += draw_node_body(node) if (!node.children.nil? && node.children.size > 0) diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/user.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/user.rb index c89ae10fef9..ff6bcd6ebbc 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/user.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/user.rb @@ -27,7 +27,6 @@ class User < ActiveRecord::Base has_many :user_roles, :dependent => :delete_all has_many :properties, :foreign_key => 'user_id', :dependent => :delete_all - has_many :filters, :dependent => :destroy has_many :active_dashboards, :dependent => :destroy, :order => 'order_index' has_many :dashboards, :dependent => :destroy has_many :measure_filters, :class_name => 'MeasureFilter', :dependent => :delete_all, :order => 'name asc' @@ -99,7 +98,6 @@ class User < ActiveRecord::Base self.save(false) self.user_roles.clear self.properties.clear - self.filters.clear self.dashboards.clear self.active_dashboards.clear self.measure_filter_favourites.clear diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/measures/_display_treemap.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/measures/_display_treemap.html.erb index ea8981befaf..561d68e3441 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/measures/_display_treemap.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/measures/_display_treemap.html.erb @@ -1,4 +1,8 @@ -<% if defined? widget %> +<% + treemap_id = 1 + if defined? widget + treemap_id = widget.id +%> <span class="note"><%= message('size') -%>: <b><%= filter.display.size_metric.short_name -%></b></span> <% if filter.display.color_metric %> @@ -17,7 +21,7 @@ <td valign="top" class="thin nowrap"> <span class="comments"><%= message('color') -%></span> <% if filter.display.color_metric %> - <span id="tm-gradient" class="note"> + <span id="tm-gradient-<%= treemap_id -%>" class="note"> <%= render :partial => 'treemap/gradient', :locals => {:metric => filter.display.color_metric} %> </span> <% end %> @@ -29,7 +33,7 @@ <button id="update-treemap">Update</button> </td> - <td></td> + <td valign="bottom"><%= image_tag 'loading.gif', :id => "tm-loading-#{treemap_id}", :style => 'display:none' -%></td> </tr> </table> <% end %> @@ -57,7 +61,17 @@ <% if filter.results.empty? %> <p><%= message('no_data') -%></p> <% else %> - <div class="treemap" style="width: 100%; height: 500px;"> + <div id="tm-<%= treemap_id -%>" class="treemap width100"> <%= filter.display.html -%> </div> + + <div style="margin: 5px 0 0 0" class="notes"> + <div style="float: right;cursor: help"><%= image_tag 'help.png', :title => h(message('treemap.click_help')) -%></div> + <div id="tm-bc-<%= treemap_id -%>">/</div> + </div> + + <script> + new Treemap(<%= treemap_id -%>, '<%= filter.display.size_metric.key -%>', '<%= filter.display.color_metric ? filter.display.color_metric.key : '' -%>'); + </script> + <% end %>
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/javascripts/application.js b/sonar-server/src/main/webapp/javascripts/application.js index eb635f67831..65d32fb7d03 100644 --- a/sonar-server/src/main/webapp/javascripts/application.js +++ b/sonar-server/src/main/webapp/javascripts/application.js @@ -15,33 +15,33 @@ function info(message) { function autocompleteResources() { $('searchInput').value = ''; new Ajax.Autocompleter('searchInput', 'searchResourcesResults', baseUrl + '/search', { - method:'post', - minChars:3, - indicator:'searchingResources', - paramName:'s', - updateElement:function (item) { + method: 'post', + minChars: 3, + indicator: 'searchingResources', + paramName: 's', + updateElement: function (item) { if (item.id) { window.location = baseUrl + '/dashboard/index/' + item.id; } }, - onShow:function (element, update) { /* no update */ + onShow: function (element, update) { /* no update */ update.show(); } }); } var SelectBox = { - cache:new Object(), - init:function (id) { + cache: new Object(), + init: function (id) { var box = document.getElementById(id); var node; SelectBox.cache[id] = new Array(); var cache = SelectBox.cache[id]; for (var i = 0; (node = box.options[i]); i++) { - cache.push({value:node.value, text:node.text, displayed:1}); + cache.push({value: node.value, text: node.text, displayed: 1}); } }, - redisplay:function (id) { + redisplay: function (id) { // Repopulate HTML select box from cache var box = document.getElementById(id); box.options.length = 0; // clear all options @@ -52,7 +52,7 @@ var SelectBox = { } } }, - filter:function (id, text) { + filter: function (id, text) { // Redisplay the HTML select box, displaying only the choices containing ALL // the words in text. (It's an AND search.) var tokens = text.toLowerCase().split(/\s+/); @@ -67,7 +67,7 @@ var SelectBox = { } SelectBox.redisplay(id); }, - delete_from_cache:function (id, value) { + delete_from_cache: function (id, value) { var node, delete_index = null; for (var i = 0; (node = SelectBox.cache[id][i]); i++) { if (node.value == value) { @@ -81,10 +81,10 @@ var SelectBox = { } SelectBox.cache[id].length--; }, - add_to_cache:function (id, option) { - SelectBox.cache[id].push({value:option.value, text:option.text, displayed:1}); + add_to_cache: function (id, option) { + SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); }, - cache_contains:function (id, value) { + cache_contains: function (id, value) { // Check if an item is contained in the cache var node; for (var i = 0; (node = SelectBox.cache[id][i]); i++) { @@ -94,31 +94,31 @@ var SelectBox = { } return false; }, - move:function (from, to) { + move: function (from, to) { var from_box = document.getElementById(from); var option; for (var i = 0; (option = from_box.options[i]); i++) { if (option.selected && SelectBox.cache_contains(from, option.value)) { - SelectBox.add_to_cache(to, {value:option.value, text:option.text, displayed:1}); + SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); SelectBox.delete_from_cache(from, option.value); } } SelectBox.redisplay(from); SelectBox.redisplay(to); }, - move_all:function (from, to) { + move_all: function (from, to) { var from_box = document.getElementById(from); var option; for (var i = 0; (option = from_box.options[i]); i++) { if (SelectBox.cache_contains(from, option.value)) { - SelectBox.add_to_cache(to, {value:option.value, text:option.text, displayed:1}); + SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); SelectBox.delete_from_cache(from, option.value); } } SelectBox.redisplay(from); SelectBox.redisplay(to); }, - sort:function (id) { + sort: function (id) { SelectBox.cache[id].sort(function (a, b) { a = a.text.toLowerCase(); b = b.text.toLowerCase(); @@ -132,7 +132,7 @@ var SelectBox = { return 0; }); }, - select_all:function (id) { + select_all: function (id) { var box = document.getElementById(id); for (var i = 0; i < box.options.length; i++) { box.options[i].selected = 'selected'; @@ -146,9 +146,8 @@ var treemaps = {}; function treemapById(id) { return treemaps[id]; } -var TreemapContext = function (type, id, label) { - this.type = type; - this.id = id; +var TreemapContext = function (rid, label) { + this.rid = rid; this.label = label; }; @@ -158,25 +157,15 @@ var TreemapContext = function (type, id, label) { * tm-bc-#{id} : required breadcrumb * tm-loading-#{id} : optional loading icon */ -var Treemap = function (id, sizeMetric, colorMetric, heightInPercents) { +var Treemap = function (id, sizeMetric, colorMetric) { this.id = id; this.sizeMetric = sizeMetric; this.colorMetric = colorMetric; - this.heightInPercents = heightInPercents; this.breadcrumb = []; treemaps[id] = this; -}; -Treemap.prototype.initResource = function (resourceId) { - this.breadcrumb.push(new TreemapContext('resource', resourceId, '')); - return this; -}; -Treemap.prototype.initFilter = function (filterId) { - this.breadcrumb.push(new TreemapContext('filter', filterId, '')); - return this; -}; -Treemap.prototype.init = function (type, id) { - this.breadcrumb.push(new TreemapContext(type, id, '')); - return this; + this.rootNode().height(this.rootNode().width() * 0.6); + this.initNodes(); + }; Treemap.prototype.changeSizeMetric = function (metric) { this.sizeMetric = metric; @@ -194,74 +183,69 @@ Treemap.prototype.currentContext = function () { } return null; }; -Treemap.prototype.width = function () { - return $('tm-' + this.id).getWidth(); -}; Treemap.prototype.load = function () { var context = this.currentContext(); - var width = this.width(); - var height = Math.round(width * Math.abs(this.heightInPercents / 100.0)); - var output = ''; this.breadcrumb.each(function (ctx) { output += ctx.label + ' / '; }); - if ($('tm-bc-' + this.id) != null) { - $('tm-bc-' + this.id).innerHTML = output; - } - var loadingIcon = $('tm-loading-' + this.id); - if (loadingIcon != null) { - loadingIcon.show(); - } - - new Ajax.Request( - baseUrl + '/treemap/index?id=' + this.id + '&height=' + height + '&size_metric=' + this.sizeMetric + '&color_metric=' + this.colorMetric + '&' + context.type + '=' + context.id, - { - asynchronous:true, - evalScripts:true - }); + $j('#tm-bc-' + this.id).html(output); + $j('#tm-loading-' + this.id).show(); + var self = this; + $j.ajax({ + type: "GET", + url: baseUrl + '/treemap/index?html_id=' + this.id + '&size_metric=' + this.sizeMetric + '&color_metric=' + this.colorMetric + '&resource=' + context.rid, + dataType: "html", + success: function (data) { + self.rootNode().html(data); + self.initNodes(); + $j("#tm-loading-" + self.id).hide(); + } + }); }; -Treemap.prototype.htmlNode = function (nodeId) { - return $('tm-node-' + this.id + '-' + nodeId); +Treemap.prototype.rootNode = function () { + return $j('#tm-' + this.id); }; -Treemap.prototype.handleClick = function (event) { - if (Event.isLeftClick(event)) { - var link = event.findElement('a'); - if (link != null) { - event.stopPropagation(); - return false; - } - var elt = event.findElement('div'); - var rid = elt.readAttribute('rid'); - var leaf = elt.hasAttribute('l'); - if (!leaf) { - var label = elt.innerText || elt.textContent; - var context = new TreemapContext('resource', rid, label); - this.breadcrumb.push(context); - this.load(); - } - - } else if (Event.isRightClick(event)) { - if (this.breadcrumb.length > 1) { - this.breadcrumb.pop(); - this.load(); - } - } -}; -Treemap.prototype.onLoaded = function (componentsSize) { - for (var i = 1; i <= componentsSize; i++) { - var elt = this.htmlNode(i); - elt.oncontextmenu = function () { - return false - }; - elt.observe('mouseup', this.handleClick.bind(this)); - } +Treemap.prototype.initNodes = function () { + var self = this; + $j('#tm-' + this.id).find('a').each(function (index) { + this.on("mouseup", function (event) { + event.stopPropagation() + }); + }); + $j('#tm-' + this.id).find('[rid]').each(function (index) { + this.on("mouseup", function (event) { + if (event.which == 1) { + var source = $j(this); + var rid = source.attr('rid'); + var has_leaves = !!(source.attr('l')); + if (!has_leaves) { + var context = new TreemapContext(rid, source.text()); + self.breadcrumb.push(context); + self.load(); + } + } + } + ); + this.on("contextmenu", function (event) { + event.preventDefault(); + // right click + if (self.breadcrumb.length > 1) { + self.breadcrumb.pop(); + self.load(); + } else { + location.reload(); + } + return false; + }); + } + ); }; (function ($j) { $j.fn.extend({ - modal:function () { + modal: function () { return this.each(function () { var obj = $j(this); var $link = obj.bind('click', function () { @@ -275,13 +259,13 @@ Treemap.prototype.onLoaded = function (componentsSize) { $dialog.html(html); $dialog .dialog({ - width:($link.attr('modal-width') || 540), - draggable:false, - autoOpen:false, - modal:true, - minHeight:50, - resizable:false, - close:function () { + width: ($link.attr('modal-width') || 540), + draggable: false, + autoOpen: false, + modal: true, + minHeight: 50, + resizable: false, + close: function () { $j('#modal').remove(); } }); @@ -301,19 +285,19 @@ Treemap.prototype.onLoaded = function (componentsSize) { }); }); }, - modalForm:function (ajax_options) { + modalForm: function (ajax_options) { return this.each(function () { var obj = $j(this); obj.submit(function (event) { $j('input[type=submit]', this).attr('disabled', 'disabled'); $j.ajax($j.extend({ - type:'POST', - url:obj.attr('action'), - data:obj.serialize(), - success:function (data) { + type: 'POST', + url: obj.attr('action'), + data: obj.serialize(), + success: function (data) { window.location.reload(); }, - error:function (xhr, textStatus, errorThrown) { + error: function (xhr, textStatus, errorThrown) { $j("#modal").html(xhr.responseText); } }, ajax_options)); diff --git a/sonar-server/src/main/webapp/stylesheets/style.css b/sonar-server/src/main/webapp/stylesheets/style.css index 4c8a61c9b4b..903bec852fc 100644 --- a/sonar-server/src/main/webapp/stylesheets/style.css +++ b/sonar-server/src/main/webapp/stylesheets/style.css @@ -271,10 +271,13 @@ h4, .h4 { .treemap a { color: #FFF; - text-decoration: underline; + text-decoration: none; font-size: 12px; padding: 1px; } +.treemap a:hover { + text-decoration: underline; +} /* ------------------- MESSAGES ------------------- */ .warning { |