From a1925bc297a5a0b9d7098cbe8904958baa994177 Mon Sep 17 00:00:00 2001 From: Pablo Alonso Garcia Date: Fri, 4 Sep 2015 12:37:08 +0200 Subject: [PATCH 01/15] Updated cartodb.js to latest develop --- lib/assets/javascripts/cdb | 2 +- package.json | 2 +- .../cartodb.mod.odyssey.uncompressed.js | 4 +- .../cartodb.mod.torque.uncompressed.js | 2 - .../javascripts/cartodb.uncompressed.js | 48 ++++++++----------- 5 files changed, 24 insertions(+), 34 deletions(-) diff --git a/lib/assets/javascripts/cdb b/lib/assets/javascripts/cdb index 1fc0998faa05..68561777c09f 160000 --- a/lib/assets/javascripts/cdb +++ b/lib/assets/javascripts/cdb @@ -1 +1 @@ -Subproject commit 1fc0998faa05243e0fe60bf39a13f23bc669c96f +Subproject commit 68561777c09ffc7e81faa85e70c9401eff175bef diff --git a/package.json b/package.json index 7c46303d5dce..655b38cc28e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cartodb-ui", - "version": "3.19.13", + "version": "3.19.14", "description": "CartoDB UI frontend", "repository": { "type": "git", diff --git a/vendor/assets/javascripts/cartodb.mod.odyssey.uncompressed.js b/vendor/assets/javascripts/cartodb.mod.odyssey.uncompressed.js index 53c3e12a7d54..2590e6c53a3c 100644 --- a/vendor/assets/javascripts/cartodb.mod.odyssey.uncompressed.js +++ b/vendor/assets/javascripts/cartodb.mod.odyssey.uncompressed.js @@ -1,5 +1,5 @@ -// version: 3.15.1 -// sha: c942686a747b755e7448d6438d63ea42e9f1d051 +// version: 3.15.2 +// sha: 5640fee5e39faed217b50f278eacff038c2d82cb !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.O=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o Date: Fri, 4 Sep 2015 14:44:09 +0200 Subject: [PATCH 02/15] Updated cartodb.js to latest develop --- lib/assets/javascripts/cdb | 2 +- vendor/assets/javascripts/cartodb.uncompressed.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/assets/javascripts/cdb b/lib/assets/javascripts/cdb index 68561777c09f..8894d2ba8067 160000 --- a/lib/assets/javascripts/cdb +++ b/lib/assets/javascripts/cdb @@ -1 +1 @@ -Subproject commit 68561777c09ffc7e81faa85e70c9401eff175bef +Subproject commit 8894d2ba80671ed8f399501067c29bf0e1dc40f5 diff --git a/vendor/assets/javascripts/cartodb.uncompressed.js b/vendor/assets/javascripts/cartodb.uncompressed.js index 78116075882e..3b22aabe897d 100644 --- a/vendor/assets/javascripts/cartodb.uncompressed.js +++ b/vendor/assets/javascripts/cartodb.uncompressed.js @@ -1,6 +1,6 @@ // cartodb.js version: 3.15.2 // uncompressed version: cartodb.uncompressed.js -// sha: 68561777c09ffc7e81faa85e70c9401eff175bef +// sha: 8894d2ba80671ed8f399501067c29bf0e1dc40f5 (function() { var define; // Undefine define (require.js), see https://github.com/CartoDB/cartodb.js/issues/543 var root = this; @@ -27116,7 +27116,7 @@ cdb.geo.TorqueLayer = cdb.geo.MapLayer.extend({ cdb.geo.CartoDBLayer = cdb.geo.MapLayer.extend({ defaults: { - attribution: 'CartoDB', + attribution: cdb.config.get('cartodb_attributions'), type: 'CartoDB', active: true, query: null, @@ -34699,7 +34699,7 @@ L.CartoDBGroupLayerBase = L.TileLayer.extend({ options: { opacity: 0.99, - attribution: "CartoDB", + attribution: cdb.config.get('cartodb_attributions'), debug: false, visible: true, added: false, @@ -35133,7 +35133,7 @@ L.CartoDBLayer = L.CartoDBGroupLayer.extend({ options: { query: "SELECT * FROM {{table_name}}", opacity: 0.99, - attribution: "CartoDB", + attribution: cdb.config.get('cartodb_attributions'), debug: false, visible: true, added: false, @@ -36089,7 +36089,7 @@ Projector.prototype.pixelToLatLng = function(point) { var default_options = { opacity: 0.99, - attribution: "CartoDB", + attribution: cdb.config.get('cartodb_attributions'), debug: false, visible: true, added: false, @@ -36537,7 +36537,7 @@ var CartoDBLayer = function(options) { var default_options = { query: "SELECT * FROM {{table_name}}", opacity: 0.99, - attribution: "CartoDB", + attribution: cdb.config.get('cartodb_attributions'), opacity: 1, debug: false, visible: true, From 27e23f7666506687e6aa1d4fbd53bc2021132daa Mon Sep 17 00:00:00 2001 From: Pablo Alonso Garcia Date: Mon, 7 Sep 2015 10:29:51 +0200 Subject: [PATCH 03/15] Fixed specs --- .../test/spec/cartodb/models/map.spec.js | 36 +++++-------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/lib/assets/test/spec/cartodb/models/map.spec.js b/lib/assets/test/spec/cartodb/models/map.spec.js index 578e1b852f8f..672c6181bfa2 100644 --- a/lib/assets/test/spec/cartodb/models/map.spec.js +++ b/lib/assets/test/spec/cartodb/models/map.spec.js @@ -46,6 +46,7 @@ describe("cartodb.models.Map", function() { describe('.setBaseLayer', function() { var savingLayersFinish; + var cartoDBAttribution = 'CartoDB attribution'; it('should set the base layer as the first layer', function(done) { savingLayersFinishCallback = jasmine.createSpy('savingLayersFinishCallback'); @@ -73,7 +74,7 @@ describe("cartodb.models.Map", function() { expect(savingLayersFinishCallback.calls.count()).toEqual(1); done(); }, 0); - expect(map.get('attribution')).toEqual([ 'CartoDB1.0' ]); + expect(map.get('attribution')).toEqual([ cartoDBAttribution, 'CartoDB1.0' ]); }) it('should update the existing base layer if the new layer has the same type', function(done) { @@ -109,13 +110,14 @@ describe("cartodb.models.Map", function() { expect(savingLayersFinishCallback.calls.count()).toEqual(1); done(); }, 0); - expect(map.get('attribution')).toEqual([ 'CartoDB2.0' ]); + expect(map.get('attribution')).toEqual([ cartoDBAttribution, 'CartoDB2.0' ]); expect(map.layers.length).toEqual(1); }) it('should replace the base layer if the current base layer has a different type', function(done) { var baseLayer = new cdb.admin.CartoDBLayer({ id: 'XXX-YYY', + attribution: 'CartoDB1.0', tile_style: 'test1', query: 'sql1', interactivity: 'int1', @@ -134,6 +136,8 @@ describe("cartodb.models.Map", function() { map.setBaseLayer(baseLayer); + expect(map.get('attribution')).toEqual([ cartoDBAttribution, 'CartoDB1.0' ]); + savingLayersFinishCallback = jasmine.createSpy('savingLayersFinishCallback'); map.bind('savingLayersFinish', savingLayersFinishCallback); @@ -147,35 +151,11 @@ describe("cartodb.models.Map", function() { expect(savingLayersFinishCallback.calls.count()).toEqual(1); done(); }, 0); - expect(map.get('attribution')).toEqual([ 'CartoDB2.0' ]); + expect(map.get('attribution')).toEqual([ cartoDBAttribution, 'CartoDB2.0' ]); + expect(map.layers.length).toEqual(1); }) - it("should set a new attribution after change base layer", function() { - var old = new cdb.geo.CartoDBLayer({ - attribution: 'CartoDB1.0', - type: 'Tiled', - urlTemplate: 'x', - base_type: 'x', - name: 'old' - }); - map.setBaseLayer(old); - var old_attribution = map.get('attribution'); - - var base = new cdb.geo.CartoDBLayer({ - attribution: 'CartoDB2.0', - type: 'Tiled', - urlTemplate: 'y', - base_type: 'y', - name: 'new' - }); - sinon.stub(base, "save").yieldsTo("success"); - var r = map.setBaseLayer(base); - var new_attribution = map.get('attribution'); - - expect(old_attribution[0]).not.toEqual(new_attribution[0]); - }); - it("shouldn't set base layer if the old base layer is the same", function() { var old = new cdb.geo.TileLayer({ type: 'Tiled', From 6828972bf295da8cbf0a2ce1f5ec54ccddbefe73 Mon Sep 17 00:00:00 2001 From: Kartones Date: Mon, 7 Sep 2015 17:00:29 +0200 Subject: [PATCH 04/15] #5375 ongoing related vizjson invalidations when a dataset's attribution changes --- .../api/json/visualizations_controller.rb | 1 - .../carto/api/vizjson_presenter.rb | 1 - app/models/visualization/member.rb | 18 +++++-- .../api/visualizations_controller_spec.rb | 48 +++++++++++++++++++ 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/json/visualizations_controller.rb b/app/controllers/api/json/visualizations_controller.rb index 26c59545795d..a95513b3937d 100644 --- a/app/controllers/api/json/visualizations_controller.rb +++ b/app/controllers/api/json/visualizations_controller.rb @@ -89,7 +89,6 @@ def update # Don't allow to modify next_id/prev_id, force to use set_next_id() vis_data.delete(:prev_id) || vis_data.delete('prev_id') vis_data.delete(:next_id) || vis_data.delete('next_id') - # when a table gets renamed, first it's canonical visualization is renamed, so we must revert renaming if that failed # This is far from perfect, but works without messing with table-vis sync and their two backends if vis.table? diff --git a/app/controllers/carto/api/vizjson_presenter.rb b/app/controllers/carto/api/vizjson_presenter.rb index 74376088d457..bef26f92c58b 100644 --- a/app/controllers/carto/api/vizjson_presenter.rb +++ b/app/controllers/carto/api/vizjson_presenter.rb @@ -20,7 +20,6 @@ def to_vizjson(options={}) private - def calculate_vizjson(options={}) vizjson_options = { full: false, diff --git a/app/models/visualization/member.rb b/app/models/visualization/member.rb index e2eff232d061..cba748de7ae0 100644 --- a/app/models/visualization/member.rb +++ b/app/models/visualization/member.rb @@ -319,10 +319,15 @@ def description_html_safe if description.present? renderer = Redcarpet::Render::Safe markdown = Redcarpet::Markdown.new(renderer, extensions = {}) - markdown.render description + markdown.render description end end + def attributions=(value) + self.dirty = true if value != @attributions + super(value) + end + def permission_id=(permission_id) self.permission_change_valid = false self.permission_change_valid = true if (@permission_id.nil? || @permission_id == permission_id) @@ -439,6 +444,7 @@ def non_dependent? def invalidate_cache invalidate_redis_cache invalidate_varnish_cache + parent.invalidate_cache unless parent_id.nil? end @@ -475,7 +481,7 @@ def password=(value) end def has_password? - ( !@password_salt.nil? && !@encrypted_password.nil? ) + ( !@password_salt.nil? && !@encrypted_password.nil? ) end def is_password_valid?(password) @@ -494,7 +500,7 @@ def make_auth_token 10.times do digest = secure_digest(digest, TOKEN_DIGEST) end - digest + digest end def get_auth_tokens @@ -714,6 +720,12 @@ def do_store(propagate_changes=true, table_privacy_changed=false) invalidate_cache end + if dirty + related_visualizations.each do |vis| + vis.invalidate_cache + end + end + set_timestamps repository.store(id, attributes.to_hash) diff --git a/spec/requests/carto/api/visualizations_controller_spec.rb b/spec/requests/carto/api/visualizations_controller_spec.rb index 5b30fdfde710..b238e4530b42 100644 --- a/spec/requests/carto/api/visualizations_controller_spec.rb +++ b/spec/requests/carto/api/visualizations_controller_spec.rb @@ -1386,6 +1386,54 @@ named_map_attributions.should include('attribution1') named_map_attributions.should include('attribution2') end + + it "Updates viz.json's layergroup when attributions in a related layer change" do + table_1_attribution = 'attribution 1' + modified_table_2_attribution = 'modified attribution 2' + + table1 = table_factory + table2 = table_factory + + payload = { + name: 'new visualization', + tables: [ + table1.fetch('name'), + table2.fetch('name') + ], + privacy: 'public' + } + + post api_v1_visualizations_create_url(api_key: @api_key), payload.to_json, @headers + last_response.status.should == 200 + visualization = JSON.parse(last_response.body) + + table1_visualization = Carto::Visualization.find(table1["table_visualization"]["id"]) + table1_visualization.update_attribute(:attributions, table_1_attribution) + table2_visualization = Carto::Visualization.find(table2["table_visualization"]["id"]) + table2_visualization.update_attribute(:attributions, 'attribution 2') + + # Call to cache the vizjson after generating it + get api_v2_visualizations_vizjson_url(id: visualization.fetch('id'), api_key: @api_key),{}, @headers + + # Now force a change + put api_v1_visualizations_update_url(api_key: @api_key, id: table2_visualization.id), + { attributions: modified_table_2_attribution }.to_json, @headers + last_response.status.should == 200 + + #table2_visualization.update_attribute(:attributions, modified_table_2_attribution) + + get api_v2_visualizations_vizjson_url(id: visualization.fetch('id'), api_key: @api_key),{}, @headers + visualization = JSON.parse(last_response.body) + + layer_group_layer = visualization["layers"][1] + layer_group_layer["type"].should == 'layergroup' + layer_group_attributions = layer_group_layer["options"]["attribution"].split(',').map(&:strip) + layer_group_layer.size.should == 2 + + layer_group_attributions.should include(table_1_attribution) + layer_group_attributions.should include(modified_table_2_attribution) + end + end describe 'tests visualization listing filters' do From 3e08bfdc083e36e29971eaab4ed19918ce7f18ec Mon Sep 17 00:00:00 2001 From: Kartones Date: Tue, 8 Sep 2015 11:37:21 +0200 Subject: [PATCH 05/15] #5375 propagation seems to be working, pending some manual tests (automated pass) --- .../admin/visualizations_controller.rb | 6 ++-- .../admin/visualization_public_map_adapter.rb | 6 ++-- .../api/visualization_vizjson_adapter.rb | 5 ++-- app/helpers/redis_vizjson_cache.rb | 1 - app/models/carto/visualization.rb | 12 +++++--- app/models/visualization/member.rb | 29 +++++++++++-------- app/models/visualization/relator.rb | 19 +++++++----- .../admin/visualizations/public_map.html.erb | 4 +-- spec/models/visualization/relator_spec.rb | 4 +-- .../api/visualizations_controller_spec.rb | 2 -- 10 files changed, 50 insertions(+), 38 deletions(-) diff --git a/app/controllers/admin/visualizations_controller.rb b/app/controllers/admin/visualizations_controller.rb index 6a28c9c0ec26..5143a842b9f4 100644 --- a/app/controllers/admin/visualizations_controller.rb +++ b/app/controllers/admin/visualizations_controller.rb @@ -226,7 +226,7 @@ def public_map @disqus_shortname = @visualization.user.disqus_shortname.presence || 'cartodb' @visualization_count = @visualization.user.public_visualization_count @related_tables = @visualization.related_tables - @related_visualizations = @visualization.related_visualizations + @related_canonical_visualizations = @visualization.related_canonical_visualizations @related_tables_owners = Hash.new @related_tables.each { |table| unless @related_tables_owners.include?(table.user_id) @@ -273,7 +273,7 @@ def show_organization_public_map @disqus_shortname = @visualization.user.disqus_shortname.presence || 'cartodb' @visualization_count = @visualization.user.public_visualization_count @related_tables = @visualization.related_tables - @related_visualizations = @visualization.related_visualizations + @related_canonical_visualizations = @visualization.related_canonical_visualizations @public_tables_count = @visualization.user.public_table_count @nonpublic_tables_count = @related_tables.select{|p| !p.public? }.count @@ -323,7 +323,7 @@ def show_protected_public_map @disqus_shortname = @visualization.user.disqus_shortname.presence || 'cartodb' @visualization_count = @visualization.user.public_visualization_count @related_tables = @visualization.related_tables - @related_visualizations = @visualization.related_visualizations + @related_canonical_visualizations = @visualization.related_canonical_visualizations @public_tables_count = @visualization.user.public_table_count @nonpublic_tables_count = @related_tables.select{|p| !p.public? }.count diff --git a/app/controllers/carto/admin/visualization_public_map_adapter.rb b/app/controllers/carto/admin/visualization_public_map_adapter.rb index 045ad6a89eae..43ad83d0954d 100644 --- a/app/controllers/carto/admin/visualization_public_map_adapter.rb +++ b/app/controllers/carto/admin/visualization_public_map_adapter.rb @@ -74,14 +74,14 @@ def public_with_link? @visualization.is_link_privacy? end - def related_visualizations - @visualization.related_visualizations.map { |rv| + def related_canonical_visualizations + @visualization.related_canonical_visualizations.map { |rv| Carto::Admin::VisualizationPublicMapAdapter.new(rv, @current_viewer) if rv.is_public? }.compact end def related_visualizations_geometry_types - related_visualizations.collect(&:geometry_types).flatten.uniq + related_canonical_visualizations.collect(&:geometry_types).flatten.uniq end def related_tables_geometry_types diff --git a/app/controllers/carto/api/visualization_vizjson_adapter.rb b/app/controllers/carto/api/visualization_vizjson_adapter.rb index 42199dc995ec..d0bc2386ec38 100644 --- a/app/controllers/carto/api/visualization_vizjson_adapter.rb +++ b/app/controllers/carto/api/visualization_vizjson_adapter.rb @@ -8,7 +8,8 @@ class VisualizationVizJSONAdapter include Carto::HtmlSafe delegate [:id, :map, :qualified_name, :likes, :description, :retrieve_named_map?, :password_protected?, :overlays, - :prev_id, :next_id, :transition_options, :has_password?, :parent_id, :get_auth_tokens, :user, :related_visualizations + :prev_id, :next_id, :transition_options, :has_password?, :parent_id, :get_auth_tokens, :user, + :related_canonical_visualizations ] => :visualization attr_reader :visualization @@ -29,7 +30,7 @@ def layers(kind) end def attributions_from_derived_visualizations - @visualization.related_visualizations.map(&:attributions).reject {|attribution| attribution.blank?} + @visualization.related_canonical_visualizations.map(&:attributions).reject {|attribution| attribution.blank?} end def children diff --git a/app/helpers/redis_vizjson_cache.rb b/app/helpers/redis_vizjson_cache.rb index b586d7a74ae4..ade533d62988 100644 --- a/app/helpers/redis_vizjson_cache.rb +++ b/app/helpers/redis_vizjson_cache.rb @@ -11,7 +11,6 @@ def initialize(redis_cache=$tables_metadata) @redis = redis_cache end - def cached(visualization_id, https_flag=false) key = key(visualization_id, https_flag) value = redis.get(key) diff --git a/app/models/carto/visualization.rb b/app/models/carto/visualization.rb index b610a40d93ee..c23708a7bcc6 100644 --- a/app/models/carto/visualization.rb +++ b/app/models/carto/visualization.rb @@ -77,8 +77,8 @@ def related_tables @related_tables ||= get_related_tables end - def related_visualizations - @related_visualizations ||= get_related_visualizations + def related_canonical_visualizations + @related_canonical_visualizations ||= get_related_canonical_visualizations end def stats @@ -313,8 +313,12 @@ def get_related_tables map.carto_and_torque_layers.flat_map { |layer| layer.affected_tables}.uniq end - def get_related_visualizations - Carto::Visualization.where(map_id: related_tables.collect(&:map_id), type: TYPE_CANONICAL).all + def get_related_canonical_visualizations + get_related_visualizations_by_types([TYPE_CANONICAL]) + end + + def get_related_visualizations_by_types(types) + Carto::Visualization.where(map_id: related_tables.collect(&:map_id), type: types).all end def has_write_permission?(user) diff --git a/app/models/visualization/member.rb b/app/models/visualization/member.rb index cba748de7ae0..e7d3cebb4a99 100644 --- a/app/models/visualization/member.rb +++ b/app/models/visualization/member.rb @@ -648,7 +648,7 @@ def license_info end def attributions_from_derived_visualizations - related_visualizations.map(&:attributions).reject {|attribution| attribution.blank?} + related_canonical_visualizations.map(&:attributions).reject {|attribution| attribution.blank?} end private @@ -714,17 +714,7 @@ def do_store(propagate_changes=true, table_privacy_changed=false) raise CartoDB::InvalidMember end - # previously we used 'invalidate_cache' but due to public_map displaying all the user public visualizations, - # now we need to purgue everything to avoid cached stale data or public->priv still showing scenarios - if name_changed || privacy_changed || table_privacy_changed || dirty - invalidate_cache - end - - if dirty - related_visualizations.each do |vis| - vis.invalidate_cache - end - end + perform_invalidations(table_privacy_changed) set_timestamps @@ -750,6 +740,21 @@ def do_store(propagate_changes=true, table_privacy_changed=false) end end + def perform_invalidations(table_privacy_changed) + # previously we used 'invalidate_cache' but due to public_map displaying all the user public visualizations, + # now we need to purgue everything to avoid cached stale data or public->priv still showing scenarios + if name_changed || privacy_changed || table_privacy_changed || dirty + invalidate_cache + end + + # When a table's relevant data is changed, propagate to all who use it or relate to it + if dirty && table + table.affected_visualizations.each do |affected_vis| + affected_vis.invalidate_cache + end + end + end + def named_maps(force_init = false) if @named_maps.nil? || force_init if user.nil? diff --git a/app/models/visualization/relator.rb b/app/models/visualization/relator.rb index af322d557682..30f681600c19 100644 --- a/app/models/visualization/relator.rb +++ b/app/models/visualization/relator.rb @@ -17,9 +17,9 @@ class Relator named_map: :named_maps_layers } - INTERFACE = %w{ overlays map user table related_templates related_tables related_visualizations layers - stats mapviews total_mapviews single_data_layer? synchronization is_synced? permission parent - children support_tables prev_list_item next_list_item likes likes_count reload_likes + INTERFACE = %w{ overlays map user table related_templates related_tables related_canonical_visualizations + layers stats mapviews total_mapviews single_data_layer? synchronization is_synced? permission + parent children support_tables prev_list_item next_list_item likes likes_count reload_likes estimated_row_count actual_row_count } def initialize(attributes={}) @@ -105,8 +105,8 @@ def related_tables .flat_map{|layer| layer.affected_tables.map{|t| t.service}}.uniq end - def related_visualizations - @related_visualizations ||= get_related_visualizations + def related_canonical_visualizations + @related_canonical_visualizations ||= get_related_canonical_visualizations end def layers(kind) @@ -165,10 +165,15 @@ def likes_search Like.where(subject: @id) end - def get_related_visualizations + def get_related_canonical_visualizations + get_related_visualizations_by_types([CartoDB::Visualization::Member::TYPE_CANONICAL]) + end + + def get_related_visualizations_by_types(types) related_map_ids = related_tables.map(&:map_id) - CartoDB::Visualization::Collection.new.fetch(map_id: related_map_ids, type: CartoDB::Visualization::Member::TYPE_CANONICAL) + CartoDB::Visualization::Collection.new.fetch(map_id: related_map_ids, type: types) end + end end end diff --git a/app/views/admin/visualizations/public_map.html.erb b/app/views/admin/visualizations/public_map.html.erb index 156495a8e8d6..30533e637b49 100644 --- a/app/views/admin/visualizations/public_map.html.erb +++ b/app/views/admin/visualizations/public_map.html.erb @@ -171,8 +171,8 @@
    - <% if @related_visualizations.present? %> - <% @related_visualizations.each do |vis| %> + <% if @related_canonical_visualizations.present? %> + <% @related_canonical_visualizations.each do |vis| %> <% if vis.privacy == "public" %>
  • diff --git a/spec/models/visualization/relator_spec.rb b/spec/models/visualization/relator_spec.rb index 28ecb19c9abf..23f13e82854e 100644 --- a/spec/models/visualization/relator_spec.rb +++ b/spec/models/visualization/relator_spec.rb @@ -62,7 +62,7 @@ Visualization::Relator.any_instance.stubs(:support_tables).returns(support_tables_mock) end - describe '#related_visualizations' do + describe '#related_canonical_visualizations' do it 'should return the canonical visualizations associated to a derived visualization' do table1 = create_table({:name => 'table1', :user_id => @user.id}) @@ -70,7 +70,7 @@ vis_table1 = create_vis_from_table(@user, table1) vis_table2 = create_vis_from_table(@user, table2) - vis_table1.related_visualizations.map(&:id).should == [table1.table_visualization.id] + vis_table1.related_canonical_visualizations.map(&:id).should == [table1.table_visualization.id] end end diff --git a/spec/requests/carto/api/visualizations_controller_spec.rb b/spec/requests/carto/api/visualizations_controller_spec.rb index b238e4530b42..afc1faa94133 100644 --- a/spec/requests/carto/api/visualizations_controller_spec.rb +++ b/spec/requests/carto/api/visualizations_controller_spec.rb @@ -1420,8 +1420,6 @@ { attributions: modified_table_2_attribution }.to_json, @headers last_response.status.should == 200 - #table2_visualization.update_attribute(:attributions, modified_table_2_attribution) - get api_v2_visualizations_vizjson_url(id: visualization.fetch('id'), api_key: @api_key),{}, @headers visualization = JSON.parse(last_response.body) From 6aef755b2ac199a469738502e8f2c353db1b65ef Mon Sep 17 00:00:00 2001 From: Kartones Date: Tue, 8 Sep 2015 15:56:45 +0200 Subject: [PATCH 06/15] #5394 table attributions update now properly updates related layers --- app/models/visualization/member.rb | 20 ++++- .../carto/api/layers_controller_spec.rb | 78 +++++++++++++++++++ 2 files changed, 96 insertions(+), 2 deletions(-) diff --git a/app/models/visualization/member.rb b/app/models/visualization/member.rb index e7d3cebb4a99..cd53ac91d858 100644 --- a/app/models/visualization/member.rb +++ b/app/models/visualization/member.rb @@ -325,6 +325,7 @@ def description_html_safe def attributions=(value) self.dirty = true if value != @attributions + self.attributions_changed = true if value != @attributions super(value) end @@ -654,7 +655,7 @@ def attributions_from_derived_visualizations private attr_reader :repository, :name_checker, :validator - attr_accessor :privacy_changed, :name_changed, :old_name, :permission_change_valid, :dirty + attr_accessor :privacy_changed, :name_changed, :old_name, :permission_change_valid, :dirty, :attributions_changed def embed_redis_cache @embed_redis_cache ||= EmbedRedisCache.new($tables_metadata) @@ -733,10 +734,11 @@ def do_store(propagate_changes=true, table_privacy_changed=false) save_named_map + propagate_attribution_change if table if type == TYPE_REMOTE || type == TYPE_CANONICAL propagate_privacy_and_name_to(table) if table and propagate_changes else - propagate_name_to(table) if !table.nil? and propagate_changes + propagate_name_to(table) if table and propagate_changes end end @@ -822,6 +824,20 @@ def propagate_name_to(table) raise CartoDB::InvalidMember.new(exception.to_s) end + def propagate_attribution_change + return unless attributions_changed + + # This includes both the canonical and derived visualizations + table.affected_visualizations.each do |affected_visualization| + affected_visualization.layers(:carto_and_torque).each do |layer| + if layer.options['table_name'] == table.name + layer.options['attribution'] = self.attributions + layer.save + end + end + end + end + def revert_name_change(previous_name) self.name = previous_name store diff --git a/spec/requests/carto/api/layers_controller_spec.rb b/spec/requests/carto/api/layers_controller_spec.rb index 10e4bd3c65b0..7344e661da43 100644 --- a/spec/requests/carto/api/layers_controller_spec.rb +++ b/spec/requests/carto/api/layers_controller_spec.rb @@ -10,6 +10,84 @@ it_behaves_like 'layers controllers' do end + describe 'attribution changes' do + include Rack::Test::Methods + include Warden::Test::Helpers + + before(:all) do + @headers = {'CONTENT_TYPE' => 'application/json'} + end + + before(:each) do + CartoDB::NamedMapsWrapper::NamedMaps.any_instance.stubs(:get => nil, :create => true, :update => true, :delete => true) + CartoDB::Visualization::Member.any_instance.stubs(:invalidate_cache).returns(nil) + end + + after(:each) do + delete_user_data($user_1) + end + + it 'attribution chanes in a visualization propagate to associated layers' do + table_1_attribution = 'attribution 1' + table_2_attribution = 'attribution 2' + modified_table_2_attribution = 'modified attribution 2' + + table1 = create_table(privacy: UserTable::PRIVACY_PUBLIC, name: "table#{rand(9999)}_1", user_id: $user_1.id) + table2 = create_table(privacy: UserTable::PRIVACY_PUBLIC, name: "table#{rand(9999)}_2", user_id: $user_1.id) + + payload = { + name: 'new visualization', + tables: [ + table1.name, + table2.name + ], + privacy: 'public' + } + + login_as($user_1, scope: $user_1.username) + host! "#{$user_1.username}.localhost.lan" + post api_v1_visualizations_create_url(api_key: @api_key), payload.to_json, @headers do |response| + response.status.should == 200 + @visualization_data = JSON.parse(response.body) + end + + visualization = Carto::Visualization.find(@visualization_data.fetch('id')) + + table1_visualization = CartoDB::Visualization::Member.new(id: table1.table_visualization.id).fetch + table1_visualization.attributions = table_1_attribution + table1_visualization.store + table2_visualization = CartoDB::Visualization::Member.new(id: table2.table_visualization.id).fetch + table2_visualization.attributions = table_2_attribution + table2_visualization.store + + get api_v1_maps_layers_index_url(map_id: visualization.map.id, api_key: @api_key) do |response| + response.status.should be_success + @layers_data = JSON.parse(response.body) + end + data_layers = @layers_data['layers'].select { |layer| layer['kind'] == 'carto' } + data_layers.count.should eq 2 + + # Rembember, layers by default added at top + data_layers[0]['options']['attribution'].should eq table_2_attribution + data_layers[1]['options']['attribution'].should eq table_1_attribution + + + table2_visualization.attributions = modified_table_2_attribution + table2_visualization.store + + get api_v1_maps_layers_index_url(map_id: visualization.map.id, api_key: @api_key) do |response| + response.status.should be_success + @layers_data = JSON.parse(response.body) + end + data_layers = @layers_data['layers'].select { |layer| layer['kind'] == 'carto' } + data_layers.count.should eq 2 + + # Rembember, layers by default added at top + data_layers[0]['options']['attribution'].should eq modified_table_2_attribution + data_layers[1]['options']['attribution'].should eq table_1_attribution + end + + end describe 'index' do include Rack::Test::Methods From fff5e38c08bc44a24cffa7342e8d2e73ad39e234 Mon Sep 17 00:00:00 2001 From: Pablo Alonso Garcia Date: Wed, 9 Sep 2015 10:48:32 +0200 Subject: [PATCH 07/15] Attributions of cdb.geo.CartoDBGroupLayer with multiple layers are handled correctly --- lib/assets/javascripts/cartodb/table/mapview.js | 4 ++++ lib/assets/test/spec/cartodb/table/mapview.spec.js | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/assets/javascripts/cartodb/table/mapview.js b/lib/assets/javascripts/cartodb/table/mapview.js index 6e3c213c2620..aae09dee9956 100644 --- a/lib/assets/javascripts/cartodb/table/mapview.js +++ b/lib/assets/javascripts/cartodb/table/mapview.js @@ -169,6 +169,10 @@ function GrouperLayerMapView(mapViewClass) { m.bind('tileOk', this._routeSignal('tileOk'), this); this.trigger('newLayerView', layer_view, layer, this); } else { + // HACK: Set the attribution of the layer in the groupLayer model so that + // cdb.admin.[Leaflet|GoogleMaps]MapView._addLayerToMap adds the new attribution + // to the map. + this.groupLayer.model.set('attribution', layer.get('attribution')); this.layers[layer.cid] = this.groupLayer; this._updateLayerDefinition(layer); this.trigger('newLayerView', this.groupLayer, layer, this); diff --git a/lib/assets/test/spec/cartodb/table/mapview.spec.js b/lib/assets/test/spec/cartodb/table/mapview.spec.js index ff0f64e0f50d..78f0d23da07c 100644 --- a/lib/assets/test/spec/cartodb/table/mapview.spec.js +++ b/lib/assets/test/spec/cartodb/table/mapview.spec.js @@ -9,13 +9,15 @@ describe("mapview", function() { var layer = new cdb.admin.CartoDBLayer({ table_name: 'test', tile_style: 'test', - user_name: 'test' + user_name: 'test', + attribution: 'attribution1' }); map.layers.add(layer); map.layers.add(new cdb.admin.CartoDBLayer({ table_name: 'test2', tile_style: 'style', - user_name: 'test' + user_name: 'test', + attribution: 'attribution2' })); var element = $('
    '); element.appendTo($('body')); @@ -164,6 +166,11 @@ describe("mapview", function() { expect(view.switchMapType).toHaveBeenCalled(); }); + it('should render attributions of each layer and default CartoDB attribution', function() { + var attributions = view.$el.find('.leaflet-control-attribution').html(); + expect(attributions).toEqual('attribution2, attribution1, CartoDB attribution'); + }); + describe("cdb.admin.MapTab.updateDataLayerView", function () { describe("given MapTab view has a cdb.CartoDB.Layer as data layer view", function() { beforeEach(function() { From 181213e85bf2b2fc14f2c4b7d552cf87051ef110 Mon Sep 17 00:00:00 2001 From: Pablo Alonso Garcia Date: Wed, 9 Sep 2015 10:57:03 +0200 Subject: [PATCH 08/15] Point cartodb.js submodule to latest develop --- lib/assets/javascripts/cdb | 2 +- vendor/assets/javascripts/cartodb.uncompressed.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/assets/javascripts/cdb b/lib/assets/javascripts/cdb index 8894d2ba8067..9c36d0291f8a 160000 --- a/lib/assets/javascripts/cdb +++ b/lib/assets/javascripts/cdb @@ -1 +1 @@ -Subproject commit 8894d2ba80671ed8f399501067c29bf0e1dc40f5 +Subproject commit 9c36d0291f8abbc9e52cb0c921db37d6f3a52bd2 diff --git a/vendor/assets/javascripts/cartodb.uncompressed.js b/vendor/assets/javascripts/cartodb.uncompressed.js index 3b22aabe897d..e715f4fc5bbf 100644 --- a/vendor/assets/javascripts/cartodb.uncompressed.js +++ b/vendor/assets/javascripts/cartodb.uncompressed.js @@ -1,6 +1,6 @@ -// cartodb.js version: 3.15.2 +// cartodb.js version: 3.15.3 // uncompressed version: cartodb.uncompressed.js -// sha: 8894d2ba80671ed8f399501067c29bf0e1dc40f5 +// sha: 9c36d0291f8abbc9e52cb0c921db37d6f3a52bd2 (function() { var define; // Undefine define (require.js), see https://github.com/CartoDB/cartodb.js/issues/543 var root = this; @@ -25655,7 +25655,7 @@ if (typeof window !== 'undefined') { var cdb = root.cdb = {}; - cdb.VERSION = "3.15.2"; + cdb.VERSION = "3.15.3"; cdb.DEBUG = false; cdb.CARTOCSS_VERSIONS = { From 4bf24223d8676c72bbbcf289c497eac5761189d1 Mon Sep 17 00:00:00 2001 From: Pablo Alonso Garcia Date: Wed, 9 Sep 2015 11:42:55 +0200 Subject: [PATCH 09/15] _updateAttribution clones the attribution so that the default attributions of maps is not modified --- lib/assets/javascripts/cartodb/models/map.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/assets/javascripts/cartodb/models/map.js b/lib/assets/javascripts/cartodb/models/map.js index 188aac34d793..5cb9fe344458 100644 --- a/lib/assets/javascripts/cartodb/models/map.js +++ b/lib/assets/javascripts/cartodb/models/map.js @@ -616,7 +616,7 @@ cdb.admin.Map = cdb.geo.Map.extend({ var attributionOfCurrentBaseLayer = currentBaseLayer && currentBaseLayer.get('attribution'); // Update Attribution of the map - this.updateAttribution(attributionOfCurrentBaseLayer, newBaseLayer.get('attribution')); + this._updateAttribution(attributionOfCurrentBaseLayer, newBaseLayer.get('attribution')); // Sets the base layer var options = { @@ -662,6 +662,24 @@ cdb.admin.Map = cdb.geo.Map.extend({ return newBaseLayer; }, + _updateAttribution: function(old, new_) { + var attributions = _.clone(this.get("attribution")) || []; + + // Remove the old one + if (old) { + attributions = _.without(attributions, old); + } + + // Save the new one + if (new_) { + if (!_.contains(attributions, new_)) { + attributions.push(new_); + } + } + + this.set({ attribution: attributions }); + }, + _updateBaseLayer: function(currentBaseLayer, newBaseLayer, opts) { var newAttributes = _.extend(_.clone(newBaseLayer.attributes), { id: currentBaseLayer.get('id'), From e51ab959a318a22308edb371aead8c6a06ff5515 Mon Sep 17 00:00:00 2001 From: Pablo Alonso Garcia Date: Wed, 9 Sep 2015 17:48:03 +0200 Subject: [PATCH 10/15] Changed the way attributions are calculated / rendered: - Update the attribution of cdb.admin.Map when layers are added/removed/reseted or attribution is updated. - Removed HACK now that the Map model has the right attributions. - Fixed spec. --- lib/assets/javascripts/cartodb/models/map.js | 1 + .../javascripts/cartodb/table/mapview.js | 4 ---- .../test/spec/cartodb/models/map.spec.js | 24 +++++++++++++++---- .../test/spec/cartodb/table/mapview.spec.js | 2 +- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/assets/javascripts/cartodb/models/map.js b/lib/assets/javascripts/cartodb/models/map.js index 5cb9fe344458..5f2ab6b2b3c4 100644 --- a/lib/assets/javascripts/cartodb/models/map.js +++ b/lib/assets/javascripts/cartodb/models/map.js @@ -538,6 +538,7 @@ cdb.admin.Map = cdb.geo.Map.extend({ this.layers = new cdb.admin.Layers(); this.layers.map = this; this.layers.bind('reset add change', this._layersChanged, this); + this.layers.bind('reset add remove change:attribution', this._updateAttributions, this); }, saveLayers: function(opts) { diff --git a/lib/assets/javascripts/cartodb/table/mapview.js b/lib/assets/javascripts/cartodb/table/mapview.js index aae09dee9956..6e3c213c2620 100644 --- a/lib/assets/javascripts/cartodb/table/mapview.js +++ b/lib/assets/javascripts/cartodb/table/mapview.js @@ -169,10 +169,6 @@ function GrouperLayerMapView(mapViewClass) { m.bind('tileOk', this._routeSignal('tileOk'), this); this.trigger('newLayerView', layer_view, layer, this); } else { - // HACK: Set the attribution of the layer in the groupLayer model so that - // cdb.admin.[Leaflet|GoogleMaps]MapView._addLayerToMap adds the new attribution - // to the map. - this.groupLayer.model.set('attribution', layer.get('attribution')); this.layers[layer.cid] = this.groupLayer; this._updateLayerDefinition(layer); this.trigger('newLayerView', this.groupLayer, layer, this); diff --git a/lib/assets/test/spec/cartodb/models/map.spec.js b/lib/assets/test/spec/cartodb/models/map.spec.js index 672c6181bfa2..695a803d11c0 100644 --- a/lib/assets/test/spec/cartodb/models/map.spec.js +++ b/lib/assets/test/spec/cartodb/models/map.spec.js @@ -74,7 +74,7 @@ describe("cartodb.models.Map", function() { expect(savingLayersFinishCallback.calls.count()).toEqual(1); done(); }, 0); - expect(map.get('attribution')).toEqual([ cartoDBAttribution, 'CartoDB1.0' ]); + expect(map.get('attribution')).toEqual([ 'CartoDB1.0', cartoDBAttribution ]); }) it('should update the existing base layer if the new layer has the same type', function(done) { @@ -110,7 +110,7 @@ describe("cartodb.models.Map", function() { expect(savingLayersFinishCallback.calls.count()).toEqual(1); done(); }, 0); - expect(map.get('attribution')).toEqual([ cartoDBAttribution, 'CartoDB2.0' ]); + expect(map.get('attribution')).toEqual([ 'CartoDB2.0', cartoDBAttribution ]); expect(map.layers.length).toEqual(1); }) @@ -136,7 +136,7 @@ describe("cartodb.models.Map", function() { map.setBaseLayer(baseLayer); - expect(map.get('attribution')).toEqual([ cartoDBAttribution, 'CartoDB1.0' ]); + expect(map.get('attribution')).toEqual([ 'CartoDB1.0', cartoDBAttribution ]); savingLayersFinishCallback = jasmine.createSpy('savingLayersFinishCallback'); map.bind('savingLayersFinish', savingLayersFinishCallback); @@ -151,7 +151,7 @@ describe("cartodb.models.Map", function() { expect(savingLayersFinishCallback.calls.count()).toEqual(1); done(); }, 0); - expect(map.get('attribution')).toEqual([ cartoDBAttribution, 'CartoDB2.0' ]); + expect(map.get('attribution')).toEqual([ 'CartoDB2.0', cartoDBAttribution ]); expect(map.layers.length).toEqual(1); }) @@ -464,6 +464,22 @@ describe("cartodb.models.Map", function() { expect(map.set('center', [0, -185]).clamp().get('center')).toEqual([0, 175]) }); + it('should update the attribution of the map when layers change', function() { + var layer1 = new cdb.geo.CartoDBLayer({ attribution: 'attribution1' }); + var layer2 = new cdb.geo.CartoDBLayer({ attribution: 'attribution1' }); + var layer3 = new cdb.geo.CartoDBLayer({ attribution: 'wadus' }); + var layer4 = new cdb.geo.CartoDBLayer({ attribution: '' }); + + map.layers.reset([ layer1, layer2, layer3, layer4 ]); + + // Attributions have been updated removing duplicated and empty attributions + expect(map.get('attribution')).toEqual([ + "attribution1", + "wadus", + "CartoDB attribution", + ]); + }); + describe("layers", function() { it("should add layers on top", function() { diff --git a/lib/assets/test/spec/cartodb/table/mapview.spec.js b/lib/assets/test/spec/cartodb/table/mapview.spec.js index 78f0d23da07c..f9bce17c3503 100644 --- a/lib/assets/test/spec/cartodb/table/mapview.spec.js +++ b/lib/assets/test/spec/cartodb/table/mapview.spec.js @@ -168,7 +168,7 @@ describe("mapview", function() { it('should render attributions of each layer and default CartoDB attribution', function() { var attributions = view.$el.find('.leaflet-control-attribution').html(); - expect(attributions).toEqual('attribution2, attribution1, CartoDB attribution'); + expect(attributions).toEqual('attribution1, attribution2, CartoDB attribution'); }); describe("cdb.admin.MapTab.updateDataLayerView", function () { From 0e73e9030efec3e1eee7db6756ce1a7916fb01b8 Mon Sep 17 00:00:00 2001 From: Pablo Alonso Garcia Date: Wed, 9 Sep 2015 17:48:26 +0200 Subject: [PATCH 11/15] Updated cartodb.js (points to a temporary branch) --- lib/assets/javascripts/cdb | 2 +- .../javascripts/cartodb.uncompressed.js | 78 ++++++------------- 2 files changed, 24 insertions(+), 56 deletions(-) diff --git a/lib/assets/javascripts/cdb b/lib/assets/javascripts/cdb index 9c36d0291f8a..65133f214eb3 160000 --- a/lib/assets/javascripts/cdb +++ b/lib/assets/javascripts/cdb @@ -1 +1 @@ -Subproject commit 9c36d0291f8abbc9e52cb0c921db37d6f3a52bd2 +Subproject commit 65133f214eb399731d493ffcb380f42cf9283d0b diff --git a/vendor/assets/javascripts/cartodb.uncompressed.js b/vendor/assets/javascripts/cartodb.uncompressed.js index e715f4fc5bbf..f0cd3878983f 100644 --- a/vendor/assets/javascripts/cartodb.uncompressed.js +++ b/vendor/assets/javascripts/cartodb.uncompressed.js @@ -1,6 +1,6 @@ // cartodb.js version: 3.15.3 // uncompressed version: cartodb.uncompressed.js -// sha: 9c36d0291f8abbc9e52cb0c921db37d6f3a52bd2 +// sha: 65133f214eb399731d493ffcb380f42cf9283d0b (function() { var define; // Undefine define (require.js), see https://github.com/CartoDB/cartodb.js/issues/543 var root = this; @@ -27275,9 +27275,26 @@ cdb.geo.Map = cdb.core.Model.extend({ } }, this); + this.layers.bind('reset', this._updateAttributions, this); + this.layers.bind('add', this._updateAttributions, this); + this.layers.bind('remove', this._updateAttributions, this); + this.layers.bind('change:attribution', this._updateAttributions, this); + this.geometries = new cdb.geo.Geometries(); }, + _updateAttributions: function() { + var attributions = _.chain(this.layers.models) + .map(function(layer) { return layer.get('attribution'); }) + .compact() + .uniq() + .value(); + + attributions.push(this.defaults.attribution[0]); + + this.set('attribution', attributions); + }, + setView: function(latlng, zoom) { this.set({ center: latlng, @@ -27443,24 +27460,6 @@ cdb.geo.Map = cdb.core.Model.extend({ } }, - updateAttribution: function(old, new_) { - var attributions = this.get("attribution") || []; - - // Remove the old one - if (old) { - attributions = _.without(attributions, old); - } - - // Save the new one - if (new_) { - if (!_.contains(attributions, new_)) { - attributions.push(new_); - } - } - - this.set({ attribution: attributions }); - }, - addGeometry: function(geom) { this.geometries.add(geom); }, @@ -27644,7 +27643,7 @@ cdb.geo.MapView = cdb.core.View.extend({ this.map.bind('change:scrollwheel', this._setScrollWheel, this); this.map.bind('change:keyboard', this._setKeyboard, this); this.map.bind('change:center', this._setCenter, this); - this.map.bind('change:attribution', this._setAttribution, this); + this.map.bind('change:attribution', this.setAttribution, this); }, /** unbind model properties */ @@ -27669,10 +27668,6 @@ cdb.geo.MapView = cdb.core.View.extend({ this.map.fitBounds(bounds, this.getSize()) }, - _setAttribution: function(m,attr) { - this.setAttribution(m); - }, - _addLayers: function() { var self = this; this._removeLayers(); @@ -35516,8 +35511,8 @@ cdb.geo.leaflet.PathView = PathView; this.map.geometries.bind('remove', this._removeGeometry, this); this._bindModel(); - this._addLayers(); + this.setAttribution(); this.map_leaflet.on('layeradd', function(lyr) { this.trigger('layeradd', lyr, self); @@ -35700,19 +35695,6 @@ cdb.geo.leaflet.PathView = PathView; lv.setZIndex(lv.model.get('order')); } - var attribution = layer.get('attribution'); - - if (attribution && attribution !== '') { - // Setting attribution in map model - // it doesn't persist in the backend, so this is needed. - var attributions = _.clone(this.map.get('attribution')) || []; - if (!_.contains(attributions, attribution)) { - attributions.unshift(attribution); - } - - this.map.set({ attribution: attributions }); - } - if(opts === undefined || !opts.silent) { this.trigger('newLayerView', layer_view, layer_view.model, this); } @@ -37019,6 +37001,7 @@ if(typeof(google) != "undefined" && typeof(google.maps) != "undefined") { this._bindModel(); this._addLayers(); + this.setAttribution(); google.maps.event.addListener(this.map_googlemaps, 'center_changed', function() { var c = self.map_googlemaps.getCenter(); @@ -37052,7 +37035,6 @@ if(typeof(google) != "undefined" && typeof(google.maps) != "undefined") { this.projector = new cdb.geo.CartoDBLayerGroupGMaps.Projector(this.map_googlemaps); this.projector.draw = this._ready; - }, _ready: function() { @@ -37144,21 +37126,7 @@ if(typeof(google) != "undefined" && typeof(google.maps) != "undefined") { cdb.log.error("layer type not supported"); } - var attribution = layer.get('attribution'); - - if (attribution && attribution !== '') { - // Setting attribution in map model - // it doesn't persist in the backend, so this is needed. - var attributions = _.clone(this.map.get('attribution')) || []; - if (!_.contains(attributions, attribution)) { - attributions.unshift(attribution); - } - - this.map.set({ attribution: attributions }); - } - return layer_view; - }, pixelToLatLon: function(pos) { @@ -37202,10 +37170,10 @@ if(typeof(google) != "undefined" && typeof(google.maps) != "undefined") { return [ [0,0], [0,0] ]; }, - setAttribution: function(m) { + setAttribution: function() { // Remove old one var old = document.getElementById("cartodb-gmaps-attribution") - , attribution = m.get("attribution").join(", "); + , attribution = this.map.get("attribution").join(", "); // If div already exists, remove it if (old) { From 7eb948d0c8d818e1c0ace7989b14c38fdeabaa21 Mon Sep 17 00:00:00 2001 From: Pablo Alonso Garcia Date: Wed, 9 Sep 2015 18:14:23 +0200 Subject: [PATCH 12/15] Attribution of the map is automagically updated when layers are resetted/added/removed or attribution is changed --- lib/assets/javascripts/cartodb/models/map.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/assets/javascripts/cartodb/models/map.js b/lib/assets/javascripts/cartodb/models/map.js index 5f2ab6b2b3c4..722f32163d06 100644 --- a/lib/assets/javascripts/cartodb/models/map.js +++ b/lib/assets/javascripts/cartodb/models/map.js @@ -614,10 +614,6 @@ cdb.admin.Map = cdb.geo.Map.extend({ var newBaseLayer = baseLayer; var currentBaseLayer = this.layers.at(0); var newBaseLayerHasLabels = newBaseLayer.get('labels') && newBaseLayer.get('labels').url; - var attributionOfCurrentBaseLayer = currentBaseLayer && currentBaseLayer.get('attribution'); - - // Update Attribution of the map - this._updateAttribution(attributionOfCurrentBaseLayer, newBaseLayer.get('attribution')); // Sets the base layer var options = { From a3e7484534412f1f1047d44cd198f7094eb00f73 Mon Sep 17 00:00:00 2001 From: Pablo Alonso Garcia Date: Wed, 9 Sep 2015 19:06:40 +0200 Subject: [PATCH 13/15] Point cartodb.js submodule to latest develop --- lib/assets/javascripts/cdb | 2 +- vendor/assets/javascripts/cartodb.uncompressed.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/assets/javascripts/cdb b/lib/assets/javascripts/cdb index 65133f214eb3..71ff7e142e2b 160000 --- a/lib/assets/javascripts/cdb +++ b/lib/assets/javascripts/cdb @@ -1 +1 @@ -Subproject commit 65133f214eb399731d493ffcb380f42cf9283d0b +Subproject commit 71ff7e142e2b8cd694e80ef655ff8d532a472f49 diff --git a/vendor/assets/javascripts/cartodb.uncompressed.js b/vendor/assets/javascripts/cartodb.uncompressed.js index f0cd3878983f..10036d530077 100644 --- a/vendor/assets/javascripts/cartodb.uncompressed.js +++ b/vendor/assets/javascripts/cartodb.uncompressed.js @@ -1,6 +1,6 @@ // cartodb.js version: 3.15.3 // uncompressed version: cartodb.uncompressed.js -// sha: 65133f214eb399731d493ffcb380f42cf9283d0b +// sha: 71ff7e142e2b8cd694e80ef655ff8d532a472f49 (function() { var define; // Undefine define (require.js), see https://github.com/CartoDB/cartodb.js/issues/543 var root = this; @@ -27284,13 +27284,15 @@ cdb.geo.Map = cdb.core.Model.extend({ }, _updateAttributions: function() { + var defaultCartoDBAttribution = this.defaults.attribution[0]; var attributions = _.chain(this.layers.models) .map(function(layer) { return layer.get('attribution'); }) + .reject(function(attribution) { return attribution == defaultCartoDBAttribution}) .compact() .uniq() .value(); - attributions.push(this.defaults.attribution[0]); + attributions.push(defaultCartoDBAttribution); this.set('attribution', attributions); }, From b88f8d6e282beb413c588ae6aefff8f46725e6d6 Mon Sep 17 00:00:00 2001 From: Pablo Alonso Garcia Date: Wed, 9 Sep 2015 19:08:52 +0200 Subject: [PATCH 14/15] This method is no longer needed --- lib/assets/javascripts/cartodb/models/map.js | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/lib/assets/javascripts/cartodb/models/map.js b/lib/assets/javascripts/cartodb/models/map.js index 722f32163d06..19e8f457bde3 100644 --- a/lib/assets/javascripts/cartodb/models/map.js +++ b/lib/assets/javascripts/cartodb/models/map.js @@ -659,24 +659,6 @@ cdb.admin.Map = cdb.geo.Map.extend({ return newBaseLayer; }, - _updateAttribution: function(old, new_) { - var attributions = _.clone(this.get("attribution")) || []; - - // Remove the old one - if (old) { - attributions = _.without(attributions, old); - } - - // Save the new one - if (new_) { - if (!_.contains(attributions, new_)) { - attributions.push(new_); - } - } - - this.set({ attribution: attributions }); - }, - _updateBaseLayer: function(currentBaseLayer, newBaseLayer, opts) { var newAttributes = _.extend(_.clone(newBaseLayer.attributes), { id: currentBaseLayer.get('id'), From ab4e355e15326ad39013d9cd1c0f68e6eb33d5cd Mon Sep 17 00:00:00 2001 From: Pablo Alonso Garcia Date: Thu, 10 Sep 2015 10:04:06 +0200 Subject: [PATCH 15/15] Updated NEWS.md --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 87c99a2a7cbe..668ccce0ada3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -18,6 +18,7 @@ * Detection of lat/long columns now is done in `ogr2ogr2` rather than rails code [#5349](https://github.com/CartoDB/cartodb/pull/5349). In order to get this feature working (and some related tests), execute this to get the ogr2ogr2 package updated: `sudo apt-get update; sudo apt-get upgrade`. From this version on, the ogr2ogr2 package is mandatory. In order to install it: `sudo apt-get install ogr2ogr2-static-bin`. * Removed Mixpanel tracking code [#5410](https://github.com/CartoDB/cartodb/pull/5410) * Don't try to short url with bitly if credentials are not present in app_config.yml +* Display custom attribution of layers in the editor and embeds [#5388](https://github.com/CartoDB/cartodb/pull/5388) 3.10.3 (2015-08-13) ---