1
1
export class MapFeature extends HTMLElement {
2
2
static get observedAttributes ( ) {
3
- return [ 'zoom' , 'onfocus ' , 'onclick' , 'onblur '] ;
3
+ return [ 'zoom' , 'min ' , 'max ' ] ;
4
4
}
5
5
6
6
get zoom ( ) {
@@ -88,15 +88,6 @@ export class MapFeature extends HTMLElement {
88
88
}
89
89
break ;
90
90
}
91
- case 'onfocus' :
92
- case 'onclick' :
93
- case 'onblur' :
94
- if ( this . _groupEl ) {
95
- // "synchronize" the onevent properties (i.e. onfocus, onclick, onblur)
96
- // between the mapFeature and its associated <g> element
97
- this . _groupEl [ name ] = this [ name ] . bind ( this . _groupEl ) ;
98
- break ;
99
- }
100
91
}
101
92
}
102
93
@@ -183,15 +174,15 @@ export class MapFeature extends HTMLElement {
183
174
}
184
175
185
176
_addFeature ( ) {
186
- let parentEl =
177
+ this . _parentEl =
187
178
this . parentNode . nodeName . toUpperCase ( ) === 'LAYER-' ||
188
179
this . parentNode . nodeName . toUpperCase ( ) === 'MAP-EXTENT'
189
180
? this . parentNode
190
181
: this . parentNode . host ;
191
182
192
183
// arrow function is not hoisted, define before use
193
184
var _attachedToMap = ( e ) => {
194
- if ( ! parentEl . _layer . _map ) {
185
+ if ( ! this . _parentEl . _layer . _map ) {
195
186
// if the parent layer- el has not yet added to the map (i.e. not yet rendered), wait until it is added
196
187
this . _layer . once (
197
188
'attached' ,
@@ -229,21 +220,21 @@ export class MapFeature extends HTMLElement {
229
220
}
230
221
} ;
231
222
232
- if ( ! parentEl . _layer ) {
223
+ if ( ! this . _parentEl . _layer ) {
233
224
// for custom projection cases, the MapMLLayer has not yet created and binded with the layer- at this point,
234
225
// because the "createMap" event of mapml-viewer has not yet been dispatched, the map has not yet been created
235
226
// the event will be dispatched after defineCustomProjection > projection setter
236
227
// should wait until MapMLLayer is built
237
228
let parentLayer =
238
- parentEl . nodeName . toUpperCase ( ) === 'LAYER-'
239
- ? parentEl
240
- : parentEl . parentElement || parentEl . parentNode . host ;
229
+ this . _parentEl . nodeName . toUpperCase ( ) === 'LAYER-'
230
+ ? this . _parentEl
231
+ : this . _parentEl . parentElement || this . _parentEl . parentNode . host ;
241
232
parentLayer . parentNode . addEventListener ( 'createmap' , ( e ) => {
242
233
this . _layer = parentLayer . _layer ;
243
234
_attachedToMap ( ) ;
244
235
} ) ;
245
236
} else {
246
- this . _layer = parentEl . _layer ;
237
+ this . _layer = this . _parentEl . _layer ;
247
238
_attachedToMap ( ) ;
248
239
}
249
240
}
@@ -274,28 +265,25 @@ export class MapFeature extends HTMLElement {
274
265
}
275
266
276
267
_setUpEvents ( ) {
277
- [ 'click' , 'focus' , 'blur' ] . forEach ( ( name ) => {
278
- // onevent properties & onevent attributes
279
- if ( this [ `on${ name } ` ] && typeof this [ `on${ name } ` ] === 'function' ) {
280
- this . _groupEl [ `on${ name } ` ] = this [ `on${ name } ` ] ;
281
- }
282
- // handle event handlers set via addEventlistener
283
- // for HTMLElement
268
+ [ 'click' , 'focus' , 'blur' , 'keyup' , 'keydown' ] . forEach ( ( name ) => {
284
269
// when <g> is clicked / focused / blurred
285
270
// should dispatch the click / focus / blur event listener on **linked HTMLFeatureElements**
286
271
this . _groupEl . addEventListener ( name , ( e ) => {
287
- // this === mapFeature as arrow function does not have their own "this" pointer
288
- // store onEvent handler of mapFeature if there is any to ensure that it will not be re-triggered when the cloned mouseevent is dispatched
289
- // so that only the event handlers set on HTMLFeatureElement via addEventListener method will be triggered
290
- const handler = this [ `on${ name } ` ] ; // a deep copy, var handler will not change when this.onevent is set to null (i.e. store the onevent property)
291
- this [ `on${ name } ` ] = null ;
292
272
if ( name === 'click' ) {
293
273
// dispatch a cloned mouseevent to trigger the click event handlers set on HTMLFeatureElement
294
- this . dispatchEvent ( new PointerEvent ( name , { ...e } ) ) ;
274
+ let clickEv = new PointerEvent ( name , { cancelable : true } ) ;
275
+ clickEv . originalEvent = e ;
276
+ this . dispatchEvent ( clickEv ) ;
277
+ } else if ( name === 'keyup' || name === 'keydown' ) {
278
+ let keyEv = new KeyboardEvent ( name , { cancelable : true } ) ;
279
+ keyEv . originalEvent = e ;
280
+ this . dispatchEvent ( keyEv ) ;
295
281
} else {
296
- this . dispatchEvent ( new FocusEvent ( name , { ...e } ) ) ;
282
+ // dispatch a cloned focusevent to trigger the focus/blue event handlers set on HTMLFeatureElement
283
+ let focusEv = new FocusEvent ( name , { cancelable : true } ) ;
284
+ focusEv . originalEvent = e ;
285
+ this . dispatchEvent ( focusEv ) ;
297
286
}
298
- this [ `on${ name } ` ] = handler ;
299
287
} ) ;
300
288
} ) ;
301
289
}
@@ -324,9 +312,7 @@ export class MapFeature extends HTMLElement {
324
312
return this . _layer . _mapmlvectors . _getNativeVariables ( content ) ;
325
313
} else if ( content . nodeName . toUpperCase ( ) === 'LAYER-' ) {
326
314
// for inline features, read native zoom and cs from inline map-meta
327
- let zoomMeta = this . parentElement . querySelectorAll (
328
- 'map-meta[name=zoom]'
329
- ) ,
315
+ let zoomMeta = this . _parentEl . querySelectorAll ( 'map-meta[name=zoom]' ) ,
330
316
zoomLength = zoomMeta ?. length ;
331
317
nativeZoom = zoomLength
332
318
? + zoomMeta [ zoomLength - 1 ]
@@ -336,7 +322,7 @@ export class MapFeature extends HTMLElement {
336
322
?. split ( '=' ) [ 1 ]
337
323
: 0 ;
338
324
339
- let csMeta = this . parentElement . querySelectorAll ( 'map-meta[name=cs]' ) ,
325
+ let csMeta = this . _parentEl . querySelectorAll ( 'map-meta[name=cs]' ) ,
340
326
csLength = csMeta ?. length ;
341
327
nativeCS = csLength
342
328
? csMeta [ csLength - 1 ] . getAttribute ( 'content' )
@@ -567,68 +553,55 @@ export class MapFeature extends HTMLElement {
567
553
}
568
554
569
555
// a method that simulates a click, or invoking the user-defined click event
570
- // event (optional): a MouseEvent object, can be passed as an argument of the user-defined click event handlers
571
- click ( event ) {
556
+ click ( ) {
572
557
let g = this . _groupEl ,
573
558
rect = g . getBoundingClientRect ( ) ;
574
- if ( ! event ) {
575
- event = new MouseEvent ( 'click' , {
576
- clientX : rect . x + rect . width / 2 ,
577
- clientY : rect . y + rect . height / 2 ,
578
- button : 0
579
- } ) ;
559
+ let event = new MouseEvent ( 'click' , {
560
+ clientX : rect . x + rect . width / 2 ,
561
+ clientY : rect . y + rect . height / 2 ,
562
+ button : 0
563
+ } ) ;
564
+ let properties = this . querySelector ( 'map-properties' ) ;
565
+ if ( g . getAttribute ( 'role' ) === 'link' ) {
566
+ for ( let path of g . children ) {
567
+ path . mousedown . call ( this . _featureGroup , event ) ;
568
+ path . mouseup . call ( this . _featureGroup , event ) ;
569
+ }
580
570
}
581
- if ( typeof this . onclick === 'function' ) {
582
- this . onclick . call ( this . _groupEl , event ) ;
583
- return ;
584
- } else {
585
- let properties = this . querySelector ( 'map-properties' ) ;
586
- if ( g . getAttribute ( 'role' ) === 'link' ) {
587
- for ( let path of g . children ) {
588
- path . mousedown . call ( this . _featureGroup , event ) ;
589
- path . mouseup . call ( this . _featureGroup , event ) ;
571
+ // dispatch click event for map-feature to allow events entered by 'addEventListener'
572
+ let clickEv = new PointerEvent ( 'click' , { cancelable : true } ) ;
573
+ clickEv . originalEvent = event ;
574
+ this . dispatchEvent ( clickEv ) ;
575
+ // for custom projection, layer- element may disconnect and re-attach to the map after the click
576
+ // so check whether map-feature element is still connected before any further operations
577
+ if ( properties && this . isConnected ) {
578
+ let featureGroup = this . _featureGroup ,
579
+ shapes = featureGroup . _layers ;
580
+ // close popup if the popup is currently open
581
+ for ( let id in shapes ) {
582
+ if ( shapes [ id ] . isPopupOpen ( ) ) {
583
+ shapes [ id ] . closePopup ( ) ;
590
584
}
591
585
}
592
- // for custom projection, layer- element may disconnect and re-attach to the map after the click
593
- // so check whether map-feature element is still connected before any further operations
594
- if ( properties && this . isConnected ) {
595
- let featureGroup = this . _featureGroup ,
596
- shapes = featureGroup . _layers ;
597
- // close popup if the popup is currently open
598
- for ( let id in shapes ) {
599
- if ( shapes [ id ] . isPopupOpen ( ) ) {
600
- shapes [ id ] . closePopup ( ) ;
601
- }
602
- }
603
- if ( featureGroup . isPopupOpen ( ) ) {
604
- featureGroup . closePopup ( ) ;
605
- } else {
606
- featureGroup . openPopup ( ) ;
607
- }
586
+ if ( featureGroup . isPopupOpen ( ) ) {
587
+ featureGroup . closePopup ( ) ;
588
+ } else if ( ! clickEv . originalEvent . cancelBubble ) {
589
+ // If stopPropagation is not set on originalEvent by user
590
+ featureGroup . openPopup ( ) ;
608
591
}
609
592
}
610
593
}
611
594
612
595
// a method that sets the current focus to the <g> element, or invoking the user-defined focus event
613
- // event (optional): a FocusEvent object, can be passed as an argument of the user-defined focus event handlers
614
- // options (optional): as options parameter for native HTMLelemnt
596
+ // options (optional): as options parameter for native HTMLElement
615
597
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
616
- focus ( event , options ) {
617
- let g = this . _groupEl ;
618
- if ( typeof this . onfocus === 'function' ) {
619
- this . onfocus . call ( this . _groupEl , event ) ;
620
- return ;
621
- } else {
622
- g . focus ( options ) ;
623
- }
598
+ focus ( options ) {
599
+ this . _groupEl . focus ( options ) ;
624
600
}
625
601
626
602
// a method that makes the <g> element lose focus, or invoking the user-defined blur event
627
- // event (optional): a FocusEvent object, can be passed as an argument of the user-defined blur event handlers
628
- blur ( event ) {
629
- if ( typeof this . onblur === 'function' ) {
630
- this . onblur . call ( this . _groupEl , event ) ;
631
- } else if (
603
+ blur ( ) {
604
+ if (
632
605
document . activeElement . shadowRoot ?. activeElement === this . _groupEl ||
633
606
document . activeElement . shadowRoot ?. activeElement . parentNode ===
634
607
this . _groupEl
0 commit comments