@eeacms/volto-arcgis-block 0.1.398 → 0.1.399

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ ### [0.1.399](https://github.com/eea/volto-arcgis-block/compare/0.1.398...0.1.399) - 27 October 2025
8
+
9
+ #### :hammer_and_wrench: Others
10
+
11
+ - (lint): necessary linting [Unai Bolivar - [`2685d7d`](https://github.com/eea/volto-arcgis-block/commit/2685d7de0736db3358fd651a9c75e9d4ab39a3d7)]
12
+ - (task): added more guard clauses in xml parsing methods to handle null values [Unai Bolivar - [`345db2e`](https://github.com/eea/volto-arcgis-block/commit/345db2e8b898b8a4156901d97917b9f1573c8d3d)]
13
+ - (bug): added guard clause for empty or incorrect xml data in parsing methods [Unai Bolivar - [`24bbda1`](https://github.com/eea/volto-arcgis-block/commit/24bbda1929af9364b008a8ba239a140e98a8f93e)]
14
+ - (task): cleaned commented code from Menuwidget script and updated clean up of event listeners in TimesliderWidget script [Unai Bolivar - [`6fc8c65`](https://github.com/eea/volto-arcgis-block/commit/6fc8c659140f7b2fbcb5ee86b670f9a4fe90d12d)]
7
15
  ### [0.1.398](https://github.com/eea/volto-arcgis-block/compare/0.1.397...0.1.398) - 10 October 2025
8
16
 
9
17
  ### [0.1.397](https://github.com/eea/volto-arcgis-block/compare/0.1.396...0.1.397) - 10 October 2025
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-arcgis-block",
3
- "version": "0.1.398",
3
+ "version": "0.1.399",
4
4
  "description": "volto-arcgis-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: CodeSyntax",
@@ -3027,42 +3027,6 @@ class MenuWidget extends React.Component {
3027
3027
  }
3028
3028
  }
3029
3029
  } catch (e) {}
3030
- // try {
3031
- // const layer = this.layers[elem.id];
3032
- // const viewService = layer?.ViewService || '';
3033
- // if (
3034
- // viewService &&
3035
- // viewService.toLowerCase().includes('wms') &&
3036
- // viewService.toLowerCase().includes('/ogc/') &&
3037
- // !layer._ogcExtentApplied &&
3038
- // !this.extentInitiated
3039
- // ) {
3040
- // let url;
3041
- // const serviceLayer = this.state.wmsUserServiceLayers.find(
3042
- // (l) => l.LayerId === elem.id,
3043
- // );
3044
- // if (!serviceLayer) {
3045
- // this.findCheckedDataset(elem);
3046
- // url = this.url;
3047
- // } else {
3048
- // url = serviceLayer.ViewService;
3049
- // }
3050
- // if (url) {
3051
- // await this.getCapabilities(url, 'wms');
3052
- // const BBoxes = this.parseBBOXCDSE(this.xml);
3053
- // if (BBoxes && BBoxes['dataset']) {
3054
- // const myExtent = new Extent({
3055
- // xmin: BBoxes['dataset'].xmin,
3056
- // ymin: BBoxes['dataset'].ymin,
3057
- // xmax: BBoxes['dataset'].xmax,
3058
- // ymax: BBoxes['dataset'].ymax,
3059
- // });
3060
- // this.view.goTo(myExtent);
3061
- // layer._ogcExtentApplied = true;
3062
- // }
3063
- // }
3064
- // }
3065
- // } catch (e) {}
3066
3030
  } else {
3067
3031
  sessionStorage.removeItem('downloadButtonClicked');
3068
3032
  sessionStorage.removeItem('timeSliderTag');
@@ -3202,8 +3166,9 @@ class MenuWidget extends React.Component {
3202
3166
  addCustomItemToLegend(layer) {
3203
3167
  // Find legend widget node
3204
3168
  const legendDiv = document.querySelectorAll('.esri-widget.esri-legend')[0];
3169
+ if (!legendDiv) return;
3205
3170
  let childDiv = legendDiv.firstChild;
3206
-
3171
+ if (!childDiv) return;
3207
3172
  // create legend element
3208
3173
  if (layer.LayerTitle !== undefined) {
3209
3174
  let legendItem = this.createStaticLegendImageNode(
@@ -3608,145 +3573,158 @@ class MenuWidget extends React.Component {
3608
3573
  parseBBOXCDSE(xml) {
3609
3574
  if (!xml || typeof xml.getElementsByTagName !== 'function') return {};
3610
3575
  const all = Array.from(xml.getElementsByTagName('*'));
3611
- const isLayer = (n) => n && (n.localName || '').toLowerCase() === 'layer';
3576
+ const isLayer = (node) =>
3577
+ node && (node.localName || '').toLowerCase() === 'layer';
3612
3578
  const layers = all.filter(isLayer);
3613
3579
  if (!layers.length) return {};
3614
- const hasChildLayer = (el) => {
3615
- const cs = el ? el.children : null;
3616
- if (!cs) return false;
3617
- for (let i = 0; i < cs.length; i++) if (isLayer(cs[i])) return true;
3580
+ const hasChildLayer = (element) => {
3581
+ const children = element ? element.children : null;
3582
+ if (!children || !children.length) return false;
3583
+ for (let i = 0; i < children.length; i++)
3584
+ if (isLayer(children[i])) return true;
3618
3585
  return false;
3619
3586
  };
3620
- const findDesc = (el, nameLower) => {
3621
- if (!el) return null;
3622
- const it = el.getElementsByTagName('*');
3623
- for (let i = 0; i < it.length; i++) {
3624
- const n = it[i];
3625
- if ((n.localName || '').toLowerCase() === nameLower) return n;
3587
+ const findDesc = (element, nameLower) => {
3588
+ if (!element || typeof element.getElementsByTagName !== 'function')
3589
+ return null;
3590
+ const items = element.getElementsByTagName('*');
3591
+ for (let i = 0; i < items.length; i++) {
3592
+ const node = items[i];
3593
+ if ((node.localName || '').toLowerCase() === nameLower) return node;
3626
3594
  }
3627
3595
  return null;
3628
3596
  };
3629
- const leaves = layers.filter((n) => !hasChildLayer(n));
3597
+ const leaves = layers.filter((node) => !hasChildLayer(node));
3630
3598
  if (!leaves.length) return {};
3631
3599
  const boxes = {};
3632
- const xs = [];
3633
- const ys = [];
3600
+ const xList = [];
3601
+ const yList = [];
3634
3602
  for (let i = 0; i < leaves.length; i++) {
3635
3603
  const leaf = leaves[i];
3636
- const nameEl = findDesc(leaf, 'name');
3604
+ if (!leaf) continue;
3605
+ const nameElement = findDesc(leaf, 'name');
3637
3606
  const name =
3638
- nameEl && nameEl.textContent ? nameEl.textContent.trim() : '';
3607
+ nameElement && nameElement.textContent
3608
+ ? nameElement.textContent.trim()
3609
+ : '';
3639
3610
  if (!name) continue;
3640
- let bb = findDesc(leaf, 'boundingbox');
3641
- if (!bb) {
3642
- let p = leaf.parentElement;
3643
- while (p) {
3644
- if (isLayer(p)) {
3645
- const cand = findDesc(p, 'boundingbox');
3646
- if (cand) {
3647
- bb = cand;
3611
+ let bboxElement = findDesc(leaf, 'boundingbox');
3612
+ if (!bboxElement) {
3613
+ let parent = leaf.parentElement;
3614
+ while (parent) {
3615
+ if (isLayer(parent)) {
3616
+ const candidate = findDesc(parent, 'boundingbox');
3617
+ if (candidate) {
3618
+ bboxElement = candidate;
3648
3619
  break;
3649
3620
  }
3650
3621
  }
3651
- p = p.parentElement;
3622
+ parent = parent.parentElement;
3652
3623
  }
3653
3624
  }
3654
- if (!bb) continue;
3655
- const w = parseFloat(bb.getAttribute('minx') || '');
3656
- const s = parseFloat(bb.getAttribute('miny') || '');
3657
- const e = parseFloat(bb.getAttribute('maxx') || '');
3658
- const n = parseFloat(bb.getAttribute('maxy') || '');
3659
- if (!isFinite(w) || !isFinite(s) || !isFinite(e) || !isFinite(n))
3625
+ if (!bboxElement) continue;
3626
+ const west = parseFloat(bboxElement.getAttribute('minx') || '');
3627
+ const south = parseFloat(bboxElement.getAttribute('miny') || '');
3628
+ const east = parseFloat(bboxElement.getAttribute('maxx') || '');
3629
+ const north = parseFloat(bboxElement.getAttribute('maxy') || '');
3630
+ if (
3631
+ !isFinite(west) ||
3632
+ !isFinite(south) ||
3633
+ !isFinite(east) ||
3634
+ !isFinite(north)
3635
+ )
3660
3636
  continue;
3661
- boxes[name] = { xmin: w, ymin: s, xmax: e, ymax: n };
3662
- xs.push(w, e);
3663
- ys.push(s, n);
3637
+ boxes[name] = { xmin: west, ymin: south, xmax: east, ymax: north };
3638
+ xList.push(west, east);
3639
+ yList.push(south, north);
3664
3640
  }
3665
3641
  if (!Object.keys(boxes).length) return {};
3642
+ if (!xList.length || !yList.length) return boxes;
3666
3643
  boxes.dataset = {
3667
- xmin: Math.min.apply(Math, xs),
3668
- ymin: Math.min.apply(Math, ys),
3669
- xmax: Math.max.apply(Math, xs),
3670
- ymax: Math.max.apply(Math, ys),
3644
+ xmin: Math.min.apply(Math, xList),
3645
+ ymin: Math.min.apply(Math, yList),
3646
+ xmax: Math.max.apply(Math, xList),
3647
+ ymax: Math.max.apply(Math, yList),
3671
3648
  };
3672
3649
  return boxes;
3673
3650
  }
3674
3651
 
3675
3652
  parseBBOXWMS(xml) {
3653
+ if (
3654
+ !xml ||
3655
+ typeof xml.querySelectorAll !== 'function' ||
3656
+ typeof xml.getElementsByTagName !== 'function'
3657
+ )
3658
+ return {};
3676
3659
  const layerParentNode = xml.querySelectorAll('Layer');
3660
+ if (!layerParentNode || layerParentNode.length === 0) return {};
3677
3661
  let layersChildren = Array.from(layerParentNode).filter(
3678
- (v) => v.querySelectorAll('Layer').length === 0,
3662
+ (v) =>
3663
+ v && v.querySelectorAll && v.querySelectorAll('Layer').length === 0,
3679
3664
  );
3680
3665
  let layerParent = Array.from(layerParentNode).filter(
3681
- (v) => v.querySelectorAll('Layer').length !== 0,
3666
+ (v) =>
3667
+ v && v.querySelectorAll && v.querySelectorAll('Layer').length !== 0,
3682
3668
  );
3669
+ if (!layersChildren.length && !layerParent.length) return {};
3683
3670
  let BBoxes = {};
3684
- let layerGeoGraphic = {};
3671
+ let layerGeographicNode = {};
3685
3672
  let xList = [];
3686
3673
  let yList = [];
3687
3674
  for (let i in layersChildren) {
3688
- if (
3689
- layersChildren[i].querySelector('EX_GeographicBoundingBox') !== null
3690
- ) {
3691
- // If the layer has BBOX
3692
- layerGeoGraphic = layersChildren[i].querySelector(
3693
- 'EX_GeographicBoundingBox',
3694
- );
3675
+ const child = layersChildren[i];
3676
+ if (!child || typeof child.querySelector !== 'function') continue;
3677
+ const bboxNode = child.querySelector('EX_GeographicBoundingBox');
3678
+ if (bboxNode !== null) {
3679
+ layerGeographicNode = bboxNode;
3695
3680
  } else {
3696
- // If the layer has no BBOX, it was assigned dataset BBOX
3697
- layerGeoGraphic = layerParent[0].querySelector(
3698
- 'EX_GeographicBoundingBox',
3699
- );
3681
+ const parentNode =
3682
+ layerParent && layerParent.length ? layerParent[0] : null;
3683
+ layerGeographicNode =
3684
+ parentNode && typeof parentNode.querySelector === 'function'
3685
+ ? parentNode.querySelector('EX_GeographicBoundingBox')
3686
+ : null;
3700
3687
  }
3701
- BBoxes[layersChildren[i].querySelector('Name').innerText] = {
3702
- xmin: Number(
3703
- layerGeoGraphic.querySelector('westBoundLongitude').innerText,
3704
- ),
3705
- ymin: Number(
3706
- layerGeoGraphic.querySelector('southBoundLatitude').innerText,
3707
- ),
3708
- xmax: Number(
3709
- layerGeoGraphic.querySelector('eastBoundLongitude').innerText,
3710
- ),
3711
- ymax: Number(
3712
- layerGeoGraphic.querySelector('northBoundLatitude').innerText,
3713
- ),
3688
+ const nameNode = child.querySelector('Name');
3689
+ const key =
3690
+ nameNode && typeof nameNode.innerText === 'string'
3691
+ ? nameNode.innerText
3692
+ : '';
3693
+ if (!layerGeographicNode || !key) continue;
3694
+ const westNode = layerGeographicNode.querySelector('westBoundLongitude');
3695
+ const southNode = layerGeographicNode.querySelector('southBoundLatitude');
3696
+ const eastNode = layerGeographicNode.querySelector('eastBoundLongitude');
3697
+ const northNode = layerGeographicNode.querySelector('northBoundLatitude');
3698
+ if (!westNode || !southNode || !eastNode || !northNode) continue;
3699
+ const xmin = Number(westNode.innerText);
3700
+ const ymin = Number(southNode.innerText);
3701
+ const xmax = Number(eastNode.innerText);
3702
+ const ymax = Number(northNode.innerText);
3703
+ if (
3704
+ !isFinite(xmin) ||
3705
+ !isFinite(ymin) ||
3706
+ !isFinite(xmax) ||
3707
+ !isFinite(ymax)
3708
+ )
3709
+ continue;
3710
+ BBoxes[key] = {
3711
+ xmin: xmin,
3712
+ ymin: ymin,
3713
+ xmax: xmax,
3714
+ ymax: ymax,
3714
3715
  };
3715
- xList.push(
3716
- BBoxes[layersChildren[i].querySelector('Name').innerText].xmin,
3717
- );
3718
- yList.push(
3719
- BBoxes[layersChildren[i].querySelector('Name').innerText].ymin,
3720
- );
3721
- xList.push(
3722
- BBoxes[layersChildren[i].querySelector('Name').innerText].xmax,
3723
- );
3724
- yList.push(
3725
- BBoxes[layersChildren[i].querySelector('Name').innerText].ymax,
3726
- );
3716
+ xList.push(BBoxes[key].xmin);
3717
+ yList.push(BBoxes[key].ymin);
3718
+ xList.push(BBoxes[key].xmax);
3719
+ yList.push(BBoxes[key].ymax);
3727
3720
  } // For loop
3728
- // Add dataset bbox
3721
+ if (!xList.length || !yList.length) return {};
3729
3722
  BBoxes['dataset'] = {
3730
3723
  xmin: Math.min.apply(Math, xList),
3731
3724
  ymin: Math.min.apply(Math, yList),
3732
3725
  xmax: Math.max.apply(Math, xList),
3733
3726
  ymax: Math.max.apply(Math, yList),
3734
3727
  };
3735
- // layerGeoGraphic = layerParent[0].querySelector('EX_GeographicBoundingBox');
3736
- // BBoxes['dataset'] = {
3737
- // xmin: Number(
3738
- // layerGeoGraphic.querySelector('westBoundLongitude').innerText,
3739
- // ),
3740
- // ymin: Number(
3741
- // layerGeoGraphic.querySelector('southBoundLatitude').innerText,
3742
- // ),
3743
- // xmax: Number(
3744
- // layerGeoGraphic.querySelector('eastBoundLongitude').innerText,
3745
- // ),
3746
- // ymax: Number(
3747
- // layerGeoGraphic.querySelector('northBoundLatitude').innerText,
3748
- // ),
3749
- // };
3750
3728
  return BBoxes;
3751
3729
  } // function parseWMS
3752
3730
 
@@ -3756,55 +3734,89 @@ class MenuWidget extends React.Component {
3756
3734
 
3757
3735
  // Web Map Tiled Services WMTS
3758
3736
  parseBBOXWMTS(xml) {
3737
+ if (
3738
+ !xml ||
3739
+ typeof xml.querySelectorAll !== 'function' ||
3740
+ typeof xml.getElementsByTagName !== 'function'
3741
+ )
3742
+ return {};
3759
3743
  let BBoxes = {};
3760
3744
  let layersChildren = null;
3761
3745
  let layerParent = null;
3762
3746
  const layerParentNode = xml.querySelectorAll('Layer');
3747
+ if (!layerParentNode || layerParentNode.length === 0) return {};
3763
3748
  layersChildren = Array.from(layerParentNode).filter(
3764
- (v) => v.querySelectorAll('Layer').length === 0,
3749
+ (v) =>
3750
+ v && v.querySelectorAll && v.querySelectorAll('Layer').length === 0,
3765
3751
  );
3766
3752
  layerParent = Array.from(layerParentNode).filter(
3767
- (v) => v.querySelectorAll('Layer').length !== 0,
3753
+ (v) =>
3754
+ v && v.querySelectorAll && v.querySelectorAll('Layer').length !== 0,
3768
3755
  );
3769
- let LowerCorner,
3770
- UpperCorner = [];
3756
+ if (!layersChildren.length && !layerParent.length) return {};
3757
+ let lowerCornerValues,
3758
+ upperCornerValues = [];
3771
3759
  let xList = [];
3772
3760
  let yList = [];
3773
3761
  let title = '';
3774
3762
  for (let i in layersChildren) {
3763
+ const child = layersChildren[i];
3764
+ if (!child) continue;
3765
+ const lowerCornerNodes = this.parseCapabilities(child, 'ows:LowerCorner');
3766
+ const upperCornerNodes = this.parseCapabilities(child, 'ows:UpperCorner');
3775
3767
  if (
3776
- this.parseCapabilities(layersChildren[i], 'ows:LowerCorner').length !==
3777
- 0
3778
- ) {
3779
- // If the layer has BBOX
3780
- LowerCorner = this.parseCapabilities(
3781
- layersChildren[i],
3782
- 'ows:LowerCorner',
3783
- )[0].innerText.split(' ');
3784
- UpperCorner = this.parseCapabilities(
3785
- layersChildren[i],
3786
- 'ows:UpperCorner',
3787
- )[0].innerText.split(' ');
3788
- } else if (
3789
- this.parseCapabilities(layerParent, 'ows:LowerCorner').length !== 0
3768
+ lowerCornerNodes &&
3769
+ lowerCornerNodes.length !== 0 &&
3770
+ upperCornerNodes &&
3771
+ upperCornerNodes.length !== 0
3790
3772
  ) {
3791
- // If the layer has no BBOX, it was assigned dataset BBOX
3792
- LowerCorner = this.parseCapabilities(
3793
- layerParent,
3794
- 'ows:LowerCorner',
3795
- )[0].innerText.split(' ');
3796
- UpperCorner = this.parseCapabilities(
3797
- layerParent,
3798
- 'ows:UpperCorner',
3799
- )[0].innerText.split(' ');
3773
+ lowerCornerValues = lowerCornerNodes[0].innerText.split(' ');
3774
+ upperCornerValues = upperCornerNodes[0].innerText.split(' ');
3775
+ } else {
3776
+ const parentNode =
3777
+ layerParent && layerParent.length ? layerParent[0] : null;
3778
+ const parentLower = parentNode
3779
+ ? this.parseCapabilities(parentNode, 'ows:LowerCorner')
3780
+ : null;
3781
+ const parentUpper = parentNode
3782
+ ? this.parseCapabilities(parentNode, 'ows:UpperCorner')
3783
+ : null;
3784
+ if (
3785
+ parentLower &&
3786
+ parentLower.length !== 0 &&
3787
+ parentUpper &&
3788
+ parentUpper.length !== 0
3789
+ ) {
3790
+ lowerCornerValues = parentLower[0].innerText.split(' ');
3791
+ upperCornerValues = parentUpper[0].innerText.split(' ');
3792
+ } else {
3793
+ continue;
3794
+ }
3800
3795
  }
3801
- title = this.parseCapabilities(layersChildren[i], 'ows:Title')[0]
3802
- .innerText;
3796
+ const titleNodes = this.parseCapabilities(child, 'ows:Title');
3797
+ if (
3798
+ !titleNodes ||
3799
+ !titleNodes[0] ||
3800
+ typeof titleNodes[0].innerText !== 'string'
3801
+ )
3802
+ continue;
3803
+ title = titleNodes[0].innerText;
3804
+ const xmin = Number(lowerCornerValues[0]);
3805
+ const ymin = Number(lowerCornerValues[1]);
3806
+ const xmax = Number(upperCornerValues[0]);
3807
+ const ymax = Number(upperCornerValues[1]);
3808
+ if (
3809
+ !isFinite(xmin) ||
3810
+ !isFinite(ymin) ||
3811
+ !isFinite(xmax) ||
3812
+ !isFinite(ymax)
3813
+ )
3814
+ continue;
3803
3815
  BBoxes[title] = {
3804
- xmin: Number(LowerCorner[0]),
3805
- ymin: Number(LowerCorner[1]),
3806
- xmax: Number(UpperCorner[0]),
3807
- ymax: Number(UpperCorner[1]),
3816
+ xmin: Number(lowerCornerValues[0]),
3817
+ ymin: Number(lowerCornerValues[1]),
3818
+ xmax: Number(upperCornerValues[0]),
3819
+ ymax: Number(upperCornerValues[1]),
3808
3820
  };
3809
3821
  xList.push(BBoxes[title].xmin);
3810
3822
  yList.push(BBoxes[title].ymin);
@@ -3812,34 +3824,13 @@ class MenuWidget extends React.Component {
3812
3824
  yList.push(BBoxes[title].ymax);
3813
3825
  } // For loop
3814
3826
 
3827
+ if (!xList.length || !yList.length) return {};
3815
3828
  BBoxes['dataset'] = {
3816
3829
  xmin: Math.min.apply(Math, xList),
3817
3830
  ymin: Math.min.apply(Math, yList),
3818
3831
  xmax: Math.max.apply(Math, xList),
3819
3832
  ymax: Math.max.apply(Math, yList),
3820
3833
  };
3821
-
3822
- // if (
3823
- // typeof layerParent === 'object' &&
3824
- // layerParent !== null &&
3825
- // 'getElementsByTagName' in layerParent
3826
- // ) {
3827
- // LowerCorner = this.parseCapabilities(
3828
- // layerParent,
3829
- // 'ows:LowerCorner',
3830
- // )[0]?.innerText.split(' ');
3831
- // UpperCorner = this.parseCapabilities(
3832
- // layerParent,
3833
- // 'ows:UpperCorner',
3834
- // )[0].innerText.split(' ');
3835
-
3836
- // BBoxes['dataset'] = {
3837
- // xmin: Number(LowerCorner[0]),
3838
- // ymin: Number(LowerCorner[1]),
3839
- // xmax: Number(UpperCorner[0]),
3840
- // ymax: Number(UpperCorner[1]),
3841
- // };
3842
- // }
3843
3834
  return BBoxes;
3844
3835
  }
3845
3836
 
@@ -55,6 +55,9 @@ class TimesliderWidget extends React.Component {
55
55
  'none';
56
56
  }
57
57
  this._cdseApplied = false;
58
+ this._watchHandles = [];
59
+ this._isMounted = false;
60
+ this._closeHandler = null;
58
61
  }
59
62
 
60
63
  loader() {
@@ -316,23 +319,27 @@ class TimesliderWidget extends React.Component {
316
319
  };
317
320
  }
318
321
  }
319
- this.TimesliderWidget.watch('timeExtent', (timeExtent) => {
320
- if (!this.container.current ? true : false) {
321
- this.TimesliderWidget.stop();
322
- }
323
- if (this.layer.type === 'wmts') {
324
- this.layer.customLayerParameters = {
325
- SHOWLOGO: false,
326
- };
327
- this.layer.customLayerParameters['TIME'] =
328
- timeDict[this.TimesliderWidget.timeExtent.end];
329
- } else {
330
- this.layer.customLayerParameters = {};
331
- this.layer.customLayerParameters['TIME'] =
332
- timeDict[this.TimesliderWidget.timeExtent.end];
333
- }
334
- this.layer.refresh();
335
- });
322
+ const watchHandle = this.TimesliderWidget.watch(
323
+ 'timeExtent',
324
+ (timeExtent) => {
325
+ if (!this.container.current ? true : false) {
326
+ this.TimesliderWidget.stop();
327
+ }
328
+ if (this.layer.type === 'wmts') {
329
+ this.layer.customLayerParameters = {
330
+ SHOWLOGO: false,
331
+ };
332
+ this.layer.customLayerParameters['TIME'] =
333
+ timeDict[this.TimesliderWidget.timeExtent.end];
334
+ } else {
335
+ this.layer.customLayerParameters = {};
336
+ this.layer.customLayerParameters['TIME'] =
337
+ timeDict[this.TimesliderWidget.timeExtent.end];
338
+ }
339
+ this.layer.refresh();
340
+ },
341
+ );
342
+ this._watchHandles.push(watchHandle);
336
343
  } catch (e) {}
337
344
  }
338
345
 
@@ -340,11 +347,13 @@ class TimesliderWidget extends React.Component {
340
347
  * This method is executed after the rener method is executed
341
348
  */
342
349
  async componentDidMount() {
350
+ this._isMounted = true;
343
351
  await this.loader();
344
352
  let playRateValue =
345
353
  this.layer.ProductId === '8474c3b080fa42cc837f1d2338fcf096' ? 4000 : 1000;
346
354
  if (!this.container.current) return;
347
355
  this.props.view.when(() => {
356
+ if (!this._isMounted) return;
348
357
  this.TimesliderWidget = new TimeSlider({
349
358
  view: this.props.view,
350
359
  container: document.querySelector('.timeslider-panel'),
@@ -417,23 +426,24 @@ class TimesliderWidget extends React.Component {
417
426
  );
418
427
  this.container.current.style.display = 'block';
419
428
  this.setState({ showDatePanel: true });
420
-
429
+ this._closeHandler = () => {
430
+ this.props.time.elem.querySelector('.active-layer-time').click();
431
+ if (this.props.fromDownload) {
432
+ if (this.props.download) {
433
+ document.getElementById('download_label').click();
434
+ } else {
435
+ document.getElementById('products_label').click();
436
+ }
437
+ }
438
+ };
421
439
  document
422
440
  .querySelector('#timeslider_close')
423
- .addEventListener('click', () => {
424
- this.props.time.elem.querySelector('.active-layer-time').click();
425
- if (this.props.fromDownload) {
426
- if (this.props.download) {
427
- document.getElementById('download_label').click();
428
- } else {
429
- document.getElementById('products_label').click();
430
- }
431
- }
432
- });
441
+ .addEventListener('click', this._closeHandler);
433
442
 
434
443
  this.props.view
435
444
  .whenLayerView(this.layer, this.TimesliderWidget)
436
445
  .then(async (lv) => {
446
+ if (!this._isMounted) return;
437
447
  this.url = lv?.layer?.viewService ?? this.layer?.url ?? null;
438
448
  const urlNorm =
439
449
  typeof this.url === 'string'
@@ -446,11 +456,13 @@ class TimesliderWidget extends React.Component {
446
456
  this.TimesliderWidget.stops = {
447
457
  interval: this.layer.timeInfo.interval,
448
458
  };
449
- this.TimesliderWidget.watch('timeExtent', (timeExtent) => {
450
- if (!this.container.current ? true : false) {
451
- this.TimesliderWidget.stop();
452
- }
453
- /*let start = new Date(timeExtent.start).getTime();
459
+ const watchHandle = this.TimesliderWidget.watch(
460
+ 'timeExtent',
461
+ (timeExtent) => {
462
+ if (!this.container.current ? true : false) {
463
+ this.TimesliderWidget.stop();
464
+ }
465
+ /*let start = new Date(timeExtent.start).getTime();
454
466
  let end = new Date(timeExtent.end).getTime();
455
467
  this.props.time.elem.setAttribute('time-start', start);
456
468
  this.props.time.elem.setAttribute('time-end', end);
@@ -460,7 +472,9 @@ class TimesliderWidget extends React.Component {
460
472
  }
461
473
  this.props.time.dataset.setAttribute('time-start', start);
462
474
  this.props.time.dataset.setAttribute('time-end', end);*/
463
- });
475
+ },
476
+ );
477
+ this._watchHandles.push(watchHandle);
464
478
  } else {
465
479
  let serviceType = '';
466
480
  if (this.layer.type === 'wms') {
@@ -488,6 +502,7 @@ class TimesliderWidget extends React.Component {
488
502
  } else {
489
503
  //place getCapabilties in here
490
504
  this.getCapabilities(this.layer.url, serviceType).then((xml) => {
505
+ if (!this._isMounted) return;
491
506
  if (this.layer.type === 'wms') {
492
507
  times = this.parseTimeWMS(xml);
493
508
  } else if (this.layer.type === 'wmts') {
@@ -578,45 +593,49 @@ class TimesliderWidget extends React.Component {
578
593
  };
579
594
  }
580
595
  }
581
- this.TimesliderWidget.watch('timeExtent', (timeExtent) => {
582
- if (!this.container.current ? true : false) {
583
- this.TimesliderWidget.stop();
584
- }
585
- // let start = new Date(timeExtent.start).getTime();
586
- // let end = new Date(timeExtent.end).getTime();
587
- // this.props.time.elem.setAttribute('time-start', start);
588
- // this.props.time.elem.setAttribute('time-end', end);
589
- // if (this.props.download) {
590
- // this.props.time.dataset.setAttribute('time-start', start);
591
- // this.props.time.dataset.setAttribute('time-end', end);
592
- // }
593
- // this.props.time.dataset.setAttribute('time-start', start);
594
- // this.props.time.dataset.setAttribute('time-end', end);
595
- if (this.layer.type === 'wmts') {
596
- this.layer.customLayerParameters = {};
597
- this.layer.customLayerParameters['TIME'] =
598
- timeDict[this.TimesliderWidget.timeExtent.end];
599
- } else {
600
- this.layer.customLayerParameters = {};
601
- if (times[this.layerName].hasOwnProperty('array')) {
596
+ const watchHandle = this.TimesliderWidget.watch(
597
+ 'timeExtent',
598
+ (timeExtent) => {
599
+ if (!this.container.current ? true : false) {
600
+ this.TimesliderWidget.stop();
601
+ }
602
+ // let start = new Date(timeExtent.start).getTime();
603
+ // let end = new Date(timeExtent.end).getTime();
604
+ // this.props.time.elem.setAttribute('time-start', start);
605
+ // this.props.time.elem.setAttribute('time-end', end);
606
+ // if (this.props.download) {
607
+ // this.props.time.dataset.setAttribute('time-start', start);
608
+ // this.props.time.dataset.setAttribute('time-end', end);
609
+ // }
610
+ // this.props.time.dataset.setAttribute('time-start', start);
611
+ // this.props.time.dataset.setAttribute('time-end', end);
612
+ if (this.layer.type === 'wmts') {
613
+ this.layer.customLayerParameters = {};
602
614
  this.layer.customLayerParameters['TIME'] =
603
615
  timeDict[this.TimesliderWidget.timeExtent.end];
604
616
  } else {
605
- const newDateTimeObject = new Date(
606
- this.TimesliderWidget.timeExtent.start.toISOString(),
607
- );
608
- newDateTimeObject.setMinutes(
609
- this.TimesliderWidget.timeExtent.start.getMinutes() +
610
- this.TimesliderWidget.stops['interval'].value,
611
- );
612
- this.layer.customLayerParameters['TIME'] =
613
- this.TimesliderWidget.timeExtent.start.toISOString() +
614
- '/' +
615
- newDateTimeObject.toISOString(); //OK
617
+ this.layer.customLayerParameters = {};
618
+ if (times[this.layerName].hasOwnProperty('array')) {
619
+ this.layer.customLayerParameters['TIME'] =
620
+ timeDict[this.TimesliderWidget.timeExtent.end];
621
+ } else {
622
+ const newDateTimeObject = new Date(
623
+ this.TimesliderWidget.timeExtent.start.toISOString(),
624
+ );
625
+ newDateTimeObject.setMinutes(
626
+ this.TimesliderWidget.timeExtent.start.getMinutes() +
627
+ this.TimesliderWidget.stops['interval'].value,
628
+ );
629
+ this.layer.customLayerParameters['TIME'] =
630
+ this.TimesliderWidget.timeExtent.start.toISOString() +
631
+ '/' +
632
+ newDateTimeObject.toISOString(); //OK
633
+ }
616
634
  }
617
- }
618
- this.layer.refresh();
619
- });
635
+ this.layer.refresh();
636
+ },
637
+ );
638
+ this._watchHandles.push(watchHandle);
620
639
  } // if there is dimension time
621
640
  else {
622
641
  this.TimesliderWidget.disabled = true;
@@ -628,6 +647,45 @@ class TimesliderWidget extends React.Component {
628
647
  });
629
648
  } //componentDidMount
630
649
 
650
+ componentWillUnmount() {
651
+ this._isMounted = false;
652
+ if (this._watchHandles && this._watchHandles.length) {
653
+ for (let i = 0; i < this._watchHandles.length; i++) {
654
+ try {
655
+ if (this._watchHandles[i] && this._watchHandles[i].remove) {
656
+ this._watchHandles[i].remove();
657
+ }
658
+ } catch (e) {}
659
+ }
660
+ this._watchHandles = [];
661
+ }
662
+ const closeElement = document.querySelector('#timeslider_close');
663
+ if (closeElement && this._closeHandler) {
664
+ try {
665
+ closeElement.removeEventListener('click', this._closeHandler);
666
+ } catch (e) {}
667
+ }
668
+ try {
669
+ const uiCorner = document.querySelector(
670
+ '.esri-ui-bottom-right.esri-ui-corner',
671
+ );
672
+ if (uiCorner) {
673
+ uiCorner.style.pointerEvents = '';
674
+ }
675
+ } catch (e) {}
676
+ try {
677
+ if (this.props.view && this.container && this.container.current) {
678
+ this.props.view.ui.remove(this.container.current);
679
+ }
680
+ } catch (e) {}
681
+ try {
682
+ if (this.TimesliderWidget) {
683
+ this.TimesliderWidget.stop();
684
+ this.TimesliderWidget.destroy();
685
+ }
686
+ } catch (e) {}
687
+ }
688
+
631
689
  componentDidUpdate(prevProps) {
632
690
  if (!this.TimesliderWidget) return;
633
691
  const url = this.layer?.url || '';