import merge from 'lodash.merge' ; import selectorsLibrary , { SelectorsLibrary } from '../selectorsLibrary' ; import { AttributeLibrary } from '../attributeLibrary' ; import regexp from './regex' ; import { ClassSelectorLibrary } from '../classSelectorLibrary' ; import { IdSelectorLibrary } from '../idSelectorLibrary' ; import { BaseLibraryOptions } from '../baseLibrary' ; export interface ReplaceStringOptions extends BaseLibraryOptions { classOnly ? : boolean ; isJSX ? : boolean ; addSelectorType ? : boolean ; forceReplace ? : boolean ; } const replaceString = ( string , regex ? , options = { } ) : string => { let result ; let tempString = string ; const beginChar = string . charAt ( 0 ) ; const endChar = string . charAt ( string . length - 1 ) ; tempString = tempString . slice ( 1 , tempString . length - 1 ) ; let selectorLib = selectorsLibrary ; let surelySelector = tempString . match ( regexp . likelySelector ) !== null ; if ( options . isJSX ) { surelySelector = false ; } if ( options . classOnly !== undefined ) { surelySelector = false ; selectorLib = options . classOnly ? selectorsLibrary . getClassSelector ( ) : selectorsLibrary . getIdSelector ( ) ; } const bastardSplitChars = ' =,()"\'\\]' ; let stringArray = tempString . split ( new RegExp ( `(?=[#.${ bastardSplitChars }])` ) ) ; let previousEqual = false ; let previousAttr = '' ; stringArray = stringArray . map ( ( element ) => { const interestingValue = element . replace ( new RegExp ( `[${ bastardSplitChars }]` , 'g' ) , '' ) ; if ( interestingValue . length === 0 ) { if ( element === '=' ) { previousEqual = true ; } return element ; } let prevEqual = previousEqual ; previousEqual = element === '=' ; const startSplitChar = bastardSplitChars . indexOf ( element . charAt ( 0 ) ) === - 1 ? '' : element . charAt ( 0 ) ; const tempElement = element . slice ( startSplitChar . length , element . length ) ; const startWithSelector = AttributeLibrary . isSelector ( tempElement ) ; prevEqual = prevEqual || startSplitChar === '=' ; const match = ( ! startWithSelector && prevEqual ) ? previousAttr . match ( /[^a-zA-Z]+([a-zA-Z]+)/ ) : null ; const previousAttributeName = match !== null ? match [ 1 ] : null ; const isAttributeInteresting = ( previousAttributeName === 'class' || previousAttributeName === 'id' || previousAttributeName === 'for' ) ; previousAttr = interestingValue ; if ( ! options . forceReplace && surelySelector && ! startWithSelector && ( ! prevEqual || ! isAttributeInteresting ) ) { return startSplitChar + tempElement ; } return ( startSplitChar + selectorLib . get ( tempElement , merge ( { addSelectorType : startWithSelector } , options ) ) ) ; } ) ; result = stringArray . join ( '' ) ; result = beginChar + result + endChar ; return result ; } ; export default replaceString ;