1919 * ];
2020 */
2121export var Feature = L . Path . extend ( {
22- options : {
23- accessibleTitle : "Feature" ,
24- } ,
2522
2623 /**
2724 * Initializes the M.Feature
@@ -32,17 +29,20 @@ export var Feature = L.Path.extend({
3229 this . type = markup . tagName . toUpperCase ( ) ;
3330
3431 if ( this . type === "POINT" || this . type === "MULTIPOINT" ) options . fillOpacity = 1 ;
32+
33+ if ( options . wrappers . length > 0 )
34+ options = Object . assign ( this . _convertWrappers ( options . wrappers ) , options ) ;
3535 L . setOptions ( this , options ) ;
3636
37- this . _createGroup ( ) ; // creates the <g> element for the feature, or sets the one passed in options as the <g>
37+ this . group = this . options . group ;
3838
3939 this . _parts = [ ] ;
4040 this . _markup = markup ;
4141 this . options . zoom = markup . getAttribute ( 'zoom' ) || this . options . nativeZoom ;
4242
4343 this . _convertMarkup ( ) ;
4444
45- if ( markup . querySelector ( 'span' ) || markup . querySelector ( 'a' ) ) {
45+ if ( markup . querySelector ( 'span' ) || markup . querySelector ( 'map- a' ) ) {
4646 this . _generateOutlinePoints ( ) ;
4747 }
4848
@@ -53,37 +53,39 @@ export var Feature = L.Path.extend({
5353 * Removes the focus handler, and calls the leaflet L.Path.onRemove
5454 */
5555 onRemove : function ( ) {
56- L . DomEvent . off ( this . group , "keyup keydown mousedown" , this . _handleFocus , this ) ;
57- L . Path . prototype . onRemove . call ( this ) ;
58- } ,
59-
60- /**
61- * Creates the <g> conditionally and also applies event handlers
62- * @private
63- */
64- _createGroup : function ( ) {
65- if ( this . options . multiGroup ) {
66- this . group = this . options . multiGroup ;
67- } else {
68- this . group = L . SVG . create ( 'g' ) ;
69- if ( this . options . interactive ) this . group . setAttribute ( "aria-expanded" , "false" ) ;
70- this . group . setAttribute ( 'aria-label' , this . options . accessibleTitle ) ;
71- if ( this . options . featureID ) this . group . setAttribute ( "data-fid" , this . options . featureID ) ;
72- L . DomEvent . on ( this . group , "keyup keydown mousedown" , this . _handleFocus , this ) ;
56+ if ( this . options . link ) {
57+ this . off ( {
58+ click : this . _handleLinkClick ,
59+ keypress : this . _handleLinkKeypress ,
60+ } ) ;
7361 }
62+
63+ if ( this . options . interactive ) this . off ( 'keypress' , this . _handleSpaceDown ) ;
64+
65+ L . Path . prototype . onRemove . call ( this ) ;
7466 } ,
7567
7668 /**
77- * Handler for focus events
78- * @param {L.DOMEvent } e - Event that occured
79- * @private
69+ * Attaches link handler to the sub parts' paths
70+ * @param path
71+ * @param link
72+ * @param linkTarget
73+ * @param linkType
74+ * @param leafletLayer
8075 */
81- _handleFocus : function ( e ) {
82- if ( ( e . keyCode === 9 || e . keyCode === 16 || e . keyCode === 13 ) && e . type === "keyup" && e . target . tagName === "g" ) {
83- this . openTooltip ( ) ;
84- } else {
85- this . closeTooltip ( ) ;
86- }
76+ attachLinkHandler : function ( path , link , linkTarget , linkType , leafletLayer ) {
77+ let drag = false ; //prevents click from happening on drags
78+ L . DomEvent . on ( path , 'mousedown' , ( ) => { drag = false ; } , this ) ;
79+ L . DomEvent . on ( path , 'mousemove' , ( ) => { drag = true ; } , this ) ;
80+ L . DomEvent . on ( path , "mouseup" , ( e ) => {
81+ L . DomEvent . stop ( e ) ;
82+ if ( ! drag ) M . handleLink ( link , linkTarget , linkType , leafletLayer ) ;
83+ } , this ) ;
84+ L . DomEvent . on ( path , "keypress" , ( e ) => {
85+ L . DomEvent . stop ( e ) ;
86+ if ( e . keyCode === 13 || e . keyCode === 32 )
87+ M . handleLink ( link , linkTarget , linkType , leafletLayer ) ;
88+ } , this ) ;
8789 } ,
8890
8991 /**
@@ -140,6 +142,32 @@ export var Feature = L.Path.extend({
140142 this . _renderer . _updateFeature ( this ) ;
141143 } ,
142144
145+ /**
146+ * Converts the spans, a and divs around a geometry subtype into options for the feature
147+ * @private
148+ */
149+ _convertWrappers : function ( elems ) {
150+ if ( ! elems || elems . length === 0 ) return ;
151+ let classList = '' , output = { } ;
152+ for ( let elem of elems ) {
153+ if ( elem . tagName . toUpperCase ( ) !== "MAP-A" && elem . className ) {
154+ // Useful if getting other attributes off spans and divs is useful
155+ /* let attr = elem.attributes;
156+ for(let i = 0; i < attr.length; i++){
157+ if(attr[i].name === "class" || attributes[attr[i].name]) continue;
158+ attributes[attr[i].name] = attr[i].value;
159+ }*/
160+ classList += `${ elem . className } ` ;
161+ } else if ( ! output . link && elem . getAttribute ( "href" ) ) {
162+ output . link = elem . getAttribute ( "href" ) ;
163+ if ( elem . hasAttribute ( "target" ) ) output . linkTarget = elem . getAttribute ( "target" ) ;
164+ if ( elem . hasAttribute ( "type" ) ) output . linkType = elem . getAttribute ( "type" ) ;
165+ }
166+ }
167+ output . className = `${ classList } ${ this . options . className } ` . trim ( ) ;
168+ return output ;
169+ } ,
170+
143171 /**
144172 * Converts this._markup to the internal structure of features
145173 * @private
@@ -149,6 +177,8 @@ export var Feature = L.Path.extend({
149177
150178 let attr = this . _markup . attributes ;
151179 this . featureAttributes = { } ;
180+ if ( this . options . link && this . _markup . parentElement . tagName . toUpperCase ( ) === "MAP-A" && this . _markup . parentElement . parentElement . tagName . toUpperCase ( ) !== "GEOMETRY" )
181+ this . featureAttributes . tabindex = "0" ;
152182 for ( let i = 0 ; i < attr . length ; i ++ ) {
153183 this . featureAttributes [ attr [ i ] . name ] = attr [ i ] . value ;
154184 }
@@ -163,10 +193,10 @@ export var Feature = L.Path.extend({
163193 this . _parts [ 0 ] . subrings = this . _parts [ 0 ] . subrings . concat ( subrings ) ;
164194 } else if ( this . type === "MULTIPOINT" ) {
165195 for ( let point of ring [ 0 ] . points . concat ( subrings ) ) {
166- this . _parts . push ( { rings : [ { points : [ point ] } ] , subrings : [ ] , cls : point . cls || this . options . className } ) ;
196+ this . _parts . push ( { rings : [ { points : [ point ] } ] , subrings : [ ] , cls :` ${ point . cls || "" } ${ this . options . className || "" } ` . trim ( ) } ) ;
167197 }
168198 } else {
169- this . _parts . push ( { rings : ring , subrings : subrings , cls : this . featureAttributes . class || this . options . className } ) ;
199+ this . _parts . push ( { rings : ring , subrings : subrings , cls : ` ${ this . featureAttributes . class || "" } ${ this . options . className || "" } ` . trim ( ) } ) ;
170200 }
171201 first = false ;
172202 }
@@ -212,11 +242,12 @@ export var Feature = L.Path.extend({
212242 * @param {Object[] } subParts - An empty array representing the sub parts
213243 * @param {boolean } isFirst - A true | false representing if the current HTML element is the parent coordinates element or not
214244 * @param {string } cls - The class of the coordinate/span
245+ * @param parents
215246 * @private
216247 */
217- _coordinateToArrays : function ( coords , main , subParts , isFirst = true , cls = undefined ) {
248+ _coordinateToArrays : function ( coords , main , subParts , isFirst = true , cls = undefined , parents = [ ] ) {
218249 for ( let span of coords . children ) {
219- this . _coordinateToArrays ( span , main , subParts , false , span . getAttribute ( "class" ) ) ;
250+ this . _coordinateToArrays ( span , main , subParts , false , span . getAttribute ( "class" ) , parents . concat ( [ span ] ) ) ;
220251 }
221252 let noSpan = coords . textContent . replace ( / ( < ( [ ^ > ] + ) > ) / ig, '' ) ,
222253 pairs = noSpan . match ( / ( \S + \s + \S + ) / gim) , local = [ ] ;
@@ -230,12 +261,13 @@ export var Feature = L.Path.extend({
230261 if ( isFirst ) {
231262 main . push ( { points : local } ) ;
232263 } else {
233- let attrMap = { } , attr = coords . attributes ;
264+ let attrMap = { } , attr = coords . attributes , wrapperAttr = this . _convertWrappers ( parents ) ;
265+ if ( wrapperAttr . link ) attrMap . tabindex = "0" ;
234266 for ( let i = 0 ; i < attr . length ; i ++ ) {
235267 if ( attr [ i ] . name === "class" ) continue ;
236268 attrMap [ attr [ i ] . name ] = attr [ i ] . value ;
237269 }
238- subParts . unshift ( { points : local , cls : cls || this . options . className , attr : attrMap } ) ;
270+ subParts . unshift ( { points : local , cls : ` ${ cls || "" } ${ wrapperAttr . className || "" } ` . trim ( ) , attr : attrMap , link : wrapperAttr . link , linkTarget : wrapperAttr . linkTarget , linkType : wrapperAttr . linkType } ) ;
239271 }
240272 } ,
241273
0 commit comments