import './String.extensions' ; import * as _ from '@microsoft/sp-lodash-subset' ; import * as strings from 'PropertyControlStrings' ; export const IMG_SUPPORTED_EXTENSIONS = ".gif,.jpg,.jpeg,.bmp,.dib,.tif,.tiff,.ico,.png,.jxr,.svg" ; /**
 * Helper with general methods to simplify some routines
 */ export class GeneralHelper { param url public static trimSlash ( url ) { if ( url . lastIndexOf ( '/' ) === url . length - 1 ) return url . slice ( 0 , - 1 ) ; return url ; } param text public static encodeText ( text ) { const n = /[<>&'"\\]/g ; return text ? text . replace ( n , this . _getEncodedChar ) : '' ; } /**
     * Copy of Microsoft's GetRelativeDateTimeString from SP.dateTimeUtil
     */ public static getRelativeDateTimeString ( format ) { const formatParts = format . split ( '|' ) ; let result = null ; let placeholdersString = null ; if ( formatParts [ 0 ] === '0' ) return format . substring ( 2 ) ; const isFuture = formatParts [ 1 ] === '1' ; const formatType = formatParts [ 2 ] ; const timeString = formatParts . length >= 4 ? formatParts [ 3 ] : null ; const dayString = formatParts . length >= 5 ? formatParts [ 4 ] : null ; switch ( formatType ) { case '1' : result = isFuture ? strings . DateTime [ 'L_RelativeDateTime_AFewSecondsFuture' ] : strings . DateTime [ 'L_RelativeDateTime_AFewSeconds' ] ; break ; case '2' : result = isFuture ? strings . DateTime [ 'L_RelativeDateTime_AboutAMinuteFuture' ] : strings . DateTime [ 'L_RelativeDateTime_AboutAMinute' ] ; break ; case '3' : placeholdersString = this . getLocalizedCountValue ( isFuture ? strings . DateTime [ 'L_RelativeDateTime_XMinutesFuture' ] : strings . DateTime [ 'L_RelativeDateTime_XMinutes' ] , isFuture ? strings . DateTime [ 'L_RelativeDateTime_XMinutesFutureIntervals' ] : strings . DateTime [ 'L_RelativeDateTime_XMinutesIntervals' ] , Number ( timeString ) ) ; break ; case '4' : result = isFuture ? strings . DateTime [ 'L_RelativeDateTime_AboutAnHourFuture' ] : strings . DateTime [ 'L_RelativeDateTime_AboutAnHour' ] ; break ; case '5' : if ( timeString === null ) { result = isFuture ? strings . DateTime [ 'L_RelativeDateTime_Tomorrow' ] : strings . DateTime [ 'L_RelativeDateTime_Yesterday' ] ; } else { placeholdersString = isFuture ? strings . DateTime [ 'L_RelativeDateTime_TomorrowAndTime' ] : strings . DateTime [ 'L_RelativeDateTime_YesterdayAndTime' ] ; } break ; case '6' : placeholdersString = this . getLocalizedCountValue ( isFuture ? strings . DateTime [ 'L_RelativeDateTime_XHoursFuture' ] : strings . DateTime [ 'L_RelativeDateTime_XHours' ] , isFuture ? strings . DateTime [ 'L_RelativeDateTime_XHoursFutureIntervals' ] : strings . DateTime [ 'L_RelativeDateTime_XHoursIntervals' ] , Number ( timeString ) ) ; break ; case '7' : if ( dayString === null ) { result = timeString ; } else { placeholdersString = strings . DateTime [ 'L_RelativeDateTime_DayAndTime' ] ; } break ; case '8' : placeholdersString = this . getLocalizedCountValue ( isFuture ? strings . DateTime [ 'L_RelativeDateTime_XDaysFuture' ] : strings . DateTime [ 'L_RelativeDateTime_XDays' ] , isFuture ? strings . DateTime [ 'L_RelativeDateTime_XDaysFutureIntervals' ] : strings . DateTime [ 'L_RelativeDateTime_XDaysIntervals' ] , Number ( timeString ) ) ; break ; case '9' : result = strings . DateTime [ 'L_RelativeDateTime_Today' ] ; } if ( placeholdersString !== null ) { result = placeholdersString . replace ( "{0}" , timeString ) ; if ( dayString !== null ) { result = result . replace ( "{1}" , dayString ) ; } } return result ; } /**
     * Copy of Microsoft's GetLocalizedCountValue from SP.dateTimeUtil.
     * I've tried to rename all the vars to have meaningful names... but some were too unclear
     */ public static getLocalizedCountValue ( format , first , second ) { if ( format === undefined || first === undefined || second === undefined ) return null ; let result = '' ; let a = - 1 ; let firstOperandOptions = first . split ( '||' ) ; for ( let firstOperandOptionsIdx = 0 , firstOperandOptionsLen = firstOperandOptions . length ; firstOperandOptionsIdx < firstOperandOptionsLen ; firstOperandOptionsIdx ++ ) { const firstOperandOption = firstOperandOptions [ firstOperandOptionsIdx ] ; if ( firstOperandOption === null || firstOperandOption === '' ) continue ; let optionParts = firstOperandOption . split ( ',' ) ; for ( let optionPartsIdx = 0 , optionPartsLen = optionParts . length ; optionPartsIdx < optionPartsLen ; optionPartsIdx ++ ) { const optionPart = optionParts [ optionPartsIdx ] ; if ( optionPart === null || optionPart === '' ) continue ; if ( isNaN ( optionPart . parseNumberInvariant ( ) ) ) { const dashParts = optionPart . split ( '-' ) ; if ( dashParts === null || dashParts . length !== 2 ) continue ; let j , n ; if ( dashParts [ 0 ] === '' ) j = 0 ; else if ( isNaN ( dashParts [ 0 ] . parseNumberInvariant ( ) ) ) continue ; else j = parseInt ( dashParts [ 0 ] ) ; if ( second >= j ) { if ( dashParts [ 1 ] === '' ) { a = firstOperandOptionsIdx ; break ; } else if ( isNaN ( dashParts [ 1 ] . parseNumberInvariant ( ) ) ) continue ; else n = parseInt ( dashParts [ 1 ] ) ; if ( second <= n ) { a = firstOperandOptionsIdx ; break ; } } } else { let p = parseInt ( optionPart ) ; if ( second === p ) { a = firstOperandOptionsIdx ; break ; } } } if ( a !== - 1 ) break ; } if ( a !== - 1 ) { let e = format . split ( '||' ) ; if ( e !== null && e [ a ] !== null && e [ a ] !== '' ) result = e [ a ] ; } return result ; } param html public static getTextFromHTML ( html ) { let result = html ; let oldResult = result ; const tagBody = '(?:[^"\'>]|"[^"]*"|\'[^\']*\')*' ; const tagOrComment = new RegExp ( '<(?:' + '!--(?:(?:-*[^->])*--+|-?)' + '|script\\b' + tagBody + '>[\\s\\S]*?</script\\s*' + '|style\\b' + tagBody + '>[\\s\\S]*?</style\\s*' + '|/?[a-z]' + tagBody + ')>' , 'gi' ) ; do { oldResult = result ; result = result . replace ( tagOrComment , '' ) ; } while ( result !== result ) ; return result ; } param value public static isDefined ( value ) { return typeof value !== 'undefined' && value !== null ; } param xmlString public static parseXml ( xmlString ) { const parser = new DOMParser ( ) ; const xml = parser . parseFromString ( xmlString , 'text/xml' ) ; return xml ; } param url public static getAbsoluteDomainUrl ( url ) { if ( url !== undefined ) { const myURL = new URL ( url . toLowerCase ( ) ) ; return myURL . protocol + "//" + myURL . host ; } else { return undefined ; } } param blob public static getFileFromBlob ( blob , fileName ) { let result = null ; try { result = new File ( [ blob ] , fileName ) ; } catch ( ieErr ) { result = blob ; result . fileName = fileName ; } return result ; } public static formatBytes ( bytes , decimals ) { if ( bytes === 0 ) { return strings . EmptyFileSize ; } const k = 1024 ; const dm = decimals <= 0 ? 0 : decimals || 2 ; const i = Math . floor ( Math . log ( bytes ) / Math . log ( k ) ) ; return parseFloat ( ( bytes / Math . pow ( k , i ) ) . toFixed ( dm ) ) + ' ' + strings . SizeUnit [ i ] ; } /**
     * Returns file name without extension.
     */ public static getFileNameWithoutExtension ( itemUrl ) { const fileNameWithExtension = GeneralHelper . getFileNameFromUrl ( itemUrl ) ; const fileNameTokens = fileNameWithExtension . split ( "." ) ; const fileName = fileNameTokens [ 0 ] ; return fileName ; } /**
     * Returns file name with the extension
     */ public static getFileNameFromUrl ( itemUrl ) { const urlTokens = itemUrl . split ( "?" ) ; const url = urlTokens [ 0 ] ; const tokens = url . split ( "/" ) ; const fileNameWithExtension = tokens [ tokens . length - 1 ] ; return fileNameWithExtension ; } public static isImage ( fileName ) { const acceptableExtensions = IMG_SUPPORTED_EXTENSIONS . split ( "," ) ; const thisExtension = GeneralHelper . getFileExtension ( fileName ) ; return acceptableExtensions . indexOf ( thisExtension ) > - 1 ; } /**
     * Returns extension of the file
     */ public static getFileExtension ( fileName ) { const splitFileName = fileName . toLowerCase ( ) . split ( '.' ) ; let extensionValue = splitFileName . pop ( ) ; if ( extensionValue . indexOf ( '?' ) !== - 1 ) { const querySplit = extensionValue . split ( '?' ) ; extensionValue = querySplit [ 0 ] ; } return `.${ extensionValue }` ; } private static _getEncodedChar ( c ) { const o = { "<" : "&lt;" , ">" : "&gt;" , "&" : "&amp;" , '"' : "&quot;" , "'" : "&#39;" , "\\" : "&#92;" } ; return o [ c ] ; } } export const setPropertyValue = ( properties , targetProperty , value ) => { if ( ! properties ) { return ; } if ( targetProperty . indexOf ( '.' ) === - 1 ) { properties [ targetProperty ] = value ; } else { _ . set ( properties , targetProperty , value ) ; } } ; export const getPropertyValue = < T = any > ( properties , targetProperty ) : T => { if ( ! properties ) { return undefined ; } if ( targetProperty . indexOf ( '.' ) === - 1 ) { return properties [ targetProperty ] ; } return _ . get ( properties , targetProperty ) ; } ; export const toRelativeUrl = ( absoluteUrl ) : string => { if ( ! absoluteUrl ) { return '' ; } return absoluteUrl . replace ( /^(?:\/\/|[^/]+)*\// , '/' ) ; } ;