import { HTMLTags } from './types' ; export type RawAttributes = { [ key ] : string | number ; } & { style ? : string ; } ; type Attributes = Record < string , number | string | boolean | StyleObject > ; export default function mapAttribute ( originalTag , attrs = { } as RawAttributes , preserveAttributes , getPropInfo ) { return Object . keys ( attrs ) . reduce ( ( result , attr ) => { if ( /^on.*/ . test ( attr ) ) { return result ; } let attributeName = attr ; if ( ! /^(data|aria)-/ . test ( attr ) ) { const preserved = preserveAttributes . filter ( ( at ) => { if ( at instanceof RegExp ) { return at . test ( attr ) ; } return at === attr ; } ) ; if ( preserved . length === 0 ) { attributeName = hypenColonToCamelCase ( attr ) ; } } const prop = getPropInfo ( originalTag , attributeName ) ; if ( prop . name === 'style' ) { result [ prop . name ] = convertStyle ( attrs . style ! ) ; } else { const value = attrs [ attr ] ; const booleanAttrributeValue = value === '' || String ( value ) . toLowerCase ( ) === attributeName . toLowerCase ( ) ; result [ prop . name ] = prop . isBoolean ? booleanAttrributeValue : value ; } return result ; } , { } as Attributes ) ; } type StyleObject = Record < string , number | string > ; function convertProperty ( prop ) { if ( /^-ms-/ . test ( prop ) ) { prop = prop . substr ( 1 ) ; } if ( prop . startsWith ( '--' ) ) { return prop ; } return hypenColonToCamelCase ( prop ) ; } function convertValue ( value ) { if ( /^\d+$/ . test ( value ) ) { return Number ( value ) ; } return value . replace ( /'/g , '"' ) ; } function convertStyle ( styleStr ) { const style = { } as StyleObject ; styleStr . split ( ';' ) . filter ( ( style ) => style . trim ( ) !== '' ) . forEach ( ( declaration ) => { const rules = declaration . split ( ':' ) ; if ( rules . length > 1 ) { const prop = convertProperty ( rules [ 0 ] . trim ( ) ) ; const val = convertValue ( rules . slice ( 1 ) . join ( ':' ) . trim ( ) ) ; style [ prop ] = val ; } } ) ; return style ; } function hypenColonToCamelCase ( str ) { return str . replace ( /(-|:)(.)/g , ( match , symbol , char ) => { return char . toUpperCase ( ) ; } ) ; }