diff --git a/RELEASING.md b/RELEASING.md index ee71752d7c..98f5cf45f5 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -13,7 +13,7 @@ - Create a new branch to prepare the release: ``` -git flow release start 3.15.3 +git flow release start 3.15.4 ``` - Build CartoDB.js files, choosing the new version: @@ -25,7 +25,7 @@ grunt release - Update the NEWS file and commit the changes. Take into account that new CartoDB.js version will be replaced in ```API.md```, ```RELEASING.md```, ```README.md```, ```package.json```, ```cartodb.js``` and ```examples``` files. ``` -git commit -am "Files changed for version 3.15.3" +git commit -am "Files changed for version 3.15.4" ``` - Release it. @@ -36,8 +36,8 @@ grunt publish - Check if those files have been updated in the CDN: ``` -http://libs.cartocdn.com.s3.amazonaws.com/cartodb.js/v3/3.15.3/cartodb.js -http://libs.cartocdn.com/cartodb.js/v3/3.15.3/cartodb.js +http://libs.cartocdn.com.s3.amazonaws.com/cartodb.js/v3/3.15.4/cartodb.js +http://libs.cartocdn.com/cartodb.js/v3/3.15.4/cartodb.js http://libs.cartocdn.com.s3.amazonaws.com/cartodb.js/v3/3.13/cartodb.js http://libs.cartocdn.com/cartodb.js/v3/3.13/cartodb.js ``` @@ -46,7 +46,7 @@ http://libs.cartocdn.com/cartodb.js/v3/3.13/cartodb.js - And to finish: close the release and push it. ``` -git flow release finish 3.15.3 +git flow release finish 3.15.4 git push --all git push --tags ``` @@ -75,7 +75,7 @@ grunt grunt publish ``` -For example, if we are in 3.15.3 and we want to go back to 3.13.4 +For example, if we are in 3.15.4 and we want to go back to 3.13.4 ``` git checkout 3.13.4 diff --git a/doc/API.md b/doc/API.md index cc0a496228..b8a02be3b1 100644 --- a/doc/API.md +++ b/doc/API.md @@ -1182,16 +1182,16 @@ cartodb.Image(vizjson_url) An _Image_ object -#### Image.getURL(_callback(err, url)_) +#### Image.getUrl(_callback(err, url)_) Gets the URL for the image requested. -
Image.getURL
+
Image.getUrl
```javascript @@ -1452,10 +1452,10 @@ Anytime you wish to push a stable version of your site to the web though, you ca alert(cartodb.VERSION) ``` -Once you know which version of CartoDB.js you're using, you can point your site to that release. If the current version of CartoDB.js is 3.15.3, the URL would be: +Once you know which version of CartoDB.js you're using, you can point your site to that release. If the current version of CartoDB.js is 3.15.4, the URL would be: ```html - + ``` You can do the same for the CSS documents we provide: diff --git a/examples/header_overlay.html b/examples/header_overlay.html new file mode 100644 index 0000000000..f965209ad6 --- /dev/null +++ b/examples/header_overlay.html @@ -0,0 +1,80 @@ + + + + Header with createLayer | CartoDB.js + + + + + + + + +
+ + + + + + + diff --git a/package.json b/package.json index 47d0e458a8..ef1abc7e82 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cartodb.js", - "version": "3.15.3", + "version": "3.15.4", "description": "CartoDB javascript library", "repository": { "type": "git", diff --git a/src/cartodb.js b/src/cartodb.js index 2293829efa..bb418ffcbf 100644 --- a/src/cartodb.js +++ b/src/cartodb.js @@ -5,7 +5,7 @@ var cdb = root.cdb = {}; - cdb.VERSION = "3.15.3"; + cdb.VERSION = "3.15.4"; cdb.DEBUG = false; cdb.CARTOCSS_VERSIONS = { diff --git a/src/geo/gmaps/gmaps.js b/src/geo/gmaps/gmaps.js index 11bb085462..77082feea6 100644 --- a/src/geo/gmaps/gmaps.js +++ b/src/geo/gmaps/gmaps.js @@ -83,6 +83,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(); @@ -116,7 +117,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() { @@ -208,21 +208,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) { @@ -266,10 +252,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) { diff --git a/src/geo/leaflet/leaflet.js b/src/geo/leaflet/leaflet.js index 317efc4a07..fa557439d7 100644 --- a/src/geo/leaflet/leaflet.js +++ b/src/geo/leaflet/leaflet.js @@ -70,8 +70,8 @@ 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); @@ -254,19 +254,6 @@ 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); } diff --git a/src/geo/map.js b/src/geo/map.js index e1c9217871..b820563266 100644 --- a/src/geo/map.js +++ b/src/geo/map.js @@ -294,9 +294,28 @@ 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 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(defaultCartoDBAttribution); + + this.set('attribution', attributions); + }, + setView: function(latlng, zoom) { this.set({ center: latlng, @@ -462,24 +481,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); }, @@ -663,7 +664,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 */ @@ -688,10 +689,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(); diff --git a/src/geo/ui/fullscreen.js b/src/geo/ui/fullscreen.js index 07cd874a04..0adb69682f 100644 --- a/src/geo/ui/fullscreen.js +++ b/src/geo/ui/fullscreen.js @@ -99,14 +99,42 @@ cdb.ui.common.FullScreen = cdb.core.View.extend({ }, render: function() { + if (this._canFullScreenBeEnabled()) { + var $el = this.$el; + var options = _.extend(this.options); + $el.html(this.options.template(options)); + } else { + cdb.log.info('FullScreen is deprecated on insecure origins. See https://goo.gl/rStTGz for more details.'); + } - var $el = this.$el; + return this; + }, - var options = _.extend(this.options); + _canFullScreenBeEnabled: function() { + // If frameElement exists, it means that the map + // is embebed as an iframe so we need to check if + // the parent has a secure protocol + var frameElement = window && window.frameElement; + if (frameElement) { + var parentWindow = this._getFramedWindow(frameElement); + var parentProtocol = parentWindow.location.protocol; + if (parentProtocol.search('https:') !== 0) { + return false; + } + } - $el.html(this.options.template(options)); + return true; + }, - return this; + _getFramedWindow: function(f) { + if (f.parentNode == null) { + f = document.body.appendChild(f); + } + var w = (f.contentWindow || f.contentDocument); + if (w && w.nodeType && w.nodeType==9) { + w = (w.defaultView || w.parentWindow); + } + return w; } }); diff --git a/test/spec/geo/gmaps/gmaps.spec.js b/test/spec/geo/gmaps/gmaps.spec.js index 991e5c76ce..c64275915f 100644 --- a/test/spec/geo/gmaps/gmaps.spec.js +++ b/test/spec/geo/gmaps/gmaps.spec.js @@ -234,20 +234,4 @@ done(); }, 2000); }); - - it("should set the attributions on the map when layers are added", function() { - var layer1 = new cdb.geo.CartoDBLayer({ type: 'cartodb', attribution: 'attribution1', table_name: "table1", tile_style: 'test', user_name: 'test' }); - var layer2 = new cdb.geo.CartoDBLayer({ type: 'cartodb', attribution: 'attribution2', table_name: "table2", tile_style: 'test', user_name: 'test' }); - var layer3 = new cdb.geo.CartoDBLayer({ type: 'cartodb', attribution: '', table_name: "table2", tile_style: 'test', user_name: 'test' }); - - map.layers.reset([layer1, layer2, layer3]); - - expect(map.get('attribution')).toEqual([ - 'attribution2', - 'attribution1', - 'CartoDB attribution' - ]); - }); - }); - diff --git a/test/spec/geo/leaflet/leaflet.spec.js b/test/spec/geo/leaflet/leaflet.spec.js index af7687afd0..bf64753e8d 100644 --- a/test/spec/geo/leaflet/leaflet.spec.js +++ b/test/spec/geo/leaflet/leaflet.spec.js @@ -293,20 +293,6 @@ describe('LeafletMapView', function() { expect(mapView.layers[newLayer.cid].check).toEqual('testing'); }); - it("should set the attributions on the map when layers are added", function() { - var layer1 = new cdb.geo.CartoDBLayer({ type: 'cartodb', attribution: 'attribution1', table_name: "table1", tile_style: 'test', user_name: 'test' }); - var layer2 = new cdb.geo.CartoDBLayer({ type: 'cartodb', attribution: 'attribution2', table_name: "table2", tile_style: 'test', user_name: 'test' }); - var layer3 = new cdb.geo.CartoDBLayer({ type: 'cartodb', attribution: '', table_name: "table2", tile_style: 'test', user_name: 'test' }); - - map.layers.reset([layer1, layer2, layer3]); - - expect(map.get('attribution')).toEqual([ - 'attribution2', - 'attribution1', - 'CartoDB attribution' - ]); - }); - // Test cases for gmaps substitutes since the support is deprecated. _({ // GMaps basemap base_type: expected substitute data //empty = defaults to gray_roadmap diff --git a/test/spec/geo/map.spec.js b/test/spec/geo/map.spec.js index fefd2ecf1b..8af9c8b005 100644 --- a/test/spec/geo/map.spec.js +++ b/test/spec/geo/map.spec.js @@ -227,6 +227,72 @@ describe("geo.map", function() { expect(map.get('maxZoom')).toEqual(40); expect(map.get('minZoom')).toEqual(0); }); + + it('should update the attributions of the map when layers are reset/added/removed', function() { + + map = new cdb.geo.Map(); + + // Map has the default CartoDB attribution + expect(map.get('attribution')).toEqual([ + "CartoDB attribution" + ]); + + 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", + ]); + + var layer = new cdb.geo.CartoDBLayer({ attribution: 'attribution2' }); + + map.layers.add(layer); + + // The attribution of the new layer has been appended before the default CartoDB attribution + expect(map.get('attribution')).toEqual([ + "attribution1", + "wadus", + "attribution2", + "CartoDB attribution", + ]); + + layer.set('attribution', 'new attribution'); + + // The attribution of the layer has been updated in the map + expect(map.get('attribution')).toEqual([ + "attribution1", + "wadus", + "new attribution", + "CartoDB attribution", + ]); + + map.layers.remove(layer); + + expect(map.get('attribution')).toEqual([ + "attribution1", + "wadus", + "CartoDB attribution", + ]); + + // Addind a layer with the default attribution + var layer = new cdb.geo.CartoDBLayer(); + + map.layers.add(layer, { at: 0 }); + + // Default CartoDB only appears once and it's the last one + expect(map.get('attribution')).toEqual([ + "attribution1", + "wadus", + "CartoDB attribution", + ]); + }) }); describe('MapView', function() { diff --git a/test/spec/geo/ui/mobile.spec.js b/test/spec/geo/ui/mobile.spec.js index 7cf135ebe1..f63c8356d9 100644 --- a/test/spec/geo/ui/mobile.spec.js +++ b/test/spec/geo/ui/mobile.spec.js @@ -61,7 +61,7 @@ describe("cdb.geo.ui.Mobile", function() { } }); - map.layers = new cdb.geo.Layers([l1, layerGroup]); + map.layers.reset([l1, layerGroup]); template = cdb.core.Template.compile('\
\
\ @@ -650,7 +650,7 @@ describe("cdb.geo.ui.Mobile", function() { } }); - map.layers = new cdb.geo.Layers([l1, layerGroup]); + map.layers.reset([l1, layerGroup]); mapView = new cdb.geo.GoogleMapsMapView({