qwc2 2026.7.9 → 2026.7.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/components/ExportSelection.js +21 -9
  2. package/components/IdentifyViewer.js +1 -7
  3. package/components/LayerInfoWindow.js +1 -2
  4. package/components/LocationRecorder.js +1 -1
  5. package/components/MapSelection.js +2 -11
  6. package/components/PickFeature.js +4 -2
  7. package/components/ResizeableWindow.js +1 -1
  8. package/components/SearchBox.js +16 -16
  9. package/components/ServiceInfoWindow.js +5 -18
  10. package/components/ThemeList.js +1 -2
  11. package/components/map3d/Map3D.js +23 -2
  12. package/components/map3d/utils/OrbitControls3D.js +2 -1
  13. package/components/share/ShareSocials.js +6 -14
  14. package/components/style/ResizeableWindow.css +10 -0
  15. package/components/widgets/ColorButton.js +38 -30
  16. package/components/widgets/LayerCatalogWidget.js +21 -8
  17. package/components/widgets/MenuButton.js +8 -5
  18. package/components/widgets/TextInput.js +4 -5
  19. package/components/widgets/style/ColorButton.css +15 -4
  20. package/extra/plugins/PlotInfoTool.js +1 -1
  21. package/package.json +4 -3
  22. package/plugins/BackgroundSwitcher.js +7 -3
  23. package/plugins/FeatureForm.js +1 -2
  24. package/plugins/HeightProfile.js +4 -0
  25. package/plugins/Identify.js +223 -137
  26. package/plugins/LayerCatalog.js +12 -3
  27. package/plugins/LayerTree.js +24 -10
  28. package/plugins/MapCopyright.js +2 -2
  29. package/plugins/MapExport.js +4 -0
  30. package/plugins/MapTip.js +2 -4
  31. package/plugins/Print.js +4 -0
  32. package/plugins/Routing.js +1 -1
  33. package/plugins/ServiceInfo.js +109 -0
  34. package/plugins/TaskButton.js +2 -10
  35. package/plugins/ThemeBrowser.js +2 -2
  36. package/plugins/TopBar.js +1 -1
  37. package/plugins/VisibilityPreset.js +14 -14
  38. package/plugins/ZoomButtons.js +3 -3
  39. package/plugins/map3d/Compare3D.js +11 -2
  40. package/plugins/map3d/Identify3D.js +1 -2
  41. package/plugins/map3d/MapCopyright3D.js +2 -2
  42. package/plugins/map3d/MapExport3D.js +23 -10
  43. package/plugins/map3d/Viewshed3D.js +387 -0
  44. package/plugins/map3d/style/Viewshed3D.css +26 -0
  45. package/plugins/redlining/RedliningFeatureLabelSupport.js +5 -5
  46. package/plugins/style/Identify.css +13 -0
  47. package/static/translations/bg-BG.json +12 -2
  48. package/static/translations/ca-ES.json +13 -3
  49. package/static/translations/cs-CZ.json +12 -2
  50. package/static/translations/de-CH.json +12 -2
  51. package/static/translations/de-DE.json +12 -2
  52. package/static/translations/en-US.json +13 -3
  53. package/static/translations/es-ES.json +13 -3
  54. package/static/translations/fi-FI.json +12 -2
  55. package/static/translations/fr-FR.json +14 -4
  56. package/static/translations/hu-HU.json +12 -2
  57. package/static/translations/it-IT.json +12 -2
  58. package/static/translations/ja-JP.json +12 -2
  59. package/static/translations/nl-NL.json +12 -2
  60. package/static/translations/no-NO.json +12 -2
  61. package/static/translations/pl-PL.json +12 -2
  62. package/static/translations/pt-BR.json +12 -2
  63. package/static/translations/pt-PT.json +12 -2
  64. package/static/translations/ro-RO.json +12 -2
  65. package/static/translations/ru-RU.json +12 -2
  66. package/static/translations/sv-SE.json +12 -2
  67. package/static/translations/tr-TR.json +12 -2
  68. package/static/translations/tsconfig.json +11 -2
  69. package/static/translations/uk-UA.json +12 -2
  70. package/utils/EditingUtils.js +16 -13
  71. package/utils/LayerUtils.js +3 -2
  72. package/utils/MiscUtils.js +24 -11
  73. package/utils/VectorLayerUtils.js +67 -28
  74. package/utils/expr_grammar/grammar.js +78 -24
  75. package/utils/expr_grammar/grammar.ne +2 -1
  76. package/utils/expr_grammar/test.js +6 -0
  77. package/actions/serviceinfo.js +0 -18
  78. package/reducers/serviceinfo.js +0 -30
@@ -128,24 +128,36 @@ var ExportSelection = /*#__PURE__*/function (_React$Component) {
128
128
  }
