Skip to content

Commit

Permalink
Allow programmatic construction of style even when one is not passed…
Browse files Browse the repository at this point in the history
… in initially ( h/t @stepankuzmin ) (#8924)
  • Loading branch information
Arindam Bose authored Dec 20, 2019
1 parent 11cbea8 commit b61d19b
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 9 deletions.
29 changes: 29 additions & 0 deletions src/style-spec/empty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import latest from './reference/latest';

export default function emptyStyle() {
const style = {};

const version = latest['$version'];
for (const styleKey in latest['$root']) {
const spec = latest['$root'][styleKey];

if (spec.required) {
let value = null;
if (styleKey === 'version') {
value = version;
} else {
if (spec.type === 'array') {
value = [];
} else {
value = {};
}
}

if (value != null) {
style[styleKey] = value;
}
}
}

return style;
}
8 changes: 8 additions & 0 deletions src/style/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import GeoJSONSource from '../source/geojson_source';
import styleSpec from '../style-spec/reference/latest';
import getWorkerPool from '../util/global_worker_pool';
import deref from '../style-spec/deref';
import emptyStyle from '../style-spec/empty';
import diffStyles, {operations as diffOperations} from '../style-spec/diff';
import {
registerForPluginStateChange,
Expand Down Expand Up @@ -88,6 +89,8 @@ const ignoredDiffOperations = pick(diffOperations, [
'setPitch'
]);

const empty = emptyStyle();

export type StyleOptions = {
validate?: boolean,
localIdeographFontFamily?: string
Expand Down Expand Up @@ -229,6 +232,11 @@ class Style extends Evented {
});
}

loadEmpty() {
this.fire(new Event('dataloading', {dataType: 'style'}));
this._load(empty, false);
}

_load(json: StyleSpecification, validate: boolean) {
if (validate && emitValidationErrors(this, validateStyle(json))) {
return;
Expand Down
14 changes: 13 additions & 1 deletion src/ui/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,14 @@ class Map extends Camera {
return this;
}

_lazyInitEmptyStyle() {
if (!this.style) {
this.style = new Style(this, {});
this.style.setEventedParent(this, {style: this.style});
this.style.loadEmpty();
}
}

_diffStyle(style: StyleSpecification | string, options?: {diff?: boolean} & StyleOptions) {
if (typeof style === 'string') {
const url = this._requestManager.normalizeStyleURL(style);
Expand Down Expand Up @@ -1307,6 +1315,7 @@ class Map extends Camera {
* @see Raster DEM source: [Add hillshading](https://docs.mapbox.com/mapbox-gl-js/example/hillshade/)
*/
addSource(id: string, source: SourceSpecification) {
this._lazyInitEmptyStyle();
this.style.addSource(id, source);
return this._update(true);
}
Expand Down Expand Up @@ -1359,6 +1368,7 @@ class Map extends Camera {
* @param {Function} callback Called when the source type is ready or with an error argument if there is an error.
*/
addSourceType(name: string, SourceType: any, callback: Function) {
this._lazyInitEmptyStyle();
return this.style.addSourceType(name, SourceType, callback);
}

Expand Down Expand Up @@ -1439,7 +1449,7 @@ class Map extends Camera {
addImage(id: string,
image: HTMLImageElement | ImageData | {width: number, height: number, data: Uint8Array | Uint8ClampedArray} | StyleImageInterface,
{pixelRatio = 1, sdf = false, stretchX, stretchY, content}: $Shape<StyleImageMetadata> = {}) {

this._lazyInitEmptyStyle();
const version = 0;

if (image instanceof HTMLImageElement) {
Expand Down Expand Up @@ -1627,6 +1637,7 @@ class Map extends Camera {
* @see [Add a WMS source](https://www.mapbox.com/mapbox-gl-js/example/wms/)
*/
addLayer(layer: LayerSpecification | CustomLayerInterface, beforeId?: string) {
this._lazyInitEmptyStyle();
this.style.addLayer(layer, beforeId);
return this._update(true);
}
Expand Down Expand Up @@ -1808,6 +1819,7 @@ class Map extends Camera {
* @returns {Map} `this`
*/
setLight(light: LightSpecification, options: StyleSetterOptions = {}) {
this._lazyInitEmptyStyle();
this.style.setLight(light, options);
return this._update(true);
}
Expand Down
15 changes: 15 additions & 0 deletions test/unit/style-spec/empty.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {test} from '../../util/test';
import emptyStyle from '../../../src/style-spec/empty';
import validateStyleMin from '../../../src/style-spec/validate_style.min';

test('it generates something', (t) => {
const style = emptyStyle();
t.ok(style);
t.end();
});

test('generated empty style is a valid style', (t) => {
const errors = validateStyleMin(emptyStyle());
t.equal(errors.length, 0);
t.end();
});
17 changes: 17 additions & 0 deletions test/unit/ui/map.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,23 @@ test('Map', (t) => {
});
});

t.test('a layer can be added even if a map is created without a style', (t) => {
const map = createMap(t, {deleteStyle: true});
const layer = {
id: 'background',
type: 'background'
};
map.addLayer(layer);
t.end();
});

t.test('a source can be added even if a map is created without a style', (t) => {
const map = createMap(t, {deleteStyle: true});
const source = createStyleSource();
map.addSource('fill', source);
t.end();
});

t.test('returns the style with added source and layer', (t) => {
const style = createStyle();
const map = createMap(t, {style});
Expand Down
17 changes: 9 additions & 8 deletions test/util/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@ import {extend} from '../../src/util/util';

export function createMap(t, options, callback) {
const container = window.document.createElement('div');

Object.defineProperty(container, 'clientWidth', {value: 200, configurable: true});
Object.defineProperty(container, 'clientHeight', {value: 200, configurable: true});

if (!options || !options.skipCSSStub) t.stub(Map.prototype, '_detectMissingCSS');

const map = new Map(extend({
const defaultOptions = {
container,
interactive: false,
attributionControl: false,
Expand All @@ -20,8 +14,15 @@ export function createMap(t, options, callback) {
"sources": {},
"layers": []
}
}, options));
};

Object.defineProperty(container, 'clientWidth', {value: 200, configurable: true});
Object.defineProperty(container, 'clientHeight', {value: 200, configurable: true});

if (!options || !options.skipCSSStub) t.stub(Map.prototype, '_detectMissingCSS');
if (options && options.deleteStyle) delete defaultOptions.style;

const map = new Map(extend(defaultOptions, options));
if (callback) map.on('load', () => {
callback(null, map);
});
Expand Down

0 comments on commit b61d19b

Please sign in to comment.