import * as strings from './strings' ; import path from './path' ; import { IdleValue } from './async' ; const sep = path . sep ; let intlFileNameCollator ; export function setFileNameComparer ( collator ) { intlFileNameCollator = collator ; } export function compareFileNames ( one , other , caseSensitive = false ) { if ( intlFileNameCollator ) { const a = one || '' ; const b = other || '' ; const result = intlFileNameCollator . getValue ( ) . collator . compare ( a , b ) ; if ( intlFileNameCollator . getValue ( ) . collatorIsNumeric && result === 0 && a !== b ) { return a < b ? - 1 : 1 ; } return result ; } return noIntlCompareFileNames ( one , other , caseSensitive ) ; } const FileNameMatch = /^(.*?)(\.([^.]*))?$/ ; export function noIntlCompareFileNames ( one , other , caseSensitive = false ) { if ( ! caseSensitive ) { one = one && one . toLowerCase ( ) ; other = other && other . toLowerCase ( ) ; } const [ oneName , oneExtension ] = extractNameAndExtension ( one ) ; const [ otherName , otherExtension ] = extractNameAndExtension ( other ) ; if ( oneName !== otherName ) { return oneName < otherName ? - 1 : 1 ; } if ( oneExtension === otherExtension ) { return 0 ; } return oneExtension < otherExtension ? - 1 : 1 ; } export function compareFileExtensions ( one , other ) { if ( intlFileNameCollator ) { const [ oneName , oneExtension ] = extractNameAndExtension ( one ) ; const [ otherName , otherExtension ] = extractNameAndExtension ( other ) ; let result = intlFileNameCollator . getValue ( ) . collator . compare ( oneExtension , otherExtension ) ; if ( result === 0 ) { if ( intlFileNameCollator . getValue ( ) . collatorIsNumeric && oneExtension !== otherExtension ) { return oneExtension < otherExtension ? - 1 : 1 ; } result = intlFileNameCollator . getValue ( ) . collator . compare ( oneName , otherName ) ; if ( intlFileNameCollator . getValue ( ) . collatorIsNumeric && result === 0 && oneName !== otherName ) { return oneName < otherName ? - 1 : 1 ; } } return result ; } return noIntlCompareFileExtensions ( one , other ) ; } function noIntlCompareFileExtensions ( one , other ) { const [ oneName , oneExtension ] = extractNameAndExtension ( one && one . toLowerCase ( ) ) ; const [ otherName , otherExtension ] = extractNameAndExtension ( other && other . toLowerCase ( ) ) ; if ( oneExtension !== otherExtension ) { return oneExtension < otherExtension ? - 1 : 1 ; } if ( oneName === otherName ) { return 0 ; } return oneName < otherName ? - 1 : 1 ; } function extractNameAndExtension ( str ? ) { const match = str ? FileNameMatch . exec ( str ) as Array < string > : ( [ ] as Array < string > ) ; return [ ( match && match [ 1 ] ) || '' , ( match && match [ 3 ] ) || '' ] ; } function comparePathComponents ( one , other , caseSensitive = false ) { if ( ! caseSensitive ) { one = one && one . toLowerCase ( ) ; other = other && other . toLowerCase ( ) ; } if ( one === other ) { return 0 ; } return one < other ? - 1 : 1 ; } export function comparePaths ( one , other , caseSensitive = false ) { const oneParts = one . split ( sep ) ; const otherParts = other . split ( sep ) ; const lastOne = oneParts . length - 1 ; const lastOther = otherParts . length - 1 ; let endOne , endOther ; for ( let i = 0 ; ; i ++ ) { endOne = lastOne === i ; endOther = lastOther === i ; if ( endOne && endOther ) { return compareFileNames ( oneParts [ i ] , otherParts [ i ] , caseSensitive ) ; } else if ( endOne ) { return - 1 ; } else if ( endOther ) { return 1 ; } const result = comparePathComponents ( oneParts [ i ] , otherParts [ i ] , caseSensitive ) ; if ( result !== 0 ) { return result ; } } } export function compareAnything ( one , other , lookFor ) { let elementAName = one . toLowerCase ( ) ; let elementBName = other . toLowerCase ( ) ; const prefixCompare = compareByPrefix ( one , other , lookFor ) ; if ( prefixCompare ) { return prefixCompare ; } let elementASuffixMatch = strings . endsWith ( elementAName , lookFor ) ; let elementBSuffixMatch = strings . endsWith ( elementBName , lookFor ) ; if ( elementASuffixMatch !== elementBSuffixMatch ) { return elementASuffixMatch ? - 1 : 1 ; } let r = compareFileNames ( elementAName , elementBName ) ; if ( r !== 0 ) { return r ; } return elementAName . localeCompare ( elementBName ) ; } export function compareByPrefix ( one , other , lookFor ) { let elementAName = one . toLowerCase ( ) ; let elementBName = other . toLowerCase ( ) ; let elementAPrefixMatch = strings . startsWith ( elementAName , lookFor ) ; let elementBPrefixMatch = strings . startsWith ( elementBName , lookFor ) ; if ( elementAPrefixMatch !== elementBPrefixMatch ) { return elementAPrefixMatch ? - 1 : 1 ; } else if ( elementAPrefixMatch && elementBPrefixMatch ) { if ( elementAName . length < elementBName . length ) { return - 1 ; } if ( elementAName . length > elementBName . length ) { return 1 ; } } return 0 ; }