import { Declaration , StyleRules } from 'css' ; import { both , curry , has } from 'ramda' ; import { ITagNode , NodeType } from 'svg-vdom' ; import { IRuleOption } from '../../typings' ; import { IDom } from '../../typings/node' ; import { animationAttrElements , animationAttributes } from '../const/definitions' ; import { regularAttr } from '../const/regular-attr' ; import { numberGlobal } from '../const/syntax' ; import { parseAlpha } from '../math/parse-alpha' ; import { shortenAlpha } from '../math/shorten-alpha' ; import { toFixed } from '../math/to-fixed' ; import { parseStyle } from '../style/parse' ; import { stringifyStyle } from '../style/stringify' ; import { shortenNumber } from '../utils/shorten-number' ; import { shortenNumberList } from '../utils/shorten-number-list' ; import { traversalObj } from '../utils/traversal-obj' ; const doShorten = curry ( ( digit , val ) => shortenNumberList ( val . replace ( numberGlobal , s => `${ shortenNumber ( toFixed ( digit , parseFloat ( s ) ) ) }` ) ) ) ; export const shortenDecimalDigits = async ( dom , { params : { sizeDigit , angelDigit , opacityDigit , } } ) : Promise < void > => new Promise ( resolve => { const fuzzyDigit = doShorten ( sizeDigit ) ; const accurateDigit = doShorten ( angelDigit ) ; const shortenValue = ( key , value ) => { const define = regularAttr [ key ] ; if ( define . maybeAlpha ) { const alpha = parseAlpha ( value ) ; if ( typeof alpha === 'number' ) { return shortenAlpha ( opacityDigit , alpha ) ; } } else if ( define . maybeSizeNumber ) { return fuzzyDigit ( value ) ; } else if ( define . maybeAccurateNumber ) { return accurateDigit ( value ) ; } return value ; } ; if ( dom . stylesheet ) { const parsedCss = dom . stylesheet . stylesheet as StyleRules ; traversalObj ( both ( has ( 'property' ) , has ( 'value' ) ) , ( cssRule ) => { cssRule . value = shortenValue ( cssRule . property as string , cssRule . value as string ) ; } , parsedCss . rules ) ; } ( dom . querySelectorAll ( NodeType . Tag ) as ITagNode [ ] ) . forEach ( node => { const attributeName = node . getAttribute ( 'attributeName' ) ; node . attributes . forEach ( attr => { numberGlobal . lastIndex = 0 ; if ( animationAttributes . includes ( attr . fullname ) && animationAttrElements . includes ( node . nodeName ) ) { if ( attributeName ) { attr . value = shortenValue ( attributeName , attr . value ) ; } } else if ( attr . fullname === 'style' ) { const styleList = parseStyle ( attr . value ) ; styleList . forEach ( s => { numberGlobal . lastIndex = 0 ; s . value = shortenValue ( s . fullname , s . value ) ; } ) ; attr . value = stringifyStyle ( styleList ) ; } else { attr . value = shortenValue ( attr . fullname , attr . value ) ; } } ) ; } ) ; resolve ( ) ; } ) ;