129
129
  if (this.props.frameRatio !== prevProps.frameRatio) {
130
130
  this.setState(function (state) {
131
- var maxWidth = _this2.exportContainer.offsetWidth;
132
- var maxHeight = _this2.exportContainer.offsetHeight;
133
- var newheight = _this2.props.frameRatio ? Math.round(state.width * _this2.props.frameRatio) : state.height;
134
- var newwidth = state.width;
131
+ var containerWidth = _this2.exportContainer.offsetWidth;
132
+ var containerHeight = _this2.exportContainer.offsetHeight;
133
+ var maxWidth = 0.75 * containerWidth;
134
+ var maxHeight = 0.75 * containerHeight;
135
+ var newwidth;
136
+ var newheight;
135
137
  if (_this2.props.frameRatio) {
136
- if (newwidth > maxWidth) {
138
+ if (_this2.props.frameRatio >= 1) {
137
139
  newwidth = maxWidth;
138
140
  newheight = Math.round(newwidth * _this2.props.frameRatio);
139
- }
140
- if (newheight > maxHeight) {
141
+ if (newheight > maxHeight) {
142
+ newheight = maxHeight;
143
+ newwidth = Math.round(newheight / _this2.props.frameRatio);
144
+ }
145
+ } else {
141
146
  newheight = maxHeight;
142
147
  newwidth = Math.round(newheight / _this2.props.frameRatio);
148
+ if (newwidth > maxWidth) {
149
+ newwidth = maxWidth;
150
+ newheight = Math.round(newwidth * _this2.props.frameRatio);
151
+ }
143
152
  }
153
+ } else {
154
+ newwidth = state.width;
155
+ newheight = state.height;
144
156
  }
145
157
  return {
146
158
  frameRatio: _this2.props.frameRatio,
147
- x: 0.5 * (maxWidth - newwidth),
148
- y: 0.5 * (maxHeight - newheight),
159
+ x: 0.5 * (containerWidth - newwidth),
160
+ y: 0.5 * (containerHeight - newheight),
149
161
  width: newwidth,
150
162
  height: newheight
151
163
  };
@@ -37,7 +37,6 @@ import React from 'react';
37
37
  import { connect } from 'react-redux';
38
38
  import axios from 'axios';
39
39
  import clone from 'clone';
40
- import DOMPurify from 'dompurify';
41
40
  import FileSaver from 'file-saver';
42
41
  import JSZip from 'jszip';
43
42
  import isEmpty from 'lodash.isempty';
@@ -1164,12 +1163,7 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
1164
1163
  return _this.parsedContent(text);
1165
1164
  });
1166
1165
  _defineProperty(_this, "parsedContent", function (text) {
1167
- text = DOMPurify.sanitize(text, {
1168
- ADD_ATTR: ['target'],
1169
- ADD_TAGS: ["iframe"],
1170
- FORCE_BODY: true,
1171
- ALLOW_UNKNOWN_PROTOCOLS: true
1172
- }).replace('&#10;', '<br />');
1166
+ text = MiscUtils.sanitizeHtml(text).replace('&#10;', '<br />');
1173
1167
  var options = {
1174
1168
  replace: function replace(node) {
1175
1169
  if (node.name === "a") {
@@ -22,7 +22,6 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
22
22
 
23
23
  import React from 'react';
24
24
  import { connect } from 'react-redux';
25
- import DOMPurify from 'dompurify';
26
25
  import PropTypes from 'prop-types';
27
26
  import { setActiveLayerInfo } from '../actions/layerinfo';
28
27
  import ResizeableWindow from '../components/ResizeableWindow';
@@ -45,7 +44,7 @@ var LayerInfoWindow = /*#__PURE__*/function (_React$Component) {
45
44
  if (content) {
46
45
  return /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, title, ":"), html ? /*#__PURE__*/React.createElement("td", {
47
46
  dangerouslySetInnerHTML: {
48
- __html: MiscUtils.addLinkAnchors(DOMPurify.sanitize(content))
47
+ __html: MiscUtils.addLinkAnchors(MiscUtils.sanitizeHtml(content))
49
48
  }
50
49
  }) : /*#__PURE__*/React.createElement("td", null, content));
51
50
  }
@@ -45,7 +45,7 @@ var LocationRecorder = /*#__PURE__*/function (_React$Component) {
45
45
  } else {
46
46
  _this.props.drawInteraction.abortDrawing();
47
47
  _this.props.drawInteraction.setActive(false);
48
- // Re-add overlay to map, removed by setActive(false), to ensure traced feature is visibile
48
+ // Re-add overlay to map, removed by setActive(false), to ensure traced feature is visible
49
49
  _this.props.drawInteraction.getOverlay().setMap(_this.props.map);
50
50
  _this.setState({
51
51
  recording: true
@@ -124,7 +124,6 @@ var MapSelection = /*#__PURE__*/function (_React$Component) {
124
124
  if (!geometry) {
125
125
  return;
126
126
  }
127
- var coords = _this.props.geomType === 'Circle' ? null : geometry.getCoordinates();
128
127
  if (_this.props.geomType === "Circle") {
129
128
  // Also store poligonized circle
130
129
  var center = geometry.getCenter();
@@ -141,19 +140,11 @@ var MapSelection = /*#__PURE__*/function (_React$Component) {
141
140
  radius: radius
142
141
  }
143
142
  });
144
- } else if (_this.props.geomType === "DragBox" || _this.props.geomType === "Box") {
145
- var boxcoords = [[Math.min(coords[0][0][0], coords[0][2][0]), Math.min(coords[0][0][1], coords[0][2][1]), Math.max(coords[0][0][0], coords[0][2][0]), Math.max(coords[0][0][1], coords[0][2][1])]];
146
- _this.setState({
147
- geometry: {
148
- type: "Polygon",
149
- coordinates: boxcoords
150
- }
151
- });
152
143
  } else {
153
144
  _this.setState({
154
145
  geometry: {
155
- type: _this.props.geomType,
156
- coordinates: coords
146
+ type: geometry.getType(),
147
+ coordinates: geometry.getCoordinates()
157
148
  }
158
149
  });
159
150
  }
@@ -94,7 +94,7 @@ var PickFeature = /*#__PURE__*/function (_React$Component) {
94
94
  };
95
95
  if (newState.pendingQueries === 0) {
96
96
  if (newState.pickResults.length === 1) {
97
- _this.props.featurePicked(newState.pickResults[0].layer, newState.pickResults[0].feature, newState.pickResults[0].mapName);
97
+ _this.props.featurePicked(newState.pickResults[0].layer, newState.pickResults[0].feature, newState.pickResults[0].mapName, state.mapPos);
98
98
  newState.pickResults = null;
99
99
  newState.pickGeom = null;
100
100
  } else if (newState.pickResults.length === 0) {
@@ -237,6 +237,7 @@ var PickFeature = /*#__PURE__*/function (_React$Component) {
237
237
  return {
238
238
  pickResults: pickResults,
239
239
  clickPos: clickPos,
240
+ mapPos: [maxX, maxY],
240
241
  pendingQueries: queryWmsLayers.length,
241
242
  reqId: reqId
242
243
  };
@@ -261,7 +262,7 @@ var PickFeature = /*#__PURE__*/function (_React$Component) {
261
262
  return /*#__PURE__*/React.createElement("div", {
262
263
  key: key,
263
264
  onClick: function onClick() {
264
- return _this3.props.featurePicked(entry.layer, entry.feature, entry.mapName);
265
+ return _this3.props.featurePicked(entry.layer, entry.feature, entry.mapName, _this3.state.mapPos);
265
266
  },
266
267
  onMouseOut: function onMouseOut() {
267
268
  return _this3.clearHighlight(key, entry.feature);
@@ -330,6 +331,7 @@ _defineProperty(PickFeature, "defaultState", {
330
331
  pickGeom: null,
331
332
  pickResults: null,
332
333
  clickPos: null,
334
+ mapPos: null,
333
335
  highlightedFeature: null,
334
336
  pendingQueries: 0,
335
337
  reqId: null
@@ -319,7 +319,7 @@ var ResizeableWindow = /*#__PURE__*/function (_React$Component) {
319
319
  }, _this.renderTitleBar(), /*#__PURE__*/React.createElement("div", {
320
320
  className: "resizeable-window-body"
321
321
  }, _this.portalNode ? /*#__PURE__*/React.createElement("div", {
322
- className: "resizeable-window-portal-container"
322
+ className: "resizeable-window-portal-container resizeable-window-portal-container-detached"
323
323
  }, /*#__PURE__*/React.createElement(portals.OutPortal, {
324
324
  node: _this.portalNode
325
325
  })) : _this.props.children)), _this.state.externalWindow.document.body);
@@ -36,7 +36,6 @@ import React from 'react';
36
36
  import { connect } from 'react-redux';
37
37
  import axios from 'axios';
38
38
  import classnames from 'classnames';
39
- import DOMPurify from 'dompurify';
40
39
  import isEmpty from 'lodash.isempty';
41
40
  import pointInPolygon from 'point-in-polygon';
42
41
  import polygonIntersectTest from 'polygon-intersect-test';
@@ -410,7 +409,7 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
410
409
  }) : null, /*#__PURE__*/React.createElement("span", {
411
410
  className: "searchbox-result-label",
412
411
  dangerouslySetInnerHTML: {
413
- __html: DOMPurify.sanitize(result.text).replace(/<br\s*\/>/ig, ' ')
412
+ __html: MiscUtils.sanitizeHtml(result.text).replace(/<br\s*\/>/ig, ' ')
414
413
  },
415
414
  title: (_result$label = result.label) !== null && _result$label !== void 0 ? _result$label : result.text
416
415
  }), result.externalLink ? /*#__PURE__*/React.createElement(Icon, {
@@ -422,21 +421,21 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
422
421
  }) : null);
423
422
  });
424
423
  _defineProperty(_this, "renderLayerResult", function (provider, group, result) {
425
- var _result$label3, _result$layer;
424
+ var _ConfigUtils$getPlugi, _result$label3, _result$layer;
426
425
  var parent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
427
426
  var level = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
428
427
  var key = provider + ":" + group.id + ":" + result.id;
429
428
  var addThemes = ConfigUtils.getConfigProp("allowAddingOtherThemes", _this.props.theme);
430
429
  var icon = null;
430
+ var toggleLayerGroup = function toggleLayerGroup(ev) {
431
+ MiscUtils.killEvent(ev);
432
+ _this.setState(function (state) {
433
+ return {
434
+ expandedLayerGroup: state.expandedLayerGroup === key ? null : key
435
+ };
436
+ });
437
+ };
431
438
  if (result.sublayers) {
432
- var toggleLayerGroup = function toggleLayerGroup(ev) {
433
- MiscUtils.killEvent(ev);
434
- _this.setState(function (state) {
435
- return {
436
- expandedLayerGroup: state.expandedLayerGroup === key ? null : key
437
- };
438
- });
439
- };
440
439
  icon = /*#__PURE__*/React.createElement(Icon, {
441
440
  icon: _this.state.expandedLayerGroup === key ? "minus" : "plus",
442
441
  onClick: function onClick(ev) {
@@ -456,7 +455,7 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
456
455
  return [/*#__PURE__*/React.createElement("div", {
457
456
  className: "searchbox-result",
458
457
  key: key,
459
- onClick: function onClick() {
458
+ onClick: (_ConfigUtils$getPlugi = ConfigUtils.getPluginConfig("LayerCatalog")) !== null && _ConfigUtils$getPlugi !== void 0 && (_ConfigUtils$getPlugi = _ConfigUtils$getPlugi.cfg) !== null && _ConfigUtils$getPlugi !== void 0 && _ConfigUtils$getPlugi.toggleGroupOnClick && result.sublayers ? toggleLayerGroup : function () {
460
459
  return selectResult(provider, group, result);
461
460
  },
462
461
  style: {
@@ -468,7 +467,7 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
468
467
  }) : null, /*#__PURE__*/React.createElement("span", {
469
468
  className: "searchbox-result-label",
470
469
  dangerouslySetInnerHTML: {
471
- __html: DOMPurify.sanitize(result.text).replace(/<br\s*\/>/ig, ' ')
470
+ __html: MiscUtils.sanitizeHtml(result.text).replace(/<br\s*\/>/ig, ' ')
472
471
  },
473
472
  title: (_result$label3 = result.label) !== null && _result$label3 !== void 0 ? _result$label3 : result.text
474
473
  }), result.theme && addThemes ? /*#__PURE__*/React.createElement(Icon, {
@@ -501,7 +500,7 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
501
500
  }) : null), _this.state.activeLayerInfo === key ? /*#__PURE__*/React.createElement("div", {
502
501
  className: "searchbox-result-abstract",
503
502
  dangerouslySetInnerHTML: {
504
- __html: MiscUtils.addLinkAnchors(DOMPurify.sanitize(((_result$layer = result.layer) === null || _result$layer === void 0 ? void 0 : _result$layer["abstract"]) || "")) || LocaleUtils.tr("search.nodescription")
503
+ __html: MiscUtils.addLinkAnchors(MiscUtils.sanitizeHtml(((_result$layer = result.layer) === null || _result$layer === void 0 ? void 0 : _result$layer["abstract"]) || "")) || LocaleUtils.tr("search.nodescription")
505
504
  },
506
505
  disabled: true,
507
506
  key: key + ":abstract",
@@ -533,13 +532,14 @@ var SearchBox = /*#__PURE__*/function (_React$Component) {
533
532
  }), /*#__PURE__*/React.createElement("span", {
534
533
  className: "searchbox-result-label",
535
534
  dangerouslySetInnerHTML: {
536
- __html: DOMPurify.sanitize(result.text).replace(/<br\s*\/>/ig, ' ')
535
+ __html: MiscUtils.sanitizeHtml(result.text).replace(/<br\s*\/>/ig, ' ')
537
536
  },
538
537
  title: (_result$label5 = result.label) !== null && _result$label5 !== void 0 ? _result$label5 : result.text
539
538
  }), result.theme && addThemes ? /*#__PURE__*/React.createElement(Icon, {
540
539
  icon: "plus",
541
540
  onClick: function onClick(ev) {
542
- return _this.addThemeLayers(result.layer);
541
+ MiscUtils.killEvent(ev);
542
+ _this.addThemeLayers(result.layer);
543
543
  },
544
544
  title: LocaleUtils.tr("themeswitcher.addtotheme")
545
545
  }) : null);
@@ -21,10 +21,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
21
21
  */
22
22
 
23
23
  import React from 'react';
24
- import { connect } from 'react-redux';
25
- import DOMPurify from 'dompurify';
26
24
  import PropTypes from 'prop-types';
27
- import { setActiveServiceInfo } from '../actions/serviceinfo';
28
25
  import ResizeableWindow from '../components/ResizeableWindow';
29
26
  import LocaleUtils from '../utils/LocaleUtils';
30
27
  import MiscUtils from '../utils/MiscUtils';
@@ -42,15 +39,12 @@ var ServiceInfoWindow = /*#__PURE__*/function (_React$Component) {
42
39
  if (content) {
43
40
  return /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, title, ":"), html ? /*#__PURE__*/React.createElement("td", {
44
41
  dangerouslySetInnerHTML: {
45
- __html: MiscUtils.addLinkAnchors(DOMPurify.sanitize(content))
42
+ __html: MiscUtils.addLinkAnchors(MiscUtils.sanitizeHtml(content))
46
43
  }
47
44
  }) : /*#__PURE__*/React.createElement("td", null, content));
48
45
  }
49
46
  return null;
50
47
  });
51
- _defineProperty(_this, "onClose", function () {
52
- _this.props.setActiveServiceInfo(null);
53
- });
54
48
  return _this;
55
49
  }
56
50
  _inherits(ServiceInfoWindow, _React$Component);
@@ -82,7 +76,7 @@ var ServiceInfoWindow = /*#__PURE__*/function (_React$Component) {
82
76
  initialX: this.props.layerInfoGeometry.initialX,
83
77
  initialY: this.props.layerInfoGeometry.initialY,
84
78
  initiallyDocked: this.props.layerInfoGeometry.initiallyDocked,
85
- onClose: this.onClose,
79
+ onClose: this.props.onClose,
86
80
  title: LocaleUtils.tr("serviceinfo.title")
87
81
  }, /*#__PURE__*/React.createElement("div", {
88
82
  className: "service-info-window-body"
@@ -98,14 +92,7 @@ var ServiceInfoWindow = /*#__PURE__*/function (_React$Component) {
98
92
  }(React.Component);
99
93
  _defineProperty(ServiceInfoWindow, "propTypes", {
100
94
  layerInfoGeometry: PropTypes.object,
101
- service: PropTypes.object,
102
- setActiveServiceInfo: PropTypes.func
95
+ onClose: PropTypes.func,
96
+ service: PropTypes.object
103
97
  });
104
- var selector = function selector(state) {
105
- return {
106
- service: state.serviceinfo.service
107
- };
108
- };
109
- export default connect(selector, {
110
- setActiveServiceInfo: setActiveServiceInfo
111
- })(ServiceInfoWindow);
98
+ export default ServiceInfoWindow;
@@ -29,7 +29,6 @@ import React from 'react';
29
29
  import { connect } from 'react-redux';
30
30
  import axios from 'axios';
31
31
  import { remove as removeDiacritics } from 'diacritics';
32
- import DOMPurify from 'dompurify';
33
32
  import isEmpty from 'lodash.isempty';
34
33
  import PropTypes from 'prop-types';
35
34
  import { setActiveLayerInfo } from '../actions/layerinfo';
@@ -180,7 +179,7 @@ var ThemeList = /*#__PURE__*/function (_React$Component) {
180
179
  }, item.description ? /*#__PURE__*/React.createElement("div", {
181
180
  className: "theme-item-description",
182
181
  dangerouslySetInnerHTML: {
183
- __html: DOMPurify.sanitize(item.description)
182
+ __html: MiscUtils.sanitizeHtml(item.description)
184
183
  }
185
184
  }) : null, /*#__PURE__*/React.createElement("img", {
186
185
  className: "theme-item-thumbnail",
@@ -148,6 +148,8 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
148
148
  zoomToObject: function zoomToObject(objectId) {},
149
149
  objectIsVisible: function objectIsVisible(objectId) {},
150
150
  objectContainsPoints: function objectContainsPoints(object) {},
151
+ addObjectAddedListener: function addObjectAddedListener(callback) {},
152
+ removeObjectAddedListener: function removeObjectAddedListener(callback) {},
151
153
  getMap: function getMap() {},
152
154
  computeBoundsTree: function computeBoundsTree(object) {},
153
155
  setViewToExtent: function setViewToExtent(bounds, angle) {},
@@ -384,6 +386,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
384
386
  }
385
387
  _this2.computeBoundsTree(scene);
386
388
  _this2.instance.notifyChange(tiles);
389
+ _this2.notifyObjectAdded(scene);
387
390
  });
388
391
  // Show/hide labels when tile visibility changes
389
392
  tiles.tiles.addEventListener('tile-visibility-change', function (_ref3) {
@@ -394,6 +397,9 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
394
397
  l.labelObject.visible = visible;
395
398
  l.labelObject.element.style.display = visible ? 'initial' : 'none';
396
399
  });
400
+ if (visible) {
401
+ _this2.notifyObjectAdded(scene);
402
+ }
397
403
  });
398
404
  tiles.castShadow = true;
399
405
  tiles.receiveShadow = true;
@@ -473,6 +479,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
473
479
  });
474
480
  } else {
475
481
  _this2.sceneObjectGroup.add(object);
482
+ _this2.notifyObjectAdded(object);
476
483
  callback === null || callback === void 0 || callback();
477
484
  }
478
485
  _this2.objectMap[objectId] = object;
@@ -583,7 +590,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
583
590
  var changed = false;
584
591
  if (options.visibility !== prevOptions.visibility || options.opacity !== (prevOptions === null || prevOptions === void 0 ? void 0 : prevOptions.opacity)) {
585
592
  var _objectTree$options$p2;
586
- // Visibile if object is visibile and parents also
593
+ // Visible if object is visible and parents also
587
594
  var isVisible = options.opacity > 0 && options.visibility;
588
595
  for (var curId = options.parent; isVisible && curId !== undefined; curId = objectTree[curId].parent) {
589
596
  isVisible && (isVisible = objectTree[curId].visibility);
@@ -647,6 +654,11 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
647
654
  }
648
655
  });
649
656
  });
657
+ _defineProperty(_this2, "notifyObjectAdded", function (obj) {
658
+ _this2.objectAddedListeners.forEach(function (listener) {
659
+ return listener(obj);
660
+ });
661
+ });
650
662
  _defineProperty(_this2, "loadTilesetStyle", function (objectId, url) {
651
663
  var applyTilesetStyle = function applyTilesetStyle(styleurl) {
652
664
  var tiles3d = _this2.objectMap[objectId];
@@ -690,7 +702,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
690
702
  var objectTree = _this2.state.sceneContext.objectTree;
691
703
  var options = objectTree[objectId];
692
704
  var isVisible = options.opacity > 0 && options.visibility;
693
- for (var curId = options.parent; isVisible && curId !== undefined; curId = objectTree[curId].parent) {
705
+ for (var curId = options.parent; isVisible && curId !== undefined && objectTree[curId]; curId = objectTree[curId].parent) {
694
706
  isVisible && (isVisible = objectTree[curId].visibility);
695
707
  }
696
708
  return isVisible;
@@ -1302,6 +1314,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
1302
1314
  _this2.sceneObjectGroup = null;
1303
1315
  _this2.objectMap = {};
1304
1316
  _this2.tilesetStyles = {};
1317
+ _this2.objectAddedListeners = [];
1305
1318
  _this2.state.sceneContext.eventDispatcher = new EventDispatcher();
1306
1319
  _this2.state.sceneContext.addLayer = _this2.addLayer;
1307
1320
  _this2.state.sceneContext.getLayer = _this2.getLayer;
@@ -1314,6 +1327,14 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
1314
1327
  _this2.state.sceneContext.getSceneObject = _this2.getSceneObject;
1315
1328
  _this2.state.sceneContext.removeSceneObject = _this2.removeSceneObject;
1316
1329
  _this2.state.sceneContext.updateSceneObject = _this2.updateSceneObject;
1330
+ _this2.state.sceneContext.addObjectAddedListener = function (callback) {
1331
+ return _this2.objectAddedListeners.push(callback);
1332
+ };
1333
+ _this2.state.sceneContext.removeObjectAddedListener = function (callback) {
1334
+ _this2.objectAddedListeners = _this2.objectAddedListeners.filter(function (cb) {
1335
+ return cb !== callback;
1336
+ });
1337
+ };
1317
1338
  _this2.state.sceneContext.zoomToObject = _this2.zoomToObject;
1318
1339
  _this2.state.sceneContext.objectIsVisible = _this2.objectIsVisible;
1319
1340
  _this2.state.sceneContext.objectContainsPoints = _this2.objectContainsPoints;
@@ -79,12 +79,13 @@ var OrbitControls3D = /*#__PURE__*/function (_MapControls) {
79
79
  key: "disconnect",
80
80
  value: function disconnect() {
81
81
  this.animationId = null;
82
- _superPropGet(OrbitControls3D, "disconnect", this, 3)([]);
83
82
  this.enabled = false;
84
83
  this.sceneContext.scene.view.setControls(null);
85
84
  this.domElement.removeEventListener('pointerdown', this.stopAnimations);
86
85
  this.domElement.removeEventListener('wheel', this.stopAnimations);
87
86
  this.removeEventListener('change', this.updateControlsTarget);
87
+ _superPropGet(OrbitControls3D, "disconnect", this, 3)([]);
88
+ this.domElement = null;
88
89
  }
89
90
  }, {
90
91
  key: "setView",
@@ -1,5 +1,4 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
2
  function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
4
3
  function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
5
4
  function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
@@ -23,7 +22,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
23
22
  */
24
23
 
25
24
  import React from 'react';
26
- import { FacebookShareButton, LinkedinShareButton, TwitterShareButton, WhatsappShareButton, EmailShareButton, FacebookShareCount, FacebookIcon, TwitterIcon, LinkedinIcon, WhatsappIcon, EmailIcon } from 'react-share';
25
+ import { FacebookShareButton, LinkedinShareButton, TwitterShareButton, WhatsappShareButton, EmailShareButton, FacebookIcon, TwitterIcon, LinkedinIcon, WhatsappIcon, EmailIcon } from 'react-share';
27
26
  import PropTypes from 'prop-types';
28
27
  import LocaleUtils from '../../utils/LocaleUtils';
29
28
  import './style/ShareSocials.css';
@@ -52,7 +51,7 @@ var ShareSocials = /*#__PURE__*/function (_React$Component) {
52
51
  }, /*#__PURE__*/React.createElement(EmailIcon, {
53
52
  round: true,
54
53
  size: 32
55
- })), /*#__PURE__*/React.createElement("div", null, "\xA0")),
54
+ }))),
56
55
  facebook: /*#__PURE__*/React.createElement("div", {
57
56
  className: "social-box",
58
57
  key: "facebook"
@@ -62,11 +61,7 @@ var ShareSocials = /*#__PURE__*/function (_React$Component) {
62
61
  }, /*#__PURE__*/React.createElement(FacebookIcon, {
63
62
  round: true,
64
63
  size: 32
65
- })), /*#__PURE__*/React.createElement(FacebookShareCount, _extends({
66
- url: url
67
- }, countProps), function (count) {
68
- return count;
69
- })),
64
+ }))),
70
65
  twitter: /*#__PURE__*/React.createElement("div", {
71
66
  className: "social-box",
72
67
  key: "twitter"
@@ -76,7 +71,7 @@ var ShareSocials = /*#__PURE__*/function (_React$Component) {
76
71
  }, /*#__PURE__*/React.createElement(TwitterIcon, {
77
72
  round: true,
78
73
  size: 32
79
- })), /*#__PURE__*/React.createElement("div", null, "\xA0")),
74
+ }))),
80
75
  linkedin: /*#__PURE__*/React.createElement("div", {
81
76
  className: "social-box",
82
77
  key: "linkedin"
@@ -86,7 +81,7 @@ var ShareSocials = /*#__PURE__*/function (_React$Component) {
86
81
  }, /*#__PURE__*/React.createElement(LinkedinIcon, {
87
82
  round: true,
88
83
  size: 32
89
- })), /*#__PURE__*/React.createElement("div", null, "\xA0")),
84
+ }))),
90
85
  whatsapp: /*#__PURE__*/React.createElement("div", {
91
86
  className: "social-box",
92
87
  key: "whatsapp"
@@ -96,7 +91,7 @@ var ShareSocials = /*#__PURE__*/function (_React$Component) {
96
91
  }, /*#__PURE__*/React.createElement(WhatsappIcon, {
97
92
  round: true,
98
93
  size: 32
99
- })), /*#__PURE__*/React.createElement("div", null, "\xA0"))
94
+ })))
100
95
  };
