@@ -6,6 +6,42 @@ import {
6
6
UIDLAttributeValue ,
7
7
} from '@teleporthq/teleport-types'
8
8
9
+ // Whitelist of attributes that are safe to transfer to anchor tags
10
+ const ANCHOR_SAFE_ATTRIBUTES = new Set ( [
11
+ // Standard HTML attributes
12
+ 'class' ,
13
+ 'id' ,
14
+ 'style' ,
15
+ 'title' ,
16
+ 'lang' ,
17
+ 'dir' ,
18
+ 'tabindex' ,
19
+ 'accesskey' ,
20
+ 'contenteditable' ,
21
+ 'draggable' ,
22
+ 'hidden' ,
23
+ 'spellcheck' ,
24
+ 'translate' ,
25
+ ] )
26
+
27
+ // ARIA attributes safe for anchor tags (link-specific)
28
+ const ANCHOR_SAFE_ARIA_ATTRIBUTES = new Set ( [
29
+ 'aria-describedby' , // Describes the link purpose (valid transfer)
30
+ 'aria-labelledby' , // References label for the link
31
+ 'aria-expanded' , // For dropdown/collapsible links
32
+ 'aria-haspopup' , // For links that open menus/dialogs
33
+ 'aria-current' , // For navigation state
34
+ 'aria-disabled' , // For disabled links
35
+ ] )
36
+
37
+ const isAttributeSafeForAnchor = ( attrName : string ) : boolean => {
38
+ return (
39
+ ANCHOR_SAFE_ATTRIBUTES . has ( attrName ) ||
40
+ attrName . startsWith ( 'data-' ) ||
41
+ ANCHOR_SAFE_ARIA_ATTRIBUTES . has ( attrName )
42
+ )
43
+ }
44
+
9
45
export const insertLinks = (
10
46
node : UIDLElementNode ,
11
47
options : GeneratorOptions ,
@@ -149,6 +185,27 @@ export const insertLinks = (
149
185
}
150
186
151
187
const linkNode = createLinkNode ( abilities . link , options )
188
+
189
+ if ( node . type === 'element' && node . content . attrs ) {
190
+ // Filter attributes to only transfer those safe for anchor tags
191
+ const safeAttrs : Record < string , UIDLAttributeValue > = { }
192
+ Object . keys ( node . content . attrs ) . forEach ( ( attrName ) => {
193
+ if ( isAttributeSafeForAnchor ( attrName ) ) {
194
+ safeAttrs [ attrName ] = { ...node . content . attrs [ attrName ] }
195
+ }
196
+ } )
197
+
198
+ linkNode . content . attrs = {
199
+ ...linkNode . content . attrs ,
200
+ ...safeAttrs ,
201
+ }
202
+
203
+ // Remove only the transferred attributes from the original node
204
+ Object . keys ( safeAttrs ) . forEach ( ( attrName ) => {
205
+ delete node . content . attrs [ attrName ]
206
+ } )
207
+ }
208
+
152
209
linkNode . content . children . push ( node )
153
210
154
211
if ( parentNode === undefined || parentNode ?. content . style ?. display ?. content === 'flex' ) {
0 commit comments