import { AttributeLibrary } from './attributeLibrary' ; import idSelectorLibrary , { IdSelectorLibrary } from './idSelectorLibrary' ; import classSelectorLibrary , { ClassSelectorLibrary } from './classSelectorLibrary' ; import { BaseLibrary , BaseLibraryOptions } from './baseLibrary' ; import arrayToRegex from './helpers/arrayToRegex' ; export class SelectorsLibrary extends BaseLibrary { selectors = [ idSelectorLibrary , classSelectorLibrary ] ; callOnBoth < T extends ( ... args : any ) => any > ( fun , ... args ) { const result = ( this . selectors . reduce < ReturnType < T > [ ] > ( ( prev , sel ) => { const fn = ( sel as any ) [ fun ] ; if ( typeof fn === 'function' ) { const res = fn . apply ( sel , args ) ; return [ ... prev , res , ] ; } return prev ; } , [ ] ) ) ; return result ; } reset ( ) { this . callOnBoth < BaseLibrary [ 'reset' ] > ( 'reset' ) ; } setAlphabet ( ... args ) { this . callOnBoth < BaseLibrary [ 'setAlphabet' ] > ( 'setAlphabet' , ... args ) ; } getClassSelector ( ) { return this . selectors [ 1 ] ; } getIdSelector ( ) { return this . selectors [ 0 ] ; } fillLibrary ( ... args ) { this . callOnBoth < BaseLibrary [ 'fillLibrary' ] > ( 'fillLibrary' , ... args ) ; } set ( ... args ) { this . callOnBoth < BaseLibrary [ 'set' ] > ( 'set' , ... args ) ; } setMultiple ( ... args ) { this . callOnBoth < BaseLibrary [ 'setMultiple' ] > ( 'setMultiple' , ... args ) ; } setPrefix ( ... args ) { this . callOnBoth < BaseLibrary [ 'setPrefix' ] > ( 'setPrefix' , ... args ) ; } setSuffix ( ... args ) { this . callOnBoth < BaseLibrary [ 'setSuffix' ] > ( 'setSuffix' , ... args ) ; } getSuffix ( ) { return this . selectors [ 0 ] . suffix ; } getPrefix ( ) { return this . selectors [ 0 ] . prefix ; } setExclude ( ... args ) { this . callOnBoth < BaseLibrary [ 'setExclude' ] > ( 'setExclude' , ... args ) ; } setInclude ( ... args ) { this . callOnBoth < BaseLibrary [ 'setInclude' ] > ( 'setInclude' , ... args ) ; } setReserved ( ... args ) { this . callOnBoth < BaseLibrary [ 'setReserved' ] > ( 'setReserved' , ... args ) ; } setAttributeSelector ( data ) { if ( Array . isArray ( data ) ) { data . forEach ( ( value ) => this . setAttributeSelector ( value ) ) ; return ; } this . selectors . forEach ( ( sel ) => { const matches = data . match ( sel . getAttributeSelectorRegex ( ) ) ; if ( matches ) { sel . setAttributeSelector ( matches ) ; } } ) ; } replaceAttributeSelector ( selector ) { let ret = false ; this . selectors . forEach ( ( sel ) => { if ( sel . isValidSelector ( selector ) ) { const res = sel . replaceAttributeSelector ( selector ) ; ret = res ? sel . selectorFirstChar ( ) + res : res ; } } ) ; return ret ; } getAllRegex ( opts = { } ) { const options = { regex : true , ... opts , } ; const ret = this . callOnBoth ( 'getAll' , options ) ; return arrayToRegex ( ret . filter ( Boolean ) . map ( ( x ) => x . source ) ) ! ; } get ( value , opts = { } ) { const stringifyLineBreaks = value . replace ( /\n/g , '\\n' ) ; const [ beginningWhitespace ] = stringifyLineBreaks . match ( /^(\\.| )+/ ) || [ '' ] ; const [ endWhitespace ] = stringifyLineBreaks . match ( /(\\.| )+$/ ) || [ '' ] ; const modifiedValue = stringifyLineBreaks . replace ( beginningWhitespace , '' ) . replace ( endWhitespace , '' ) ; const hasType = AttributeLibrary . isSelector ( modifiedValue ) ; const reconstructValue = ( v ) : string => ( ( beginningWhitespace + v + endWhitespace ) . replace ( /\\n/g , '\n' ) ) ; if ( ! hasType ) { const ret = this . selectors [ 0 ] . get ( modifiedValue , opts ) ; return reconstructValue ( ( ret === modifiedValue ? this . selectors [ 1 ] . get ( modifiedValue , opts ) : ret ) ) ; } if ( this . selectors [ 0 ] . isValidSelector ( modifiedValue ) ) { return reconstructValue ( this . selectors [ 0 ] . get ( modifiedValue , opts ) ) ; } return reconstructValue ( this . selectors [ 1 ] . get ( modifiedValue , opts ) ) ; } isReserved ( ... args ) { const ret = this . callOnBoth < BaseLibrary [ 'isReserved' ] > ( 'isReserved' , ... args ) ; return ret [ 0 ] || ret [ 1 ] ; } isExcluded ( ... args ) { const ret = this . callOnBoth < BaseLibrary [ 'isExcluded' ] > ( 'isExcluded' , ... args ) ; return ret [ 0 ] || ret [ 1 ] ; } } export default new SelectorsLibrary ( ) ;