diff --git a/spec/suites/SpecHelper.js b/spec/suites/SpecHelper.js index 939a6faaf..1c610e00c 100644 --- a/spec/suites/SpecHelper.js +++ b/spec/suites/SpecHelper.js @@ -16,16 +16,17 @@ expect.Assertion.prototype.nearLatLng = function (expected, delta) { .be.within(expected.lng - delta, expected.lng + delta); }; -happen.at = function (what, x, y, props) { - this.once(document.elementFromPoint(x, y), L.Util.extend({ +happen.at = function (what, x, y, props = {}) { + this.once(document.elementFromPoint(x, y), { type: what, clientX: x, clientY: y, screenX: x, screenY: y, which: 1, - button: 0 - }, props || {})); + button: 0, + ...props + }); }; happen.makeEvent = (function (makeEvent) { diff --git a/spec/suites/core/UtilSpec.js b/spec/suites/core/UtilSpec.js index b73678c5a..394c08823 100644 --- a/spec/suites/core/UtilSpec.js +++ b/spec/suites/core/UtilSpec.js @@ -1,38 +1,4 @@ describe('Util', () => { - describe('#extend', () => { - let a; - - beforeEach(() => { - a = { - foo: 5, - bar: 'asd' - }; - }); - - it('extends the first argument with the properties of the second', () => { - L.Util.extend(a, { - bar: 7, - baz: 3 - }); - - expect(a).to.eql({ - foo: 5, - bar: 7, - baz: 3 - }); - }); - - it('accepts more than 2 arguments', () => { - L.Util.extend(a, {bar: 7}, {baz: 3}); - - expect(a).to.eql({ - foo: 5, - bar: 7, - baz: 3 - }); - }); - }); - describe('#stamp', () => { it('sets a unique id on the given object and returns it', () => { const a = {}, diff --git a/spec/suites/dom/DomEvent.DoubleTapSpec.js b/spec/suites/dom/DomEvent.DoubleTapSpec.js index f6efbffef..02be5b920 100644 --- a/spec/suites/dom/DomEvent.DoubleTapSpec.js +++ b/spec/suites/dom/DomEvent.DoubleTapSpec.js @@ -76,7 +76,7 @@ describe('DomEvent.DoubleTapSpec.js', () => { happen.click(container, click); const event = spy.lastCall.args[0]; - const expectedProps = L.extend(click, { + const expectedProps = Object.assign(click, { type: 'dblclick', // bubbles: true, // not important, as we do not actually dispatch the event // cancelable: true, // diff --git a/spec/suites/dom/DomEvent.PointerSpec.js b/spec/suites/dom/DomEvent.PointerSpec.js index c3fe8d23d..81bbae470 100644 --- a/spec/suites/dom/DomEvent.PointerSpec.js +++ b/spec/suites/dom/DomEvent.PointerSpec.js @@ -99,7 +99,7 @@ describe('DomEvent.Pointer', () => { // pointerdown/touchstart const pointer1 = {clientX:1, clientY:1, pointerId: 1}; - happen.once(el, L.extend({type: 'pointerdown'}, pointer1)); + happen.once(el, {type: 'pointerdown', ...pointer1})); let evt = listeners.touchstart.lastCall.args[0]; expect(evt.type).to.be('pointerdown'); expect(evt).to.have.keys('touches', 'changedTouches'); @@ -110,7 +110,7 @@ describe('DomEvent.Pointer', () => { // another pointerdown/touchstart (multitouch) const pointer2 = {clientX:2, clientY:2, pointerId: 2}; - happen.once(el, L.extend({type: 'pointerdown'}, pointer2)); + happen.once(el, {type: 'pointerdown', ...pointer2}); evt = listeners.touchstart.lastCall.args[0]; expect(evt.type).to.be('pointerdown'); expect(evt).to.have.keys('touches', 'changedTouches'); @@ -120,8 +120,8 @@ describe('DomEvent.Pointer', () => { expect(containIn([pointer1, pointer2], evt.touches)).to.be.ok(); // pointermove/touchmove (multitouch) - L.extend(pointer1, {clientX:11, clientY:11}); - happen.once(el, L.extend({type: 'pointermove'}, pointer1)); + Object.assign(pointer1, {clientX:11, clientY:11}); + happen.once(el, {type: 'pointermove', ...pointer1}); evt = listeners.touchmove.lastCall.args[0]; expect(evt.type).to.be('pointermove'); expect(evt).to.have.keys('touches', 'changedTouches'); @@ -131,7 +131,7 @@ describe('DomEvent.Pointer', () => { expect(containIn([pointer1, pointer2], evt.touches)).to.be.ok(); // pointerup/touchend (multitouch) - happen.once(el, L.extend({type: 'pointerup'}, pointer2)); + happen.once(el, {type: 'pointerup', ...pointer2}); evt = listeners.touchend.lastCall.args[0]; expect(evt.type).to.be('pointerup'); expect(evt).to.have.keys('touches', 'changedTouches'); @@ -141,7 +141,7 @@ describe('DomEvent.Pointer', () => { expect(containIn(pointer1, evt.touches[0])).to.be.ok(); // pointercancel/touchcancel - happen.once(el, L.extend({type: 'pointercancel'}, pointer1)); + happen.once(el, {type: 'pointercancel', ...pointer1}); evt = listeners.touchcancel.lastCall.args[0]; expect(evt.type).to.be('pointercancel'); expect(evt).to.have.keys('touches', 'changedTouches'); diff --git a/src/core/Class.js b/src/core/Class.js index 01c060be9..6a2a30498 100644 --- a/src/core/Class.js +++ b/src/core/Class.js @@ -44,23 +44,23 @@ Class.extend = function (props) { // mix static properties into the class if (props.statics) { - Util.extend(NewClass, props.statics); + Object.assign(NewClass, props.statics); } // mix includes into the prototype if (props.includes) { - Util.extend.apply(null, [proto].concat(props.includes)); + Object.assign(proto, ...props.includes); } // mix given properties into the prototype - Util.extend(proto, props); + Object.assign(proto, props); delete proto.statics; delete proto.includes; // merge options if (proto.options) { proto.options = parentProto.options ? Util.create(parentProto.options) : {}; - Util.extend(proto.options, props.options); + Object.assign(proto.options, props.options); } proto._initHooks = []; @@ -89,7 +89,7 @@ Class.extend = function (props) { // [Includes a mixin](#class-includes) into the current class. Class.include = function (props) { const parentOptions = this.prototype.options; - Util.extend(this.prototype, props); + Object.assign(this.prototype, props); if (props.options) { this.prototype.options = parentOptions; this.mergeOptions(props.options); @@ -100,7 +100,7 @@ Class.include = function (props) { // @function mergeOptions(options: Object): this // [Merges `options`](#class-options) into the defaults of the class. Class.mergeOptions = function (options) { - Util.extend(this.prototype.options, options); + Object.assign(this.prototype.options, options); return this; }; diff --git a/src/core/Events.js b/src/core/Events.js index 7366aa504..04e76a392 100644 --- a/src/core/Events.js +++ b/src/core/Events.js @@ -175,11 +175,12 @@ export const Events = { fire(type, data, propagate) { if (!this.listens(type, propagate)) { return this; } - const event = Util.extend({}, data, { + const event = { + ...data, type, target: this, sourceTarget: data && data.sourceTarget || this - }); + }; if (this._events) { const listeners = this._events[type]; @@ -308,10 +309,11 @@ export const Events = { _propagateEvent(e) { for (const id in this._eventParents) { - this._eventParents[id].fire(e.type, Util.extend({ + this._eventParents[id].fire(e.type, { layer: e.target, - propagatedFrom: e.target - }, e), true); + propagatedFrom: e.target, + ...e + }, true); } } }; diff --git a/src/core/Util.js b/src/core/Util.js index 5e03d5f00..8df5cb374 100644 --- a/src/core/Util.js +++ b/src/core/Util.js @@ -4,20 +4,6 @@ * Various utility functions, used by Leaflet internally. */ -// @function extend(dest: Object, src?: Object): Object -// Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut. -export function extend(dest, ...args) { - let i, j, len, src; - - for (j = 0, len = args.length; j < len; j++) { - src = args[j]; - for (i in src) { - dest[i] = src[i]; - } - } - return dest; -} - // @function create(proto: Object, properties?: Object): Object // Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create) export const create = Object.create || (function () { diff --git a/src/core/index.js b/src/core/index.js index d493c37cd..c8407b652 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -5,4 +5,4 @@ export {Handler} from './Handler'; import * as Util from './Util'; export {Util}; -export {extend, stamp, setOptions} from './Util'; +export {stamp, setOptions} from './Util'; diff --git a/src/geo/crs/CRS.EPSG3395.js b/src/geo/crs/CRS.EPSG3395.js index 595625d86..1537af560 100644 --- a/src/geo/crs/CRS.EPSG3395.js +++ b/src/geo/crs/CRS.EPSG3395.js @@ -1,7 +1,6 @@ import {Earth} from './CRS.Earth'; import {Mercator} from '../projection/Projection.Mercator'; import {toTransformation} from '../../geometry/Transformation'; -import * as Util from '../../core/Util'; /* * @namespace CRS @@ -9,7 +8,8 @@ import * as Util from '../../core/Util'; * * Rarely used by some commercial tile providers. Uses Elliptical Mercator projection. */ -export const EPSG3395 = Util.extend({}, Earth, { +export const EPSG3395 = { + ...Earth, code: 'EPSG:3395', projection: Mercator, @@ -17,4 +17,4 @@ export const EPSG3395 = Util.extend({}, Earth, { const scale = 0.5 / (Math.PI * Mercator.R); return toTransformation(scale, 0.5, -scale, 0.5); }()) -}); +}; diff --git a/src/geo/crs/CRS.EPSG3857.js b/src/geo/crs/CRS.EPSG3857.js index 0b6a7aaca..9905dee05 100644 --- a/src/geo/crs/CRS.EPSG3857.js +++ b/src/geo/crs/CRS.EPSG3857.js @@ -1,7 +1,6 @@ import {Earth} from './CRS.Earth'; import {SphericalMercator} from '../projection/Projection.SphericalMercator'; import {toTransformation} from '../../geometry/Transformation'; -import * as Util from '../../core/Util'; /* * @namespace CRS @@ -12,7 +11,8 @@ import * as Util from '../../core/Util'; * Map's `crs` option. */ -export const EPSG3857 = Util.extend({}, Earth, { +export const EPSG3857 = { + ...Earth, code: 'EPSG:3857', projection: SphericalMercator, @@ -20,8 +20,9 @@ export const EPSG3857 = Util.extend({}, Earth, { const scale = 0.5 / (Math.PI * SphericalMercator.R); return toTransformation(scale, 0.5, -scale, 0.5); }()) -}); +}; -export const EPSG900913 = Util.extend({}, EPSG3857, { +export const EPSG900913 = { + ...EPSG3857, code: 'EPSG:900913' -}); +}; diff --git a/src/geo/crs/CRS.EPSG4326.js b/src/geo/crs/CRS.EPSG4326.js index 5922791c7..57a77aaf7 100644 --- a/src/geo/crs/CRS.EPSG4326.js +++ b/src/geo/crs/CRS.EPSG4326.js @@ -1,7 +1,6 @@ import {Earth} from './CRS.Earth'; import {LonLat} from '../projection/Projection.LonLat'; import {toTransformation} from '../../geometry/Transformation'; -import * as Util from '../../core/Util'; /* * @namespace CRS @@ -16,8 +15,9 @@ import * as Util from '../../core/Util'; * or (-180,-90) for `TileLayer`s with [the `tms` option](#tilelayer-tms) set. */ -export const EPSG4326 = Util.extend({}, Earth, { +export const EPSG4326 = { + ...Earth, code: 'EPSG:4326', projection: LonLat, transformation: toTransformation(1 / 180, 1, -1 / 180, 0.5) -}); +}; diff --git a/src/geo/crs/CRS.Earth.js b/src/geo/crs/CRS.Earth.js index 8af0f3932..cf937c654 100755 --- a/src/geo/crs/CRS.Earth.js +++ b/src/geo/crs/CRS.Earth.js @@ -1,5 +1,4 @@ import {CRS} from './CRS'; -import * as Util from '../../core/Util'; /* * @namespace CRS @@ -11,7 +10,8 @@ import * as Util from '../../core/Util'; * meters. */ -export const Earth = Util.extend({}, CRS, { +export const Earth = { + ...CRS, wrapLng: [-180, 180], // Mean Earth Radius, as recommended for use by @@ -30,4 +30,4 @@ export const Earth = Util.extend({}, CRS, { c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return this.R * c; } -}); +}; diff --git a/src/geo/crs/CRS.Simple.js b/src/geo/crs/CRS.Simple.js index 61818b016..43043abfa 100644 --- a/src/geo/crs/CRS.Simple.js +++ b/src/geo/crs/CRS.Simple.js @@ -1,7 +1,6 @@ import {CRS} from './CRS'; import {LonLat} from '../projection/Projection.LonLat'; import {toTransformation} from '../../geometry/Transformation'; -import * as Util from '../../core/Util'; /* * @namespace CRS @@ -13,7 +12,8 @@ import * as Util from '../../core/Util'; * simple euclidean distance. */ -export const Simple = Util.extend({}, CRS, { +export const Simple = { + ...CRS, projection: LonLat, transformation: toTransformation(1, 0, -1, 0), @@ -33,4 +33,4 @@ export const Simple = Util.extend({}, CRS, { }, infinite: true -}); +}; diff --git a/src/layer/GeoJSON.js b/src/layer/GeoJSON.js index cb3ffa364..0570891ac 100644 --- a/src/layer/GeoJSON.js +++ b/src/layer/GeoJSON.js @@ -138,7 +138,7 @@ export const GeoJSON = FeatureGroup.extend({ return this.eachLayer(this.resetStyle, this); } // reset any custom styles - layer.options = Util.extend({}, layer.defaultOptions); + layer.options = {...layer.defaultOptions}; this._setLayerStyle(layer, this.options.style); return this; }, @@ -296,7 +296,7 @@ export function latLngsToCoords(latlngs, levelsDeep, closed, precision) { export function getFeature(layer, newGeometry) { return layer.feature ? - Util.extend({}, layer.feature, {geometry: newGeometry}) : + {...layer.feature, geometry: newGeometry} : asFeature(newGeometry); } diff --git a/src/layer/tile/TileLayer.WMS.js b/src/layer/tile/TileLayer.WMS.js index 770684da6..f345866e3 100644 --- a/src/layer/tile/TileLayer.WMS.js +++ b/src/layer/tile/TileLayer.WMS.js @@ -1,5 +1,5 @@ import {TileLayer} from './TileLayer'; -import {extend, setOptions, getParamString} from '../../core/Util'; +import {setOptions, getParamString} from '../../core/Util'; import Browser from '../../core/Browser'; import {EPSG4326} from '../../geo/crs/CRS.EPSG4326'; import {toBounds} from '../../geometry/Bounds'; @@ -69,7 +69,7 @@ export const TileLayerWMS = TileLayer.extend({ this._url = url; - const wmsParams = extend({}, this.defaultWmsParams); + const wmsParams = {...this.defaultWmsParams}; // all keys that are not TileLayer options go to WMS params for (const i in options) { @@ -119,7 +119,7 @@ export const TileLayerWMS = TileLayer.extend({ // Merges an object with the new parameters and re-requests tiles on the current screen (unless `noRedraw` was set to true). setParams(params, noRedraw) { - extend(this.wmsParams, params); + Object.assign(this.wmsParams, params); if (!noRedraw) { this.redraw(); diff --git a/src/layer/tile/TileLayer.js b/src/layer/tile/TileLayer.js index 5cda7ce3c..be4f59435 100644 --- a/src/layer/tile/TileLayer.js +++ b/src/layer/tile/TileLayer.js @@ -193,7 +193,7 @@ export const TileLayer = GridLayer.extend({ data['-y'] = invertedY; } - return Util.template(this._url, Util.extend(data, this.options)); + return Util.template(this._url, Object.assign(data, this.options)); }, _tileOnLoad(done, tile) { diff --git a/src/layer/vector/Circle.js b/src/layer/vector/Circle.js index ca5f5715d..3cdb61209 100644 --- a/src/layer/vector/Circle.js +++ b/src/layer/vector/Circle.js @@ -27,7 +27,7 @@ export const Circle = CircleMarker.extend({ initialize(latlng, options, legacyOptions) { if (typeof options === 'number') { // Backwards compatibility with 0.7.x factory (latlng, radius, options?) - options = Util.extend({}, legacyOptions, {radius: options}); + options = {...legacyOptions, radius: options}; } Util.setOptions(this, options); this._latlng = toLatLng(latlng); diff --git a/src/map/Map.js b/src/map/Map.js index f9f1c7ae8..7f1f21720 100644 --- a/src/map/Map.js +++ b/src/map/Map.js @@ -182,8 +182,8 @@ export const Map = Evented.extend({ if (this._loaded && !options.reset && options !== true) { if (options.animate !== undefined) { - options.zoom = Util.extend({animate: options.animate}, options.zoom); - options.pan = Util.extend({animate: options.animate, duration: options.duration}, options.pan); + options.zoom = {animate: options.animate, ...options.zoom}; + options.pan = {animate: options.animate, duration: options.duration, ...options.pan}; } // try animating pan or zoom @@ -553,7 +553,7 @@ export const Map = Evented.extend({ invalidateSize(options) { if (!this._loaded) { return this; } - options = Util.extend({ + options = Object.assign({ animate: false, pan: true }, options === true ? {animate: true} : options); @@ -618,14 +618,15 @@ export const Map = Evented.extend({ // See `Locate options` for more details. locate(options) { - options = this._locateOptions = Util.extend({ + options = this._locateOptions = { timeout: 10000, - watch: false + watch: false, // setView: false // maxZoom: // maximumAge: 0 // enableHighAccuracy: false - }, options); + ...options + }; if (!('geolocation' in navigator)) { this._handleGeolocationError({ @@ -1413,7 +1414,7 @@ export const Map = Evented.extend({ // Fired before mouse click on the map (sometimes useful when you // want something to happen on click before any existing click // handlers start running). - const synth = Util.extend({}, e); + const synth = {...e}; synth.type = 'preclick'; this._fireDOMEvent(synth, synth.type, canvasTargets); }