19
19
* ];
20
20
*/
21
21
export var Feature = L . Path . extend ( {
22
- options : {
23
- accessibleTitle : "Feature" ,
24
- } ,
25
22
26
23
/**
27
24
* Initializes the M.Feature
@@ -32,17 +29,20 @@ export var Feature = L.Path.extend({
32
29
this . type = markup . tagName . toUpperCase ( ) ;
33
30
34
31
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 ) ;
35
35
L . setOptions ( this , options ) ;
36
36
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 ;
38
38
39
39
this . _parts = [ ] ;
40
40
this . _markup = markup ;
41
41
this . options . zoom = markup . getAttribute ( 'zoom' ) || this . options . nativeZoom ;
42
42
43
43
this . _convertMarkup ( ) ;
44
44
45
- if ( markup . querySelector ( 'span' ) || markup . querySelector ( 'a' ) ) {
45
+ if ( markup . querySelector ( 'span' ) || markup . querySelector ( 'map- a' ) ) {
46
46
this . _generateOutlinePoints ( ) ;
47
47
}
48
48
@@ -53,37 +53,39 @@ export var Feature = L.Path.extend({
53
53
* Removes the focus handler, and calls the leaflet L.Path.onRemove
54
54
*/
55
55
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
+ } ) ;
73
61
}
62
+
63
+ if ( this . options . interactive ) this . off ( 'keypress' , this . _handleSpaceDown ) ;
64
+
65
+ L . Path . prototype . onRemove . call ( this ) ;
74
66
} ,
75
67
76
68
/**
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
80
75
*/
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 ) ;
87
89
} ,
88
90
89
91
/**
@@ -140,6 +142,32 @@ export var Feature = L.Path.extend({
140
142
this . _renderer . _updateFeature ( this ) ;
141
143
} ,
142
144
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
+
143
171
/**
144
172
* Converts this._markup to the internal structure of features
145
173
* @private
@@ -149,6 +177,8 @@ export var Feature = L.Path.extend({
149
177
150
178
let attr = this . _markup . attributes ;
151
179
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" ;
152
182
for ( let i = 0 ; i < attr . length ; i ++ ) {
153
183
this . featureAttributes [ attr [ i ] . name ] = attr [ i ] . value ;
154
184
}
@@ -163,10 +193,10 @@ export var Feature = L.Path.extend({
163
193
this . _parts [ 0 ] . subrings = this . _parts [ 0 ] . subrings . concat ( subrings ) ;
164
194
} else if ( this . type === "MULTIPOINT" ) {
165
195
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 ( ) } ) ;
167
197
}
168
198
} 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 ( ) } ) ;
170
200
}
171
201
first = false ;
172
202
}
@@ -212,11 +242,12 @@ export var Feature = L.Path.extend({
212
242
* @param {Object[] } subParts - An empty array representing the sub parts
213
243
* @param {boolean } isFirst - A true | false representing if the current HTML element is the parent coordinates element or not
214
244
* @param {string } cls - The class of the coordinate/span
245
+ * @param parents
215
246
* @private
216
247
*/
217
- _coordinateToArrays : function ( coords , main , subParts , isFirst = true , cls = undefined ) {
248
+ _coordinateToArrays : function ( coords , main , subParts , isFirst = true , cls = undefined , parents = [ ] ) {
218
249
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 ] ) ) ;
220
251
}
221
252
let noSpan = coords . textContent . replace ( / ( < ( [ ^ > ] + ) > ) / ig, '' ) ,
222
253
pairs = noSpan . match ( / ( \S + \s + \S + ) / gim) , local = [ ] ;
@@ -230,12 +261,13 @@ export var Feature = L.Path.extend({
230
261
if ( isFirst ) {
231
262
main . push ( { points : local } ) ;
232
263
} else {
233
- let attrMap = { } , attr = coords . attributes ;
264
+ let attrMap = { } , attr = coords . attributes , wrapperAttr = this . _convertWrappers ( parents ) ;
265
+ if ( wrapperAttr . link ) attrMap . tabindex = "0" ;
234
266
for ( let i = 0 ; i < attr . length ; i ++ ) {
235
267
if ( attr [ i ] . name === "class" ) continue ;
236
268
attrMap [ attr [ i ] . name ] = attr [ i ] . value ;
237
269
}
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 } ) ;
239
271
}
240
272
} ,
241
273
0 commit comments