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
this . _groupEl . _feature = this ;
@@ -275,28 +266,25 @@ export class MapFeature extends HTMLElement {
275
266
}
276
267
277
268
_setUpEvents ( ) {
278
- [ 'click' , 'focus' , 'blur' ] . forEach ( ( name ) => {
279
- // onevent properties & onevent attributes
280
- if ( this [ `on${ name } ` ] && typeof this [ `on${ name } ` ] === 'function' ) {
281
- this . _groupEl [ `on${ name } ` ] = this [ `on${ name } ` ] ;
282
- }
283
- // handle event handlers set via addEventlistener
284
- // for HTMLElement
269
+ [ 'click' , 'focus' , 'blur' , 'keyup' , 'keydown' ] . forEach ( ( name ) => {
285
270
// when <g> is clicked / focused / blurred
286
271
// should dispatch the click / focus / blur event listener on **linked HTMLFeatureElements**
287
272
this . _groupEl . addEventListener ( name , ( e ) => {
288
- // this === mapFeature as arrow function does not have their own "this" pointer
289
- // store onEvent handler of mapFeature if there is any to ensure that it will not be re-triggered when the cloned mouseevent is dispatched
290
- // so that only the event handlers set on HTMLFeatureElement via addEventListener method will be triggered
291
- 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)
292
- this [ `on${ name } ` ] = null ;
293
273
if ( name === 'click' ) {
294
274
// dispatch a cloned mouseevent to trigger the click event handlers set on HTMLFeatureElement
295
- this . dispatchEvent ( new PointerEvent ( name , { ...e } ) ) ;
275
+ let clickEv = new PointerEvent ( name , { cancelable : true } ) ;
276
+ clickEv . originalEvent = e ;
277
+ this . dispatchEvent ( clickEv ) ;
278
+ } else if ( name === 'keyup' || name === 'keydown' ) {
279
+ let keyEv = new KeyboardEvent ( name , { cancelable : true } ) ;
280
+ keyEv . originalEvent = e ;
281
+ this . dispatchEvent ( keyEv ) ;
296
282
} else {
297
- this . dispatchEvent ( new FocusEvent ( name , { ...e } ) ) ;
283
+ // dispatch a cloned focusevent to trigger the focus/blue event handlers set on HTMLFeatureElement
284
+ let focusEv = new FocusEvent ( name , { cancelable : true } ) ;
285
+ focusEv . originalEvent = e ;
286
+ this . dispatchEvent ( focusEv ) ;
298
287
}
299
- this [ `on${ name } ` ] = handler ;
300
288
} ) ;
301
289
} ) ;
302
290
}
@@ -343,9 +331,7 @@ export class MapFeature extends HTMLElement {
343
331
return this . _layer . _mapmlvectors . _getNativeVariables ( content ) ;
344
332
} else if ( content . nodeName . toUpperCase ( ) === 'LAYER-' ) {
345
333
// for inline features, read native zoom and cs from inline map-meta
346
- let zoomMeta = this . parentElement . querySelectorAll (
347
- 'map-meta[name=zoom]'
348
- ) ,
334
+ let zoomMeta = this . _parentEl . querySelectorAll ( 'map-meta[name=zoom]' ) ,
349
335
zoomLength = zoomMeta ?. length ;
350
336
nativeZoom = zoomLength
351
337
? + zoomMeta [ zoomLength - 1 ]
@@ -355,7 +341,7 @@ export class MapFeature extends HTMLElement {
355
341
?. split ( '=' ) [ 1 ]
356
342
: 0 ;
357
343
358
- let csMeta = this . parentElement . querySelectorAll ( 'map-meta[name=cs]' ) ,
344
+ let csMeta = this . _parentEl . querySelectorAll ( 'map-meta[name=cs]' ) ,
359
345
csLength = csMeta ?. length ;
360
346
nativeCS = csLength
361
347
? csMeta [ csLength - 1 ] . getAttribute ( 'content' )
@@ -588,68 +574,55 @@ export class MapFeature extends HTMLElement {
588
574
}
589
575
590
576
// a method that simulates a click, or invoking the user-defined click event
591
- // event (optional): a MouseEvent object, can be passed as an argument of the user-defined click event handlers
592
- click ( event ) {
577
+ click ( ) {
593
578
let g = this . _groupEl ,
594
579
rect = g . getBoundingClientRect ( ) ;
595
- if ( ! event ) {
596
- event = new MouseEvent ( 'click' , {
597
- clientX : rect . x + rect . width / 2 ,
598
- clientY : rect . y + rect . height / 2 ,
599
- button : 0
600
- } ) ;
580
+ let event = new MouseEvent ( 'click' , {
581
+ clientX : rect . x + rect . width / 2 ,
582
+ clientY : rect . y + rect . height / 2 ,
583
+ button : 0
584
+ } ) ;
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 ) ;
590
+ }
601
591
}
602
- if ( typeof this . onclick === 'function' ) {
603
- this . onclick . call ( this . _groupEl , event ) ;
604
- return ;
605
- } else {
606
- let properties = this . querySelector ( 'map-properties' ) ;
607
- if ( g . getAttribute ( 'role' ) === 'link' ) {
608
- for ( let path of g . children ) {
609
- path . mousedown . call ( this . _featureGroup , event ) ;
610
- path . mouseup . call ( this . _featureGroup , event ) ;
592
+ // dispatch click event for map-feature to allow events entered by 'addEventListener'
593
+ let clickEv = new PointerEvent ( 'click' , { cancelable : true } ) ;
594
+ clickEv . originalEvent = event ;
595
+ this . dispatchEvent ( clickEv ) ;
596
+ // for custom projection, layer- element may disconnect and re-attach to the map after the click
597
+ // so check whether map-feature element is still connected before any further operations
598
+ if ( properties && this . isConnected ) {
599
+ let featureGroup = this . _featureGroup ,
600
+ shapes = featureGroup . _layers ;
601
+ // close popup if the popup is currently open
602
+ for ( let id in shapes ) {
603
+ if ( shapes [ id ] . isPopupOpen ( ) ) {
604
+ shapes [ id ] . closePopup ( ) ;
611
605
}
612
606
}
613
- // for custom projection, layer- element may disconnect and re-attach to the map after the click
614
- // so check whether map-feature element is still connected before any further operations
615
- if ( properties && this . isConnected ) {
616
- let featureGroup = this . _featureGroup ,
617
- shapes = featureGroup . _layers ;
618
- // close popup if the popup is currently open
619
- for ( let id in shapes ) {
620
- if ( shapes [ id ] . isPopupOpen ( ) ) {
621
- shapes [ id ] . closePopup ( ) ;
622
- }
623
- }
624
- if ( featureGroup . isPopupOpen ( ) ) {
625
- featureGroup . closePopup ( ) ;
626
- } else {
627
- featureGroup . openPopup ( ) ;
628
- }
607
+ if ( featureGroup . isPopupOpen ( ) ) {
608
+ featureGroup . closePopup ( ) ;
609
+ } else if ( ! clickEv . originalEvent . cancelBubble ) {
610
+ // If stopPropagation is not set on originalEvent by user
611
+ featureGroup . openPopup ( ) ;
629
612
}
630
613
}
631
614
}
632
615
633
616
// a method that sets the current focus to the <g> element, or invoking the user-defined focus event
634
- // event (optional): a FocusEvent object, can be passed as an argument of the user-defined focus event handlers
635
- // options (optional): as options parameter for native HTMLelemnt
617
+ // options (optional): as options parameter for native HTMLElement
636
618
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
637
- focus ( event , options ) {
638
- let g = this . _groupEl ;
639
- if ( typeof this . onfocus === 'function' ) {
640
- this . onfocus . call ( this . _groupEl , event ) ;
641
- return ;
642
- } else {
643
- g . focus ( options ) ;
644
- }
619
+ focus ( options ) {
620
+ this . _groupEl . focus ( options ) ;
645
621
}
646
622
647
623
// a method that makes the <g> element lose focus, or invoking the user-defined blur event
648
- // event (optional): a FocusEvent object, can be passed as an argument of the user-defined blur event handlers
649
- blur ( event ) {
650
- if ( typeof this . onblur === 'function' ) {
651
- this . onblur . call ( this . _groupEl , event ) ;
652
- } else if (
624
+ blur ( ) {
625
+ if (
653
626
document . activeElement . shadowRoot ?. activeElement === this . _groupEl ||
654
627
document . activeElement . shadowRoot ?. activeElement . parentNode ===
655
628
this . _groupEl
0 commit comments