From 9b9521b468e5cfcb88945e1ac32d00b828a45877 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Fri, 8 Nov 2024 15:04:19 -0500 Subject: [PATCH] perf: Stop using jquery extend Pure javascript is faster --- src/annotation/annotation.js | 35 ++++++++-------- src/annotation/circleAnnotation.js | 6 +-- src/annotation/ellipseAnnotation.js | 8 ++-- src/annotation/lineAnnotation.js | 6 +-- src/annotation/pointAnnotation.js | 7 ++-- src/annotation/polygonAnnotation.js | 5 +-- src/annotation/rectangleAnnotation.js | 16 ++++---- src/annotation/squareAnnotation.js | 6 +-- src/annotationLayer.js | 8 ++-- src/choroplethFeature.js | 5 +-- src/contourFeature.js | 5 +-- src/feature.js | 4 +- src/graphFeature.js | 6 +-- src/gridFeature.js | 5 +-- src/heatmapFeature.js | 3 +- src/index.js | 2 +- src/isolineFeature.js | 7 ++-- src/layer.js | 2 +- src/lineFeature.js | 4 +- src/map.js | 22 +++++------ src/mapInteractor.js | 27 ++++++------- src/markerFeature.js | 6 +-- src/meshFeature.js | 5 +-- src/osmLayer.js | 9 ++--- src/pathFeature.js | 3 +- src/pixelmapFeature.js | 2 +- src/pixelmapLayer.js | 7 ++-- src/pointFeature.js | 6 +-- src/polygonFeature.js | 3 +- src/quadFeature.js | 2 +- src/registry.js | 57 ++++++++++++++------------- src/svg/pathFeature.js | 3 +- src/textFeature.js | 4 +- src/tileLayer.js | 9 +++-- src/trackFeature.js | 21 ++++------ src/ui/scaleWidget.js | 6 +-- src/ui/widget.js | 3 +- src/util/clustering.js | 2 +- src/util/common.js | 39 +++++++++++++++++- src/util/mesh.js | 7 ++-- src/util/mockVGL.js | 3 +- src/vectorFeature.js | 4 +- 42 files changed, 197 insertions(+), 193 deletions(-) diff --git a/src/annotation/annotation.js b/src/annotation/annotation.js index 28f30d6f1e..995139800f 100644 --- a/src/annotation/annotation.js +++ b/src/annotation/annotation.js @@ -1,4 +1,3 @@ -var $ = require('jquery'); var geo_event = require('../event'); var geo_action = require('../action'); var transform = require('../transform'); @@ -101,7 +100,7 @@ var annotation = function (type, args) { } var m_this = this, - m_options = $.extend(true, {}, this.constructor.defaults, args || {}), + m_options = util.deepMerge({}, this.constructor.defaults, args || {}), m_id = m_options.annotationId; delete m_options.annotationId; if (m_id === undefined || (m_options.layer && m_options.layer.annotationById(m_id))) { @@ -526,14 +525,14 @@ var annotation = function (type, args) { var coordinatesSet; if (arg2 === undefined) { coordinatesSet = arg1[m_this._coordinateOption] !== undefined; - m_options = $.extend(true, m_options, arg1); + m_options = util.deepMerge(m_options, arg1); /* For style objects, re-extend them without recursion. This allows * setting colors without an opacity field, for instance. */ ['style', 'createStyle', 'editStyle', 'editHandleStyle', 'labelStyle', 'highlightStyle', 'cursorStyle' ].forEach(function (key) { if (arg1[key] !== undefined) { - $.extend(m_options[key], arg1[key]); + Object.assign(m_options[key], arg1[key]); } }); } else { @@ -596,7 +595,7 @@ var annotation = function (type, args) { m_options[styleType] = {}; } if (arg2 === undefined) { - m_options[styleType] = $.extend(true, m_options[styleType], arg1); + m_options[styleType] = util.deepMerge(m_options[styleType], arg1); } else { m_options[styleType][arg1] = arg2; } @@ -659,15 +658,15 @@ var annotation = function (type, args) { /* for some states, fall back to the general style if they don't specify a * value explicitly. */ if (state === annotationState.edit || state === annotationState.highlight) { - return $.extend({}, m_options.style, m_options[state + 'Style']); + return Object.assign({}, m_options.style, m_options[state + 'Style']); } if (state === annotationState.create) { - return $.extend({}, m_options.style, m_options.editStyle, - m_options[state + 'Style']); + return Object.assign({}, m_options.style, m_options.editStyle, + m_options[state + 'Style']); } if (state === annotationState.cursor) { - return $.extend({}, m_options.style, m_options.editStyle, - m_options.createStyle, m_options[state + 'Style']); + return Object.assign({}, m_options.style, m_options.editStyle, + m_options.createStyle, m_options[state + 'Style']); } return m_options[state + 'Style'] || m_options.style || {}; }; @@ -925,7 +924,7 @@ var annotation = function (type, args) { */ this._addEditHandles = function (features, vertices, opts, isOpen) { var editPoints, - style = $.extend({}, defaultEditHandleStyle, m_this.editHandleStyle()), + style = Object.assign({}, defaultEditHandleStyle, m_this.editHandleStyle()), handles = util.ensureFunction(style.handles)() || {}, selected = ( m_this._editHandle && m_this._editHandle.handle && @@ -933,7 +932,7 @@ var annotation = function (type, args) { m_this._editHandle.handle : undefined); /* opts specify which handles are allowed. They must be allowed by the * original opts object and by the editHandleStyle.handle object. */ - opts = $.extend({}, opts); + opts = Object.assign({}, opts); Object.keys(handles).forEach(function (key) { if (handles[key] === false) { opts[key] = false; @@ -947,16 +946,16 @@ var annotation = function (type, args) { vertexList.forEach((vert, vidx) => { vert.forEach(function (pt, idx) { if (opts.vertex !== false) { - editPoints.push($.extend({}, pt, {type: 'vertex', index: idx, vindex: vidx, style: style, editHandle: true})); + editPoints.push(Object.assign({}, pt, {type: 'vertex', index: idx, vindex: vidx, style: style, editHandle: true})); } if (opts.edge !== false && idx !== vert.length - 1 && (pt.x !== vert[idx + 1].x || pt.y !== vert[idx + 1].y)) { - editPoints.push($.extend({ + editPoints.push(Object.assign({ x: (pt.x + vert[idx + 1].x) / 2, y: (pt.y + vert[idx + 1].y) / 2 }, {type: 'edge', index: idx, vindex: vidx, style: style, editHandle: true})); } if (opts.edge !== false && !isOpen && idx === vert.length - 1 && (pt.x !== vert[0].x || pt.y !== vert[0].y)) { - editPoints.push($.extend({ + editPoints.push(Object.assign({ x: (pt.x + vert[0].x) / 2, y: (pt.y + vert[0].y) / 2 }, {type: 'edge', index: idx, vindex: vidx, style: style, editHandle: true})); @@ -964,10 +963,10 @@ var annotation = function (type, args) { }); }); if (opts.center !== false) { - editPoints.push($.extend({}, util.centerFromPerimeter(m_this._coordinates()), {type: 'center', style: style, editHandle: true})); + editPoints.push(Object.assign({}, util.centerFromPerimeter(m_this._coordinates()), {type: 'center', style: style, editHandle: true})); } if (opts.rotate !== false) { - editPoints.push($.extend(m_this._rotateHandlePosition( + editPoints.push(Object.assign(m_this._rotateHandlePosition( style.rotateHandleOffset, style.rotateHandleRotation + (selected && selected.type === 'rotate' ? m_this._editHandle.amountRotated : 0) ), {type: 'rotate', style: style, editHandle: true})); @@ -976,7 +975,7 @@ var annotation = function (type, args) { } } if (opts.resize !== false) { - editPoints.push($.extend(m_this._rotateHandlePosition( + editPoints.push(Object.assign(m_this._rotateHandlePosition( style.resizeHandleOffset, style.resizeHandleRotation ), {type: 'resize', style: style, editHandle: true})); diff --git a/src/annotation/circleAnnotation.js b/src/annotation/circleAnnotation.js index ad7956623c..a6d891754b 100644 --- a/src/annotation/circleAnnotation.js +++ b/src/annotation/circleAnnotation.js @@ -1,7 +1,7 @@ -const $ = require('jquery'); const inherit = require('../inherit'); const registerAnnotation = require('../registry').registerAnnotation; const markerFeature = require('../markerFeature'); +const util = require('../util'); const ellipseAnnotation = require('./ellipseAnnotation'); @@ -22,7 +22,7 @@ var circleAnnotation = function (args, annotationName) { if (!(this instanceof circleAnnotation)) { return new circleAnnotation(args, annotationName); } - args = $.extend(true, {}, this.constructor.defaults, args, {constraint: 1}); + args = util.deepMerge({}, this.constructor.defaults, args, {constraint: 1}); ellipseAnnotation.call(this, args, annotationName || 'circle'); }; inherit(circleAnnotation, ellipseAnnotation); @@ -30,7 +30,7 @@ inherit(circleAnnotation, ellipseAnnotation); /** * This object contains the default options to initialize the class. */ -circleAnnotation.defaults = $.extend({}, ellipseAnnotation.defaults, { +circleAnnotation.defaults = Object.assign({}, ellipseAnnotation.defaults, { }); var circleRequiredFeatures = {}; diff --git a/src/annotation/ellipseAnnotation.js b/src/annotation/ellipseAnnotation.js index 425097911b..6903e5147d 100644 --- a/src/annotation/ellipseAnnotation.js +++ b/src/annotation/ellipseAnnotation.js @@ -1,7 +1,7 @@ -const $ = require('jquery'); const inherit = require('../inherit'); const registerAnnotation = require('../registry').registerAnnotation; const markerFeature = require('../markerFeature'); +const util = require('../util'); const annotationState = require('./annotation').state; const rectangleAnnotation = require('./rectangleAnnotation'); @@ -23,7 +23,7 @@ var ellipseAnnotation = function (args, annotationName) { if (!(this instanceof ellipseAnnotation)) { return new ellipseAnnotation(args, annotationName); } - args = $.extend(true, {}, this.constructor.defaults, args); + args = util.deepMerge({}, this.constructor.defaults, args); rectangleAnnotation.call(this, args, annotationName || 'ellipse'); var m_this = this; @@ -49,7 +49,7 @@ var ellipseAnnotation = function (args, annotationName) { marker: { x: (opt.corners[0].x + opt.corners[1].x + opt.corners[2].x + opt.corners[3].x) / 4, y: (opt.corners[0].y + opt.corners[1].y + opt.corners[2].y + opt.corners[3].y) / 4, - style: $.extend( + style: Object.assign( {}, style, { radius: radius, @@ -120,7 +120,7 @@ inherit(ellipseAnnotation, rectangleAnnotation); /** * This object contains the default options to initialize the class. */ -ellipseAnnotation.defaults = $.extend({}, rectangleAnnotation.defaults, { +ellipseAnnotation.defaults = Object.assign({}, rectangleAnnotation.defaults, { }); var ellipseRequiredFeatures = {}; diff --git a/src/annotation/lineAnnotation.js b/src/annotation/lineAnnotation.js index d0a6eeec09..424f574761 100644 --- a/src/annotation/lineAnnotation.js +++ b/src/annotation/lineAnnotation.js @@ -1,7 +1,7 @@ -const $ = require('jquery'); const inherit = require('../inherit'); const registerAnnotation = require('../registry').registerAnnotation; const lineFeature = require('../lineFeature'); +const util = require('../util'); const annotation = require('./annotation').annotation; const annotationState = require('./annotation').state; @@ -37,7 +37,7 @@ var lineAnnotation = function (args) { if (!(this instanceof lineAnnotation)) { return new lineAnnotation(args); } - args = $.extend(true, {}, this.constructor.defaults, { + args = util.deepMerge({}, this.constructor.defaults, { style: { line: function (d) { /* Return an array that has the same number of items as we have @@ -324,7 +324,7 @@ inherit(lineAnnotation, annotation); /** * This object contains the default options to initialize the class. */ -lineAnnotation.defaults = $.extend({}, annotation.defaults, { +lineAnnotation.defaults = Object.assign({}, annotation.defaults, { style: { strokeColor: {r: 0, g: 0, b: 0}, strokeOpacity: 1, diff --git a/src/annotation/pointAnnotation.js b/src/annotation/pointAnnotation.js index f51d93d20c..3a81f238e7 100644 --- a/src/annotation/pointAnnotation.js +++ b/src/annotation/pointAnnotation.js @@ -1,4 +1,3 @@ -const $ = require('jquery'); const inherit = require('../inherit'); const util = require('../util'); const registerAnnotation = require('../registry').registerAnnotation; @@ -40,7 +39,7 @@ var pointAnnotation = function (args) { return new pointAnnotation(args); } - args = $.extend(true, {}, this.constructor.defaults, args); + args = util.deepMerge({}, this.constructor.defaults, args); args.position = args.position || (args.coordinates ? args.coordinates[0] : undefined); delete args.coordinates; annotation.call(this, 'point', args); @@ -66,7 +65,7 @@ var pointAnnotation = function (args) { if (opt.style.scaled === true) { opt.style.scaled = m_this.layer().map().zoom(); } - style = $.extend({}, style, { + style = Object.assign({}, style, { radius: function () { var radius = opt.style.radius, zoom = m_this.layer().map().zoom(); @@ -182,7 +181,7 @@ inherit(pointAnnotation, annotation); /** * This object contains the default options to initialize the class. */ -pointAnnotation.defaults = $.extend({}, annotation.defaults, { +pointAnnotation.defaults = Object.assign({}, annotation.defaults, { style: { fill: true, fillColor: {r: 0, g: 1, b: 0}, diff --git a/src/annotation/polygonAnnotation.js b/src/annotation/polygonAnnotation.js index 28513c8bc4..0e8df9947e 100644 --- a/src/annotation/polygonAnnotation.js +++ b/src/annotation/polygonAnnotation.js @@ -1,4 +1,3 @@ -const $ = require('jquery'); const inherit = require('../inherit'); const registerAnnotation = require('../registry').registerAnnotation; const lineFeature = require('../lineFeature'); @@ -44,7 +43,7 @@ var polygonAnnotation = function (args) { return new polygonAnnotation(args); } - args = $.extend(true, {}, this.constructor.defaults, { + args = util.deepMerge({}, this.constructor.defaults, { style: { polygon: function (d) { return d.polygon; } }, @@ -354,7 +353,7 @@ inherit(polygonAnnotation, annotation); /** * This object contains the default options to initialize the class. */ -polygonAnnotation.defaults = $.extend({}, annotation.defaults, { +polygonAnnotation.defaults = Object.assign({}, annotation.defaults, { style: { fill: true, fillColor: {r: 0, g: 1, b: 0}, diff --git a/src/annotation/rectangleAnnotation.js b/src/annotation/rectangleAnnotation.js index fb3b50385d..a15997a44c 100644 --- a/src/annotation/rectangleAnnotation.js +++ b/src/annotation/rectangleAnnotation.js @@ -1,9 +1,9 @@ -const $ = require('jquery'); const inherit = require('../inherit'); const geo_event = require('../event'); const geo_action = require('../action'); const registerAnnotation = require('../registry').registerAnnotation; const polygonFeature = require('../polygonFeature'); +const util = require('../util'); const annotation = require('./annotation').annotation; const annotationState = require('./annotation').state; @@ -48,7 +48,7 @@ var rectangleAnnotation = function (args, annotationName) { return new rectangleAnnotation(args, annotationName); } - args = $.extend(true, {}, this.constructor.defaults, args); + args = util.deepMerge({}, this.constructor.defaults, args); args.corners = args.corners || args.coordinates || []; delete args.coordinates; annotation.call(this, annotationName || 'rectangle', args); @@ -230,7 +230,7 @@ var rectangleAnnotation = function (args, annotationName) { c2 = map.gcsToDisplay(evt.mapgcs, null), c1 = {x: c2.x, y: c0.y}, c3 = {x: c0.x, y: c2.y}; - corners[2] = $.extend({}, evt.mapgcs); + corners[2] = Object.assign({}, evt.mapgcs); corners[1] = map.displayToGcs(c1, null); corners[3] = map.displayToGcs(c3, null); if (this._selectionConstraint) { @@ -290,10 +290,10 @@ var rectangleAnnotation = function (args, annotationName) { return 'done'; } if (evt.buttonsDown.left) { - corners.push($.extend({}, evt.mapgcs)); - corners.push($.extend({}, evt.mapgcs)); - corners.push($.extend({}, evt.mapgcs)); - corners.push($.extend({}, evt.mapgcs)); + corners.push(Object.assign({}, evt.mapgcs)); + corners.push(Object.assign({}, evt.mapgcs)); + corners.push(Object.assign({}, evt.mapgcs)); + corners.push(Object.assign({}, evt.mapgcs)); return true; } }; @@ -388,7 +388,7 @@ inherit(rectangleAnnotation, annotation); /** * This object contains the default options to initialize the class. */ -rectangleAnnotation.defaults = $.extend({}, annotation.defaults, { +rectangleAnnotation.defaults = Object.assign({}, annotation.defaults, { style: { fill: true, fillColor: {r: 0, g: 1, b: 0}, diff --git a/src/annotation/squareAnnotation.js b/src/annotation/squareAnnotation.js index cddb7cf409..20afd38bf2 100644 --- a/src/annotation/squareAnnotation.js +++ b/src/annotation/squareAnnotation.js @@ -1,7 +1,7 @@ -const $ = require('jquery'); const inherit = require('../inherit'); const registerAnnotation = require('../registry').registerAnnotation; const polygonFeature = require('../polygonFeature'); +const util = require('../util'); const rectangleAnnotation = require('./rectangleAnnotation'); @@ -22,7 +22,7 @@ var squareAnnotation = function (args, annotationName) { if (!(this instanceof squareAnnotation)) { return new squareAnnotation(args, annotationName); } - args = $.extend(true, {}, this.constructor.defaults, args, {constraint: 1}); + args = util.deepMerge({}, this.constructor.defaults, args, {constraint: 1}); rectangleAnnotation.call(this, args, annotationName || 'square'); }; inherit(squareAnnotation, rectangleAnnotation); @@ -30,7 +30,7 @@ inherit(squareAnnotation, rectangleAnnotation); /** * This object contains the default options to initialize the class. */ -squareAnnotation.defaults = $.extend({}, rectangleAnnotation.defaults, { +squareAnnotation.defaults = Object.assign({}, rectangleAnnotation.defaults, { }); var squareRequiredFeatures = {}; diff --git a/src/annotationLayer.js b/src/annotationLayer.js index 6b6def83da..314e8d47d9 100644 --- a/src/annotationLayer.js +++ b/src/annotationLayer.js @@ -140,7 +140,7 @@ var annotationLayer = function (arg) { }; }); - m_options = $.extend(true, {}, { + m_options = util.deepMerge({}, { dblClickTime: 300, adjacentPointProximity: 5, // in pixels, 0 is exact // in pixels; set to continuousPointProximity to false to disable @@ -445,7 +445,7 @@ var annotationLayer = function (arg) { return m_options[arg1]; } if (arg2 === undefined) { - m_options = $.extend(true, m_options, arg1); + m_options = util.deepMerge(m_options, arg1); } else { m_options[arg1] = arg2; } @@ -696,7 +696,7 @@ var annotationLayer = function (arg) { m_this.map().interactor().removeAction( undefined, undefined, geo_annotation.actionOwner); if (createAnnotation) { - options = $.extend({}, options || {}, { + options = Object.assign({}, options || {}, { state: geo_annotation.state.create, layer: m_this }); @@ -812,7 +812,7 @@ var annotationLayer = function (arg) { gcs === undefined ? map.ingcs() : gcs)); $.each(dataList, function (data_idx, data) { var type = (data.properties || {}).annotationType || feature.featureType, - options = $.extend({}, data.properties || {}), + options = Object.assign({}, data.properties || {}), position, datagcs, i, existing; if ($.inArray(type, annotationList) < 0) { return; diff --git a/src/choroplethFeature.js b/src/choroplethFeature.js index 16750d13c3..331d23cd8f 100644 --- a/src/choroplethFeature.js +++ b/src/choroplethFeature.js @@ -34,7 +34,6 @@ var choroplethFeature = function (arg) { arg = arg || {}; feature.call(this, arg); - var $ = require('jquery'); var ensureFunction = require('./util').ensureFunction; delete arg.layer; @@ -45,7 +44,7 @@ var choroplethFeature = function (arg) { var d3 = require('./svg/svgRenderer').d3, m_this = this, s_init = this._init, - m_choropleth = $.extend( + m_choropleth = Object.assign( {}, { colorRange: [ @@ -142,7 +141,7 @@ var choroplethFeature = function (arg) { return m_choropleth[arg1]; } if (arg2 === undefined) { - choropleth = $.extend( + choropleth = Object.assign( {}, m_choropleth, arg1 diff --git a/src/contourFeature.js b/src/contourFeature.js index faf015313e..bb92f50aec 100644 --- a/src/contourFeature.js +++ b/src/contourFeature.js @@ -94,7 +94,6 @@ var contourFeature = function (arg) { return new contourFeature(arg); } - var $ = require('jquery'); var util = require('./util'); var meshUtil = require('./util/mesh'); @@ -129,7 +128,7 @@ var contourFeature = function (arg) { this._init = function (arg) { s_init.call(m_this, arg); - var defaultStyle = $.extend( + var defaultStyle = Object.assign( {}, { opacity: 1.0, @@ -144,7 +143,7 @@ var contourFeature = function (arg) { m_this.style(defaultStyle); - m_this.contour($.extend({}, { + m_this.contour(Object.assign({}, { minColor: 'black', minOpacity: 0, maxColor: 'black', diff --git a/src/feature.js b/src/feature.js index b9f9212442..fdb2290239 100644 --- a/src/feature.js +++ b/src/feature.js @@ -540,7 +540,7 @@ var feature = function (arg) { } else if (typeof arg1 === 'string' && arg2 === undefined) { return m_style[arg1]; } else if (arg2 === undefined) { - m_style = $.extend({}, m_style, arg1); + m_style = Object.assign({}, m_style, arg1); m_this.modified(); return m_this; } else { @@ -936,7 +936,7 @@ var feature = function (arg) { if (!m_layer) { throw new Error('Feature requires a valid layer'); } - m_style = $.extend( + m_style = Object.assign( {}, {opacity: 1.0}, arg.style === undefined ? {} : arg.style); diff --git a/src/graphFeature.js b/src/graphFeature.js index 32ff9b09c3..a4452c5364 100644 --- a/src/graphFeature.js +++ b/src/graphFeature.js @@ -39,7 +39,6 @@ var graphFeature = function (arg) { arg = arg || {}; feature.call(this, arg); - var $ = require('jquery'); var util = require('./util'); var registry = require('./registry'); @@ -64,8 +63,9 @@ var graphFeature = function (arg) { this._init = function (arg) { s_init.call(m_this, arg); - var defaultStyle = $.extend( - true, {}, { + var defaultStyle = util.deepMerge( + {}, + { nodes: { radius: 5.0, fill: true, diff --git a/src/gridFeature.js b/src/gridFeature.js index ed88aef88c..b1e4bada84 100644 --- a/src/gridFeature.js +++ b/src/gridFeature.js @@ -93,7 +93,6 @@ var gridFeature = function (arg) { return new gridFeature(arg); } - var $ = require('jquery'); var util = require('./util'); var meshUtil = require('./util/mesh'); @@ -128,7 +127,7 @@ var gridFeature = function (arg) { this._init = function (arg) { s_init.call(m_this, arg); - var defaultStyle = $.extend( + var defaultStyle = Object.assign( {}, { opacity: 1.0, @@ -143,7 +142,7 @@ var gridFeature = function (arg) { m_this.style(defaultStyle); - m_this.grid($.extend({}, { + m_this.grid(Object.assign({}, { minColor: 'black', minOpacity: 0, maxColor: 'black', diff --git a/src/heatmapFeature.js b/src/heatmapFeature.js index 251d46911d..d3e20eb4af 100644 --- a/src/heatmapFeature.js +++ b/src/heatmapFeature.js @@ -1,4 +1,3 @@ -var $ = require('jquery'); var inherit = require('./inherit'); var feature = require('./feature'); var transform = require('./transform'); @@ -233,7 +232,7 @@ var heatmapFeature = function (arg) { this._init = function (arg) { s_init.call(m_this, arg); - var defaultStyle = $.extend( + var defaultStyle = Object.assign( {}, { radius: 10, diff --git a/src/index.js b/src/index.js index e2a45b67e5..42d4589af1 100644 --- a/src/index.js +++ b/src/index.js @@ -41,7 +41,7 @@ $.htmlPrefilter = function (html) { require('./main.styl'); -module.exports = $.extend({ +module.exports = Object.assign({ annotationLayer: require('./annotationLayer'), camera: require('./camera'), choroplethFeature: require('./choroplethFeature'), diff --git a/src/isolineFeature.js b/src/isolineFeature.js index c5c66dd98d..14f6c14bb3 100644 --- a/src/isolineFeature.js +++ b/src/isolineFeature.js @@ -190,7 +190,6 @@ var isolineFeature = function (arg) { return new isolineFeature(arg); } - var $ = require('jquery'); var transform = require('./transform'); var geo_event = require('./event'); var textFeature = require('./textFeature'); @@ -646,7 +645,7 @@ var isolineFeature = function (arg) { * properties if there are no labels. */ this.lastLabelPositions = function () { - return $.extend({}, m_lastLabelPositions); + return Object.assign({}, m_lastLabelPositions); }; /** @@ -816,7 +815,7 @@ var isolineFeature = function (arg) { arg = arg || {}; s_init.call(m_this, arg); - var defaultStyle = $.extend( + var defaultStyle = Object.assign( {}, { opacity: 1.0, @@ -836,7 +835,7 @@ var isolineFeature = function (arg) { m_this.style(defaultStyle); - m_this.isoline($.extend({}, { + m_this.isoline(Object.assign({}, { count: 15, autofit: true, levels: [5, 5], diff --git a/src/layer.js b/src/layer.js index 7efea6b9b9..6bee2410f6 100644 --- a/src/layer.js +++ b/src/layer.js @@ -517,7 +517,7 @@ var layer = function (arg) { m_map.node().append(m_node); /* Pass along the arguments, but not the map reference */ - var options = $.extend({}, arg); + var options = Object.assign({}, arg); delete options.map; if (m_renderer) { diff --git a/src/lineFeature.js b/src/lineFeature.js index 5ad90e3c6d..f4875f4019 100644 --- a/src/lineFeature.js +++ b/src/lineFeature.js @@ -79,8 +79,6 @@ var lineFeature = function (arg) { return new lineFeature(arg); } - var $ = require('jquery'); - arg = arg || {}; feature.call(this, arg); @@ -475,7 +473,7 @@ var lineFeature = function (arg) { arg = arg || {}; s_init.call(m_this, arg); - var defaultStyle = $.extend( + var defaultStyle = Object.assign( {}, { strokeWidth: 1.0, diff --git a/src/map.js b/src/map.js index 5a4f1858d1..7a189c5c33 100644 --- a/src/map.js +++ b/src/map.js @@ -332,7 +332,7 @@ var map = function (arg) { * @returns {geo.geoPosition} */ this.origin = function () { - return $.extend({}, m_origin); + return Object.assign({}, m_origin); }; /** @@ -594,7 +594,7 @@ var map = function (arg) { this.center = function (coordinates, gcs, ignoreDiscreteZoom, ignoreClampBounds) { var center; if (coordinates === undefined) { - center = $.extend({}, m_this.worldToGcs(m_center, gcs)); + center = Object.assign({}, m_this.worldToGcs(m_center, gcs)); return center; } @@ -901,7 +901,7 @@ var map = function (arg) { if (typeof readerOrName === 'string') { opts = opts || {}; if (!opts.layer) { - opts.layer = m_this.createLayer('feature', $.extend({}, opts)); + opts.layer = m_this.createLayer('feature', Object.assign({}, opts)); } opts.renderer = opts.layer.renderer().api(); m_fileReader = registry.createFileReader(readerOrName, opts); @@ -1060,7 +1060,7 @@ var map = function (arg) { */ this.zoomRange = function (arg, noRefresh) { if (arg === undefined) { - return $.extend({}, m_validZoomRange); + return Object.assign({}, m_validZoomRange); } if (arg.max !== undefined) { m_validZoomRange.max = arg.max; @@ -1130,12 +1130,12 @@ var map = function (arg) { /* The queued transition needs to combine the current transition's * endpoint, any other queued transition, and the new transition to be * complete. */ - var transitionEnd = $.extend(true, {}, m_transition.end); + var transitionEnd = util.deepMerge({}, m_transition.end); if (transitionEnd.center && m_gcs !== m_ingcs) { transitionEnd.center = transform.transformCoordinates( m_gcs, m_ingcs, transitionEnd.center); } - m_queuedTransition = $.extend( + m_queuedTransition = Object.assign( {}, transitionEnd || {}, m_queuedTransition || {}, opts); return m_this; } @@ -1188,13 +1188,13 @@ var map = function (arg) { if (opts.center) { gcs = (gcs === null ? m_gcs : (gcs === undefined ? m_ingcs : gcs)); - opts = $.extend(true, {}, opts); + opts = util.deepMerge({}, opts); opts.center = util.normalizeCoordinates(opts.center); if (gcs !== m_gcs) { opts.center = transform.transformCoordinates(gcs, m_gcs, opts.center); } } - opts = $.extend(true, {}, defaultOpts, opts); + opts = util.deepMerge({}, defaultOpts, opts); m_transition = { start: { @@ -1756,7 +1756,7 @@ var map = function (arg) { /* if asked to wait, return a Deferred that will do so, calling the * screenshot function without waiting once it is done. */ if (opts.wait) { - var optsWithoutWait = $.extend({}, opts, {wait: false}); + var optsWithoutWait = Object.assign({}, opts, {wait: false}); defer = $.Deferred(); var waitForRAF = function () { @@ -2228,7 +2228,7 @@ var map = function (arg) { } var dx, dy, maxBounds = m_maxBounds; if (rotation) { - maxBounds = $.extend({}, m_maxBounds); + maxBounds = Object.assign({}, m_maxBounds); /* When rotated, expand the maximum bounds so that they will allow the * corners to be visible. We know the rotated bounding box, plus the * original maximum bounds. To fit the corners of the maximum bounds, we @@ -2417,7 +2417,7 @@ var map = function (arg) { m_zoom = this._fix_zoom(m_zoom); m_rotation = fix_rotation(m_rotation); // Now update to the correct center and zoom level - this.center($.extend({}, arg.center || m_center), undefined); + this.center(Object.assign({}, arg.center || m_center), undefined); if (arg.interactor !== null) { this.interactor(arg.interactor || mapInteractor({discreteZoom: m_discreteZoom})); diff --git a/src/mapInteractor.js b/src/mapInteractor.js index 2ddc22447b..d9bdde7d30 100644 --- a/src/mapInteractor.js +++ b/src/mapInteractor.js @@ -175,8 +175,7 @@ var mapInteractor = function (args) { } // copy the options object with defaults - m_options = $.extend( - true, + m_options = util.deepMerge( {}, { throttle: 30, @@ -390,13 +389,13 @@ var mapInteractor = function (args) { /* We don't want to merge the original arrays with arrays passed in the args, * so override that as necessary for actions. */ if (args && args.actions) { - m_options.actions = $.extend(true, [], args.actions); + m_options.actions = util.deepMerge([], args.actions); } if (args && args.momentum && args.momentum.actions) { - m_options.momentum.actions = $.extend(true, [], args.momentum.actions); + m_options.momentum.actions = util.deepMerge([], args.momentum.actions); } if (args && args.keyboard && args.keyboard.actions !== undefined) { - m_options.keyboard.actions = $.extend(true, {}, args.keyboard.actions); + m_options.keyboard.actions = util.deepMerge({}, args.keyboard.actions); } // default mouse object @@ -882,9 +881,9 @@ var mapInteractor = function (args) { */ this.options = function (opts) { if (opts === undefined) { - return $.extend({}, m_options); + return Object.assign({}, m_options); } - $.extend(m_options, opts); + Object.assign(m_options, opts); // reset event handlers for new options m_this._connectEvents(); @@ -1039,7 +1038,7 @@ var mapInteractor = function (args) { display: display, gcs: gcs, mouse: mouse, - origin: $.extend({}, m_state.origin) + origin: Object.assign({}, m_state.origin) }; }; @@ -1119,7 +1118,7 @@ var mapInteractor = function (args) { m_this._setClickMaybe({ x: m_mouse.page.x, y: m_mouse.page.y, - buttons: $.extend({}, m_mouse.buttons) + buttons: Object.assign({}, m_mouse.buttons) }); if (m_options.click.duration > 0) { m_clickMaybeTimeout = window.setTimeout(function () { @@ -1153,7 +1152,7 @@ var mapInteractor = function (args) { m_state = { action: action, actionRecord: actionRecord, - origin: $.extend(true, {}, m_mouse), + origin: util.deepMerge({}, m_mouse), initialZoom: map.zoom(), initialRotation: map.rotation(), initialEventRotation: evt.rotation, @@ -1686,7 +1685,7 @@ var mapInteractor = function (args) { function accum(dz, org) { var map = m_this.map(), zoom; - origin = $.extend(true, {}, org); + origin = util.deepMerge({}, org); deltaZ += dz; if (targetZoom === undefined) { startZoom = targetZoom = map.zoom(); @@ -2004,7 +2003,7 @@ var mapInteractor = function (args) { * @returns {object} The current mouse state. */ this.mouse = function () { - return $.extend(true, {}, m_mouse); + return util.deepMerge({}, m_mouse); }; /** @@ -2017,7 +2016,7 @@ var mapInteractor = function (args) { */ this.keyboard = function (newValue) { if (newValue === undefined) { - return $.extend(true, {}, m_options.keyboard || {}); + return util.deepMerge({}, m_options.keyboard || {}); } return m_this.options({keyboard: newValue}); }; @@ -2028,7 +2027,7 @@ var mapInteractor = function (args) { * @returns {geo.interactorState} */ this.state = function () { - return $.extend(true, {}, m_state); + return util.deepMerge({}, m_state); }; /** diff --git a/src/markerFeature.js b/src/markerFeature.js index 3e570b3c2f..f30705a369 100644 --- a/src/markerFeature.js +++ b/src/markerFeature.js @@ -74,7 +74,6 @@ var markerFeature = function (arg) { arg = arg || {}; pointFeature.call(this, arg); - var $ = require('jquery'); var timestamp = require('./timestamp'); var util = require('./util'); var KDBush = require('kdbush'); @@ -404,11 +403,10 @@ var markerFeature = function (arg) { * @returns {this} */ this._init = function (arg) { - arg = $.extend( - true, + arg = util.deepMerge( {}, { - style: $.extend( + style: Object.assign( {}, { radius: 6.25, diff --git a/src/meshFeature.js b/src/meshFeature.js index 9c5fcaf008..44f584b215 100644 --- a/src/meshFeature.js +++ b/src/meshFeature.js @@ -112,7 +112,6 @@ var meshFeature = function (arg) { return new meshFeature(arg); } - var $ = require('jquery'); var util = require('./util'); arg = arg || {}; @@ -145,7 +144,7 @@ var meshFeature = function (arg) { return m_mesh[specOrProperty]; } if (value === undefined) { - var mesh = $.extend( + var mesh = Object.assign( {}, { gridWidth: function () { @@ -552,7 +551,7 @@ var meshFeature = function (arg) { /* Initialize from arguments */ arg = arg || {}; - var style = $.extend({}, { + var style = Object.assign({}, { position: (d) => Array.isArray(d) ? {x: d[0], y: d[1], z: d[2] || 0} : d }, arg.style || {}); diff --git a/src/osmLayer.js b/src/osmLayer.js index 5e4f179866..b5e3abaabe 100644 --- a/src/osmLayer.js +++ b/src/osmLayer.js @@ -1,8 +1,8 @@ -var $ = require('jquery'); var inherit = require('./inherit'); var tileLayer = require('./tileLayer'); var registry = require('./registry'); var quadFeature = require('./quadFeature'); +var util = require('./util'); /** * Object specification for an OSM layer. @@ -37,11 +37,10 @@ var osmLayer = function (arg) { } arg = arg || {}; if (arg.mapOpacity !== undefined && arg.opacity === undefined) { - arg = $.extend({}, arg); + arg = Object.assign({}, arg); arg.opacity = arg.mapOpacity; } - arg = $.extend( - true, + arg = util.deepMerge( {}, this.constructor.defaults, osmLayer.tileSources[this.constructor.defaults.source] || {}, @@ -118,7 +117,7 @@ var osmLayer = function (arg) { /** * This object contains the default options used to initialize the osmLayer. */ -osmLayer.defaults = $.extend({}, tileLayer.defaults, { +osmLayer.defaults = Object.assign({}, tileLayer.defaults, { tileOffset : function (level) { var s = Math.pow(2, level - 1) * 256; return {x: s, y: s}; diff --git a/src/pathFeature.js b/src/pathFeature.js index 294535db83..a7de5c46e0 100644 --- a/src/pathFeature.js +++ b/src/pathFeature.js @@ -1,4 +1,3 @@ -var $ = require('jquery'); var inherit = require('./inherit'); var feature = require('./feature'); @@ -79,7 +78,7 @@ var pathFeature = function (arg) { this._init = function (arg) { s_init.call(m_this, arg); - var defaultStyle = $.extend( + var defaultStyle = Object.assign( {}, { strokeWidth: 1, diff --git a/src/pixelmapFeature.js b/src/pixelmapFeature.js index 5553fca09c..20d47521ea 100644 --- a/src/pixelmapFeature.js +++ b/src/pixelmapFeature.js @@ -274,7 +274,7 @@ var pixelmapFeature = function (arg) { arg = arg || {}; s_init.call(m_this, arg); - var style = $.extend( + var style = Object.assign( {}, { color: function (d, idx) { diff --git a/src/pixelmapLayer.js b/src/pixelmapLayer.js index 230e23d41d..1eb11ae0c7 100644 --- a/src/pixelmapLayer.js +++ b/src/pixelmapLayer.js @@ -1,9 +1,9 @@ -var $ = require('jquery'); var inherit = require('./inherit'); var tileLayer = require('./tileLayer'); var registry = require('./registry'); var quadFeature = require('./quadFeature'); var pixelmapFeature = require('./pixelmapFeature'); +var util = require('./util'); /** * Object specification for a pixelmap layer. @@ -47,8 +47,7 @@ var pixelmapLayer = function (arg) { argdata = arg.data; delete arg.data; } - arg = $.extend( - true, + arg = util.deepMerge( {}, this.constructor.defaults, arg); @@ -136,7 +135,7 @@ var pixelmapLayer = function (arg) { * This object contains the default options used to initialize the * pixelmapLayer. */ -pixelmapLayer.defaults = $.extend({}, tileLayer.defaults, { +pixelmapLayer.defaults = Object.assign({}, tileLayer.defaults, { features: [quadFeature.capabilities.image, pixelmapFeature.capabilities.lookup], tileOffset : function (level) { var s = Math.pow(2, level - 1) * 256; diff --git a/src/pointFeature.js b/src/pointFeature.js index 22e820730e..75cf2f46f6 100644 --- a/src/pointFeature.js +++ b/src/pointFeature.js @@ -76,7 +76,6 @@ var pointFeature = function (arg) { arg = arg || {}; feature.call(this, arg); - var $ = require('jquery'); var timestamp = require('./timestamp'); var ClusterGroup = require('./util/clustering'); var geo_event = require('./event'); @@ -150,7 +149,7 @@ var pointFeature = function (arg) { radiusInGcsAtZoom = Math.pow(Math.pow(offset.y - center.y, 2) + Math.pow(offset.x - center.x, 2), 0.5), zoom = map.zoom(), radiusInGcsAtZoom0 = radiusInGcsAtZoom * Math.pow(2, zoom); - opts = $.extend({}, opts, {radius: radiusInGcsAtZoom0}); + opts = Object.assign({}, opts, {radius: radiusInGcsAtZoom0}); m_clusterTree = new ClusterGroup(opts); m_allData.forEach(function (d, i) { @@ -497,8 +496,7 @@ var pointFeature = function (arg) { arg = arg || {}; s_init.call(m_this, arg); - var defaultStyle = $.extend( - true, + var defaultStyle = util.deepMerge( {}, { radius: 5.0, diff --git a/src/polygonFeature.js b/src/polygonFeature.js index b68e574fba..fd56f7df09 100644 --- a/src/polygonFeature.js +++ b/src/polygonFeature.js @@ -1,4 +1,3 @@ -var $ = require('jquery'); var inherit = require('./inherit'); var feature = require('./feature'); var transform = require('./transform'); @@ -763,7 +762,7 @@ var polygonFeature = function (arg) { arg = arg || {}; s_init.call(m_this, arg); - var style = $.extend( + var style = Object.assign( {}, { // default style diff --git a/src/quadFeature.js b/src/quadFeature.js index d5e42856c9..f6c776f114 100644 --- a/src/quadFeature.js +++ b/src/quadFeature.js @@ -712,7 +712,7 @@ var quadFeature = function (arg) { m_cacheQuads = (arg.cacheQuads !== false); - var style = $.extend( + var style = Object.assign( {}, { color: { r: 1.0, g: 1, b: 1 }, diff --git a/src/registry.js b/src/registry.js index 9ffec0c769..0e14a2ed63 100644 --- a/src/registry.js +++ b/src/registry.js @@ -1,5 +1,6 @@ var $ = require('jquery'); var geo_action = require('./action'); +var util = require('./util/common'); var widgets = { dom: {} @@ -12,7 +13,7 @@ var featureCapabilities = {}; var fileReaders = {}; var rendererLayerAdjustments = {}; var annotations = {}; -var util = {}; +var registry = {}; /** * Register a new file reader type. @@ -22,7 +23,7 @@ var util = {}; * exists, the class creation function is replaced. * @param {function} func Class creation function. */ -util.registerFileReader = function (name, func) { +registry.registerFileReader = function (name, func) { fileReaders[name] = func; }; @@ -35,7 +36,7 @@ util.registerFileReader = function (name, func) { * @returns {geo.fileReader|null} The new reader or null if no such name is * registered. */ -util.createFileReader = function (name, opts) { +registry.createFileReader = function (name, opts) { if (fileReaders.hasOwnProperty(name)) { return fileReaders[name](opts); } @@ -50,7 +51,7 @@ util.createFileReader = function (name, opts) { * exists, the class creation function is replaced. * @param {function} func Class creation function. */ -util.registerRenderer = function (name, func) { +registry.registerRenderer = function (name, func) { renderers[name] = func; }; @@ -66,7 +67,7 @@ util.registerRenderer = function (name, func) { * @returns {geo.renderer|null} The new renderer or null if no such name is * registered. */ -util.createRenderer = function (name, layer, canvas, options) { +registry.createRenderer = function (name, layer, canvas, options) { if (renderers.hasOwnProperty(name)) { var ren = renderers[name]( {layer: layer, canvas: canvas, options: options} @@ -89,7 +90,7 @@ util.createRenderer = function (name, layer, canvas, options) { * @returns {string|null|false} The name of the renderer that should be used * or false if no valid renderer can be determined. */ -util.checkRenderer = function (name, noFallback) { +registry.checkRenderer = function (name, noFallback) { if (name === null) { return name; } @@ -101,7 +102,7 @@ util.checkRenderer = function (name, noFallback) { if (!ren.fallback || noFallback) { return false; } - var fallback = util.checkRenderer(ren.fallback(), true); + var fallback = registry.checkRenderer(ren.fallback(), true); if (fallback !== false) { console.warn(name + ' renderer is unavailable, using ' + fallback + ' renderer instead'); @@ -129,13 +130,13 @@ util.checkRenderer = function (name, noFallback) { * @returns {string|null|false} The name of the renderer that should be used * or false if no valid renderer can be determined. */ -util.rendererForFeatures = function (featureList) { +registry.rendererForFeatures = function (featureList) { var preferredRenderers = ['webgl', 'canvas', 'svg', 'vtkjs', null]; var renderer, ridx, feature, fidx, capability, available; for (ridx = 0; ridx < preferredRenderers.length; ridx += 1) { renderer = preferredRenderers[ridx]; - if (util.checkRenderer(renderer, true) === false) { + if (registry.checkRenderer(renderer, true) === false) { continue; } if (!featureList) { @@ -189,7 +190,7 @@ util.rendererForFeatures = function (featureList) { * @returns {object} if this feature replaces an existing one, this was the * feature that was replaced. In this case, a warning is issued. */ -util.registerFeature = function (category, name, func, capabilities) { +registry.registerFeature = function (category, name, func, capabilities) { if (!(category in features)) { features[category] = {}; featureCapabilities[category] = {}; @@ -216,12 +217,12 @@ util.registerFeature = function (category, name, func, capabilities) { * @returns {geo.feature|null} The new feature or null if no such name is * registered. */ -util.createFeature = function (name, layer, renderer, arg) { +registry.createFeature = function (name, layer, renderer, arg) { var category = renderer.api(), options = {layer: layer, renderer: renderer}; if (category in features && name in features[category]) { if (arg !== undefined) { - $.extend(true, options, arg); + util.deepMerge(options, arg); } var feature = features[category][name](options); if (layer.gcs === undefined) { @@ -248,7 +249,7 @@ util.createFeature = function (name, layer, renderer, arg) { * @returns {object} if this layer adjustment replaces an existing one, this * was the value that was replaced. In this case, a warning is issued. */ -util.registerLayerAdjustment = function (category, name, func) { +registry.registerLayerAdjustment = function (category, name, func) { if (!(category in rendererLayerAdjustments)) { rendererLayerAdjustments[category] = {}; } @@ -269,7 +270,7 @@ util.registerLayerAdjustment = function (category, name, func) { * @param {string} name Name of the layer or adjustment. * @param {object} layer Instantiated layer object. */ -util.adjustLayerForRenderer = function (name, layer) { +registry.adjustLayerForRenderer = function (name, layer) { var rendererName = layer.rendererName(); if (rendererName) { if (rendererLayerAdjustments && @@ -290,7 +291,7 @@ util.adjustLayerForRenderer = function (name, layer) { * @param {string[]} [defaultFeatures] An optional list of feature capabilities * that are required to use this layer. */ -util.registerLayer = function (name, func, defaultFeatures) { +registry.registerLayer = function (name, func, defaultFeatures) { layers[name] = func; layerDefaultFeatures[name] = defaultFeatures; }; @@ -305,7 +306,7 @@ util.registerLayer = function (name, func, defaultFeatures) { * @returns {geo.layer|null} The new layer or null if no such name is * registered. */ -util.createLayer = function (name, map, arg) { +registry.createLayer = function (name, map, arg) { // Default renderer is webgl var options = {map: map}, layer = null; @@ -317,7 +318,7 @@ util.createLayer = function (name, map, arg) { if (arg !== undefined) { const argdata = arg.data; delete arg.data; - $.extend(true, options, arg); + util.deepMerge(options, arg); if (argdata) { options.data = argdata; } @@ -342,7 +343,7 @@ util.createLayer = function (name, map, arg) { * @returns {object} If this widget replaces an existing one, this was the * value that was replaced. In this case, a warning is issued. */ -util.registerWidget = function (category, name, func) { +registry.registerWidget = function (category, name, func) { if (!(category in widgets)) { widgets[category] = {}; } @@ -364,14 +365,14 @@ util.registerWidget = function (category, name, func) { * @param {object} arg Options for the new widget. * @returns {geo.widget} The new widget. */ -util.createWidget = function (name, layer, arg) { +registry.createWidget = function (name, layer, arg) { var options = { layer: layer }; if (name in widgets.dom) { if (arg !== undefined) { - $.extend(true, options, arg); + util.deepMerge(options, arg); } return widgets.dom[name](options); @@ -394,7 +395,7 @@ util.createWidget = function (name, layer, arg) { * @returns {object} if this annotation replaces an existing one, this was the * value that was replaced. In this case, a warning is issued. */ -util.registerAnnotation = function (name, func, features) { +registry.registerAnnotation = function (name, func, features) { var old = annotations[name]; if (old) { console.warn('The ' + name + ' annotation is already registered'); @@ -412,7 +413,7 @@ util.registerAnnotation = function (name, func, features) { * @param {object} options The options for the annotation. * @returns {object} the new annotation. */ -util.createAnnotation = function (name, options) { +registry.createAnnotation = function (name, options) { if (!annotations[name]) { console.warn('The ' + name + ' annotation is not registered'); return; @@ -427,7 +428,7 @@ util.createAnnotation = function (name, options) { * @alias geo.listAnnotations * @returns {string[]} A list of registered annotations. */ -util.listAnnotations = function () { +registry.listAnnotations = function () { return Object.keys(annotations); }; @@ -445,7 +446,7 @@ util.listAnnotations = function () { * @returns {string[]} a list of features needed for the specified annotations. * There may be duplicates in the list. */ -util.featuresForAnnotations = function (annotationList) { +registry.featuresForAnnotations = function (annotationList) { var features = []; var annList = Array.isArray(annotationList) ? annotationList : Object.keys(annotationList); @@ -483,8 +484,8 @@ util.featuresForAnnotations = function (annotationList) { * @returns {string|null|false} the name of the renderer that should be used or * false if no valid renderer can be determined. */ -util.rendererForAnnotations = function (annotationList) { - return util.rendererForFeatures(util.featuresForAnnotations(annotationList)); +registry.rendererForAnnotations = function (annotationList) { + return registry.rendererForFeatures(registry.featuresForAnnotations(annotationList)); }; /** @@ -493,7 +494,7 @@ util.rendererForAnnotations = function (annotationList) { * * @namespace geo.registries */ -util.registries = { +registry.registries = { annotations: annotations, features: features, featureCapabilities: featureCapabilities, @@ -503,4 +504,4 @@ util.registries = { widgets: widgets }; -module.exports = util; +module.exports = registry; diff --git a/src/svg/pathFeature.js b/src/svg/pathFeature.js index f7adb06f81..d3c7bab365 100644 --- a/src/svg/pathFeature.js +++ b/src/svg/pathFeature.js @@ -18,7 +18,6 @@ var svg_pathFeature = function (arg) { return new svg_pathFeature(arg); } - var $ = require('jquery'); var object = require('./object'); var timestamp = require('../timestamp'); @@ -73,7 +72,7 @@ var svg_pathFeature = function (arg) { m_style.id = m_this._svgid(); m_style.append = 'path'; m_style.classes = ['svgPathFeature']; - m_style.style = $.extend({ + m_style.style = Object.assign({ fill: function () { return false; }, fillColor: {r: 0, g: 0, b: 0} }, s_style); diff --git a/src/textFeature.js b/src/textFeature.js index 2490ef1c78..8f11a9b3c0 100644 --- a/src/textFeature.js +++ b/src/textFeature.js @@ -94,8 +94,6 @@ var textFeature = function (arg) { arg = arg || {}; feature.call(this, arg); - var $ = require('jquery'); - /** * @private */ @@ -149,7 +147,7 @@ var textFeature = function (arg) { arg = arg || {}; s_init.call(m_this, arg); - var style = $.extend( + var style = Object.assign( {}, { font: 'bold 16px sans-serif', diff --git a/src/tileLayer.js b/src/tileLayer.js index 6930a9af05..ee44321515 100644 --- a/src/tileLayer.js +++ b/src/tileLayer.js @@ -1,5 +1,6 @@ var inherit = require('./inherit'); var featureLayer = require('./featureLayer'); +var util = require('./util'); /** * Object specification for a tile layer. @@ -194,7 +195,7 @@ var tileLayer = function (arg) { var adjustLayerForRenderer = require('./registry').adjustLayerForRenderer; var Tile = require('./tile'); - arg = $.extend(true, {}, this.constructor.defaults, arg || {}); + arg = util.deepMerge({}, this.constructor.defaults, arg || {}); if (!arg.cacheSize) { // this size should be sufficient for a 4k display // where display size is (w, h), minimum tile dimension is ts, and total @@ -236,7 +237,7 @@ var tileLayer = function (arg) { m_this = this; // copy the options into a private variable - this._options = $.extend(true, {}, arg); + this._options = util.deepMerge({}, arg); // set the layer attribution text this.attribution(arg.attribution); @@ -282,7 +283,7 @@ var tileLayer = function (arg) { * @name geo.tileLayer#options */ Object.defineProperty(this, 'options', {get: function () { - return $.extend({}, m_this._options); + return Object.assign({}, m_this._options); }}); /** @@ -303,7 +304,7 @@ var tileLayer = function (arg) { * @name geo.tileLayer#activeTiles */ Object.defineProperty(this, 'activeTiles', {get: function () { - return $.extend({}, m_this._activeTiles); // copy on output + return Object.assign({}, m_this._activeTiles); // copy on output }}); /** diff --git a/src/trackFeature.js b/src/trackFeature.js index 4bed29c3ca..9b6e181a11 100644 --- a/src/trackFeature.js +++ b/src/trackFeature.js @@ -66,7 +66,6 @@ var trackFeature = function (arg) { return new trackFeature(arg); } - var $ = require('jquery'); var transform = require('./transform'); arg = arg || {}; @@ -480,7 +479,7 @@ var trackFeature = function (arg) { m_styles[styleType] = {}; } if (arg2 === undefined) { - m_styles[styleType] = $.extend(true, m_styles[styleType], arg1); + m_styles[styleType] = util.deepMerge(m_styles[styleType], arg1); } else { m_styles[styleType][arg1] = arg2; } @@ -810,8 +809,7 @@ var trackFeature = function (arg) { arg = arg || {}; s_init.call(m_this, arg); - var style = $.extend( - true, + var style = util.deepMerge( {}, { track: util.identityFunction, @@ -822,8 +820,7 @@ var trackFeature = function (arg) { }, arg.style === undefined ? {} : arg.style ); - var markerStyle = $.extend( - true, + var markerStyle = util.deepMerge( {}, { rotateWithMap: true, @@ -831,8 +828,7 @@ var trackFeature = function (arg) { }, arg.markerStyle === undefined ? {} : arg.markerStyle ); - var textStyle = $.extend( - true, + var textStyle = util.deepMerge( {}, { rotateWithMap: true, @@ -840,24 +836,21 @@ var trackFeature = function (arg) { }, arg.textStyle === undefined ? {} : arg.textStyle ); - var pastStyle = $.extend( - true, + var pastStyle = util.deepMerge( {}, { strokeOpacity: 0.25 }, arg.pastStyle === undefined ? {} : arg.pastStyle ); - var currentStyle = $.extend( - true, + var currentStyle = util.deepMerge( {}, { // defaults go here }, arg.currentStyle === undefined ? {} : arg.currentStyle ); - var futureStyle = $.extend( - true, + var futureStyle = util.deepMerge( {}, { strokeOpacity: 0.25 diff --git a/src/ui/scaleWidget.js b/src/ui/scaleWidget.js index 7a40b33c0b..04da25d560 100644 --- a/src/ui/scaleWidget.js +++ b/src/ui/scaleWidget.js @@ -93,7 +93,7 @@ var scaleWidget = function (arg) { var m_this = this, s_exit = this._exit, - m_options = $.extend({}, { + m_options = Object.assign({}, { scale: 1, maxWidth: 200, maxHeight: arg.orientation === 'left' || arg.orientation === 'right' ? 200 : 20, @@ -299,7 +299,7 @@ var scaleWidget = function (arg) { */ this.options = function (arg1, arg2) { if (arg1 === undefined) { - var result = $.extend({}, m_options); + var result = Object.assign({}, m_options); result.position = m_this.position(undefined, true); return result; } @@ -307,7 +307,7 @@ var scaleWidget = function (arg) { return arg1 === 'position' ? m_this.position(undefined, true) : m_options[arg1]; } if (arg2 === undefined) { - m_options = $.extend(true, m_options, arg1); + m_options = util.deepMerge(m_options, arg1); } else { m_options[arg1] = arg2; } diff --git a/src/ui/widget.js b/src/ui/widget.js index be53261719..a656c36291 100644 --- a/src/ui/widget.js +++ b/src/ui/widget.js @@ -1,6 +1,5 @@ var inherit = require('../inherit'); var sceneObject = require('../sceneObject'); -var $ = require('jquery'); /** * @typedef {object} geo.gui.widget.position @@ -164,7 +163,7 @@ var widget = function (arg) { if (m_position.hasOwnProperty('x') && m_position.hasOwnProperty('y')) { m_this.layer().geoOn(geo_event.pan, m_this.repositionEvent); } - m_this.reposition($.extend(clearPosition, m_this.position())); + m_this.reposition(Object.assign(clearPosition, m_this.position())); return m_this; } if (m_position.hasOwnProperty('x') && m_position.hasOwnProperty('y') && !actualValue) { diff --git a/src/util/clustering.js b/src/util/clustering.js index 8e1701d2cd..2899ef858b 100644 --- a/src/util/clustering.js +++ b/src/util/clustering.js @@ -144,7 +144,7 @@ function C(opts) { var DistanceGrid = require('./distanceGrid'); // store the options - this._opts = $.extend({ + this._opts = Object.assign({ maxZoom: 18, radius: 5 }, opts); diff --git a/src/util/common.js b/src/util/common.js index a3702c1a1e..a21a576f5c 100644 --- a/src/util/common.js +++ b/src/util/common.js @@ -522,7 +522,7 @@ var util = { * @example The returned objects can be modified or * extended. * var results = pixelCoordinateParams('#map', 10000, 9000); - * var map = geo.map($.extend(results.map, {clampZoom: false})); + * var map = geo.map(Object.assign(results.map, {clampZoom: false})); * map.createLayer('osm', results.layer); * * @param {string?} node DOM selector for the map container. @@ -991,6 +991,43 @@ var util = { }); }, + /** + * Recursively merge two objects. This is intended to replace + * util.deepMerge(target, ...sources). + * + * @param {object} target target object to modify. + * @param {object} sources object(s) to merge into the target. + * @returns {object} The merged object. + * @member geo.util + */ + deepMerge: function (target, ...sources) { + for (const source of sources) { + if (source === null || source === undefined) { + continue; + } + for (const key in source) { + if (key === '__proto__' || target === source[key]) { + continue; + } + const copy = source[key]; + if (copy && typeof copy === 'object' && copy && (copy.constructor === undefined || copy.constructor === Object || Array.isArray(copy))) { + let src = target[key]; + if (!Array.isArray(copy)) { + if (typeof src !== 'object' || Array.isArray(src)) { + src = {}; + } + } else if (!Array.isArray(src)) { + src = []; + } + target[key] = util.deepMerge(src, copy); + } else if (copy !== undefined) { + target[key] = copy; + } + } + } + return target; + }, + /** * Check svg image and html img tags. If the source is set, load images * explicitly and convert them to local data:image references. diff --git a/src/util/mesh.js b/src/util/mesh.js index 94f2d1b1a3..d64bcca5fa 100644 --- a/src/util/mesh.js +++ b/src/util/mesh.js @@ -35,7 +35,6 @@ * information. */ function createColoredMesh(feature, elementValues) { - var $ = require('jquery'); var util = require('../util'); var mesh = feature.mesh, @@ -62,14 +61,14 @@ function createColoredMesh(feature, elementValues) { result.stepped = stepped === undefined || stepped ? true : false; /* Create the min/max colors and the color array */ result.colorMap = []; - result.minColor = $.extend( + result.minColor = Object.assign( {a: mesh.get('minOpacity')(result) || 0}, util.convertColor(mesh.get('minColor')(result))); - result.maxColor = $.extend( + result.maxColor = Object.assign( {a: mesh.get('maxOpacity')(result) || 0}, util.convertColor(mesh.get('maxColor')(result))); mesh.get('colorRange')(result).forEach(function (clr, idx) { - result.colorMap.push($.extend({ + result.colorMap.push(Object.assign({ a: opacityRange && opacityRange[idx] !== undefined ? opacityRange[idx] : 1 }, util.convertColor(clr))); }); diff --git a/src/util/mockVGL.js b/src/util/mockVGL.js index 21e1dbeb86..c82e874d14 100644 --- a/src/util/mockVGL.js +++ b/src/util/mockVGL.js @@ -1,6 +1,5 @@ /* eslint-disable camelcase */ -var $ = require('jquery'); var webglRenderer = require('../webgl/webglRenderer'); var _renderWindow, _supported; @@ -152,7 +151,7 @@ module.exports.mockWebglRenderer = function mockWebglRenderer(supported) { wsize = m_this.windowSize(), wpos = m_this.windowPosition(); - m_context = $.extend({}, vgl.GL, default_context); + m_context = Object.assign({}, vgl.GL, default_context); for (i = 0; i < renderers.length; i += 1) { if ((renderers[i].width() > wsize[0]) || diff --git a/src/vectorFeature.js b/src/vectorFeature.js index a27ba27167..c0a75db850 100644 --- a/src/vectorFeature.js +++ b/src/vectorFeature.js @@ -52,8 +52,6 @@ var vectorFeature = function (arg) { return new vectorFeature(arg); } - var $ = require('jquery'); - arg = arg || {}; feature.call(this, arg); @@ -112,7 +110,7 @@ var vectorFeature = function (arg) { this._init = function (arg) { s_init.call(m_this, arg); - var defaultStyle = $.extend( + var defaultStyle = Object.assign( {}, { strokeColor: 'black',