101
96
  var socialBoxes = [];
102
97
  if (this.props.showSocials === true) {
@@ -125,7 +120,4 @@ _defineProperty(ShareSocials, "propTypes", {
125
120
  shareUrl: PropTypes.string,
126
121
  showSocials: PropTypes.oneOfType([PropTypes.bool, PropTypes.array])
127
122
  });
128
- _defineProperty(ShareSocials, "defaultProps", {
129
- shareTitle: 'GeoSolutions'
130
- });
131
123
  export { ShareSocials as default };
@@ -16,6 +16,16 @@ div.resizeable-window-portal-container > div {
16
16
  height: 100%;
17
17
  }
18
18
 
19
+ div.resizeable-window-portal-container-detached {
20
+ position: fixed;
21
+ left: 0;
22
+ right: 0;
23
+ bottom: 0;
24
+ top: 2.5em;
25
+ padding: 0.25em;
26
+ background-color: var(--container-bg-color);
27
+ }
28
+
19
29
  div.resizeable-window-contents {
20
30
  display: flex;
21
31
  flex-direction: column;
@@ -29,6 +29,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
29
29
  import { ColorPicker } from '@vtaits/react-color-picker';
30
30
  import '@vtaits/react-color-picker/index.css';
31
31
  import React from 'react';
32
+ import ReactDOM from 'react-dom';
32
33
  import PropTypes from 'prop-types';
33
34
  import MiscUtils from '../../utils/MiscUtils';
34
35
  import './style/ColorButton.css';
@@ -41,26 +42,36 @@ var ColorButton = /*#__PURE__*/function (_React$Component) {
41
42
  _classCallCheck(this, ColorButton);
42
43
  _this = _callSuper(this, ColorButton, [props]);
43
44
  _defineProperty(_this, "state", {
44
- colors: defaultColors
45
+ colors: defaultColors,
46
+ pickerPos: null,
47
+ hexStr: null
45
48
  });
46
49
  _defineProperty(_this, "togglePicker", function (ev) {
47
- if (!_this.state.pickerVisible) {
48
- document.addEventListener('click', _this.checkClosePicker);
49
- } else {
50
- document.removeEventListener('click', _this.checkClosePicker);
50
+ if (_this.menuContainer) {
51
+ // Should not happen...
52
+ _this.menuContainer.parentElement.removeChild(_this.menuContainer);
53
+ _this.menuContainer = null;
51
54
  }
52
- ev.stopPropagation();
53
- _this.setState(function (state) {
54
- return {
55
- hexStr: null,
56
- pickerVisible: !state.pickerVisible
57
- };
55
+ _this.menuContainer = ev.view.document.createElement("div");
56
+ _this.menuContainer.className = "colorbutton-picker-container";
57
+ ev.view.document.body.appendChild(_this.menuContainer);
58
+ _this.menuContainer.addEventListener('click', function (ev2) {
59
+ if (ev2.currentTarget === ev2.target) {
60
+ _this.setState({
61
+ pickerPos: null,
62
+ hexStr: null
63
+ }, function () {
64
+ _this.menuContainer.parentElement.removeChild(_this.menuContainer);
65
+ _this.menuContainer = null;
66
+ });
67
+ }
58
68
  });
59
- });
60
- _defineProperty(_this, "checkClosePicker", function (ev) {
61
- if (_this.pickerEl && !_this.pickerEl.contains(ev.target)) {
62
- _this.togglePicker(ev);
63
- }
69
+ var rect = ev.currentTarget.getBoundingClientRect();
70
+ _this.setState({
71
+ hexStr: null,
72
+ pickerPos: [rect.left + 0.5 * rect.width, rect.bottom]
73
+ });
74
+ ev.stopPropagation();
64
75
  });
65
76
  _defineProperty(_this, "selectColor", function (idx) {
66
77
  _this.setState({
@@ -99,11 +110,7 @@ var ColorButton = /*#__PURE__*/function (_React$Component) {
99
110
  var newColor = [].concat(_toConsumableArray(_this.props.color.slice(0, 3)), [parseFloat(alpha)]);
100
111
  _this.props.onColorChanged(newColor);
101
112
  });
102
- _this.state = {
103
- pickerVisible: false,
104
- hexStr: null
105
- };
106
- _this.pickerEl = null;
113
+ _this.menuContainer = null;
107
114
  _this.state.colors = props.defaultColors;
108
115
  return _this;
109
116
  }
@@ -112,10 +119,13 @@ var ColorButton = /*#__PURE__*/function (_React$Component) {
112
119
  key: "render",
113
120
  value: function render() {
114
121
  var _this2 = this;
115
- var pickerStyle = {
116
- visibility: this.state.pickerVisible ? 'visible' : 'hidden'
117
- };
118
122
  var curColor = this.props.color;
123
+ var pickerStyle = function pickerStyle() {
124
+ return {
125
+ left: "calc(".concat(_this2.state.pickerPos[0], "px - 6.5em)"),
126
+ top: "calc(".concat(_this2.state.pickerPos[1], "px + 0.7em)")
127
+ };
128
+ };
119
129
  return /*#__PURE__*/React.createElement("div", {
120
130
  className: "ColorButton"
121
131
  }, /*#__PURE__*/React.createElement("div", {
@@ -127,12 +137,9 @@ var ColorButton = /*#__PURE__*/function (_React$Component) {
127
137
  style: {
128
138
  backgroundColor: this.cssColor(curColor)
129
139
  }
130
- })), /*#__PURE__*/React.createElement("div", {
140
+ })), this.state.pickerPos ? /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement("div", {
131
141
  className: "colorbutton-picker",
132
- ref: function ref(el) {
133
- _this2.pickerEl = el;
134
- },
135
- style: pickerStyle
142
+ style: pickerStyle()
136
143
  }, /*#__PURE__*/React.createElement("div", {
137
144
  className: "colorbutton-picker-icons"
138
145
  }, this.state.colors.map(function (color, idx) {
@@ -156,6 +163,7 @@ var ColorButton = /*#__PURE__*/function (_React$Component) {
156
163
  className: "colorbutton-picker-spectrum",
157
164
  onDrag: this.changeColor,
158
165
  saturationHeight: 150,
166
+ saturationWidth: null,
159
167
  value: this.cssColorRGB(curColor)
160
168
  }), /*#__PURE__*/React.createElement("div", {
161
169
  className: "colorbutton-picker-input controlgroup"
@@ -182,7 +190,7 @@ var ColorButton = /*#__PURE__*/function (_React$Component) {
182
190
  step: "0.1",
183
191
  type: "range",
184
192
  value: curColor[3]
185
- }))) : null)));
193
+ }))) : null)), this.menuContainer) : null);
186
194
  }
187
195
  }, {
188
196
  key: "cssColor",