-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add Mapbox wordmark as LogoControl #3933
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
'use strict'; | ||
|
||
const DOM = require('../../util/dom'); | ||
const util = require('../../util/util'); | ||
|
||
/** | ||
* A `LogoControl` is a control that adds the Mapbox watermark | ||
* to the map as required by the [terms of service](https://www.mapbox.com/tos/) for Mapbox | ||
* vector tiles and core styles. | ||
* | ||
* @implements {IControl} | ||
**/ | ||
|
||
class LogoControl { | ||
|
||
constructor() { | ||
util.bindAll(['_logoRequired', '_updateLogo'], this); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can omit empty constructors |
||
|
||
onAdd(map) { | ||
this._map = map; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to save the map reference if it's not used by the control? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess we don't! I was following the |
||
this._container = DOM.create('div', 'mapboxgl-ctrl'); | ||
|
||
this._map.on('data', this._updateLogo); | ||
this._updateLogo(); | ||
return this._container; | ||
} | ||
|
||
onRemove() { | ||
this._container.parentNode.removeChild(this._container); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also needs |
||
} | ||
|
||
getDefaultPosition() { | ||
return 'bottom-left'; | ||
} | ||
|
||
_updateLogo() { | ||
if (this._logoRequired()) { | ||
const anchor = DOM.create('a', 'mapboxgl-ctrl-logo'); | ||
anchor.target = "_blank"; | ||
anchor.href = "https://www.mapbox.com/"; | ||
anchor.setAttribute("aria-label", "Mapbox logo"); | ||
this._container.appendChild(anchor); | ||
this._map.off('data', this._updateLogo); | ||
} | ||
} | ||
|
||
_logoRequired() { | ||
if (!this._map.style) return; | ||
|
||
const sourceCaches = this._map.style.sourceCaches; | ||
for (const id in sourceCaches) { | ||
const source = sourceCaches[id].getSource(); | ||
if (source.mapbox_logo) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} | ||
|
||
|
||
module.exports = LogoControl; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ const LngLat = require('../geo/lng_lat'); | |
const LngLatBounds = require('../geo/lng_lat_bounds'); | ||
const Point = require('point-geometry'); | ||
const AttributionControl = require('./control/attribution_control'); | ||
const LogoControl = require('./control/logo_control'); | ||
const isSupported = require('mapbox-gl-supported'); | ||
|
||
const defaultMinZoom = 0; | ||
|
@@ -99,6 +100,7 @@ const defaultOptions = { | |
* in an HTML element's `class` attribute. To learn more about Mapbox style classes, read about | ||
* [Layers](https://www.mapbox.com/mapbox-gl-style-spec/#layers) in the style specification. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you really mean to replace Given further down you've dropped out There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yipes good catch @andrewharvey -- this was not intentional! |
||
* @param {boolean} [options.attributionControl=true] If `true`, an [AttributionControl](#AttributionControl) will be added to the map. | ||
* @param {boolean} [options.logoPosition='bottom-left'] Position of the Mapbox wordmark on the map. Valid options are ['top-left','top-right', 'bottom-left', 'bottom-right']. | ||
* @param {boolean} [options.failIfMajorPerformanceCaveat=false] If `true`, map creation will fail if the performance of Mapbox | ||
* GL JS would be dramatically worse than expected (i.e. a software renderer would be used). | ||
* @param {boolean} [options.preserveDrawingBuffer=false] If `true`, the map's canvas can be exported to a PNG using `map.getCanvas().toDataURL()`. This is `false` by default as a performance optimization. | ||
|
@@ -200,6 +202,7 @@ class Map extends Camera { | |
if (options.style) this.setStyle(options.style); | ||
|
||
if (options.attributionControl) this.addControl(new AttributionControl()); | ||
this.addControl(new LogoControl(), options.logoPosition); | ||
|
||
this.on('style.load', function() { | ||
if (this.transform.unmodified) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
'use strict'; | ||
const test = require('mapbox-gl-js-test').test; | ||
const VectorTileSource = require('../../../../js/source/vector_tile_source'); | ||
const window = require('../../../../js/util/window'); | ||
const Map = require('../../../../js/ui/map'); | ||
|
||
function createMap(logoPosition, logoRequired) { | ||
const container = window.document.createElement('div'); | ||
return new Map({ | ||
container: container, | ||
style: { | ||
version: 8, | ||
sources: { | ||
'composite': createSource({ | ||
minzoom: 1, | ||
maxzoom: 10, | ||
attribution: "Mapbox", | ||
tiles: [ | ||
"http://example.com/{z}/{x}/{y}.png" | ||
] | ||
}, logoRequired) | ||
}, | ||
layers: [] | ||
}, | ||
logoPosition: logoPosition || undefined | ||
}); | ||
} | ||
|
||
function createSource(options, logoRequired) { | ||
const source = new VectorTileSource('id', options, { send: function () {} }); | ||
source.onAdd({ | ||
transform: { angle: 0, pitch: 0, showCollisionBoxes: false } | ||
}); | ||
source.on('error', (e) => { | ||
throw e.error; | ||
}); | ||
const logoFlag = "mapbox_logo"; | ||
source[logoFlag] = logoRequired === undefined ? true : logoRequired; | ||
return source; | ||
} | ||
test('LogoControl appears in bottom-left by default', (t) => { | ||
const map = createMap(); | ||
map.on('load', () => { | ||
t.equal(map.getContainer().querySelectorAll( | ||
'.mapboxgl-ctrl-bottom-left .mapboxgl-ctrl-logo' | ||
).length, 1); | ||
t.end(); | ||
}); | ||
}); | ||
test('LogoControl appears in the position specified by the position option', (t) => { | ||
const map = createMap('top-left'); | ||
map.on('load', () => { | ||
t.equal(map.getContainer().querySelectorAll( | ||
'.mapboxgl-ctrl-top-left .mapboxgl-ctrl-logo' | ||
).length, 1); | ||
t.end(); | ||
}); | ||
}); | ||
test('LogoControl is not added when the mapbox_logo property is false', (t) => { | ||
const map = createMap('top-left', false); | ||
map.on('load', () => { | ||
t.equal(map.getContainer().querySelectorAll( | ||
'.mapboxgl-ctrl-top-left .mapboxgl-ctrl-logo').length, | ||
0); | ||
t.end(); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
_logoRequired
doesn't need to be bound (it's not used as an event handler).