import Log from "./log" ; /**
 * A list of general useful functions.
 */ export default class Utils { param { object } object returns static cloneObject ( object ) { if ( object === null ) { return null ; } else if ( typeof object === "object" ) { return JSON . parse ( JSON . stringify ( object ) ) ; } else { Log . error ( "Impossible to clone a non-object" , "type" ) ; } } param { object } object static clearObject ( object ) { for ( let property in object ) { delete object [ property ] ; } } param { object } object returns { Array } static fromObjectToArray ( object ) { let array = [ ] ; for ( let p in object ) { array . push ( object [ p ] ) ; } return array ; } param { object } object1 param { object } object2 param { boolean } restricted returns { object } static mergeObjects ( object1 , object2 , restricted = false ) { if ( object2 === undefined && this . isPureObjectType ( object1 ) ) { return this . cloneObject ( object1 ) ; } else if ( object1 === undefined && this . isPureObjectType ( object2 ) ) { return this . cloneObject ( object2 ) ; } else if ( ! this . isPureObjectType ( object1 ) || ! this . isPureObjectType ( object2 ) ) { Log . error ( "Only two pure objects can be merged" , "type" ) ; } let result = this . cloneObject ( object1 ) ; for ( let property in object2 ) { let value = object2 [ property ] ; if ( ! restricted || result [ property ] !== undefined ) { if ( this . isPrimitiveType ( value ) || value === null ) { result [ property ] = value ; } else if ( Array . isArray ( value ) ) { result [ property ] = Utils . cloneObject ( value ) ; } else if ( this . isPureObjectType ( value ) ) { if ( this . isPureObjectType ( result [ property ] ) ) { result [ property ] = Utils . mergeObjects ( result [ property ] , value ) ; } else { result [ property ] = Utils . cloneObject ( value ) ; } } else { Log . error ( `Type "${ typeof value }" not allowed here` , "type" ) ; } } } return result ; } param { HTMLElement } element return { string } static cssRules ( element ) { let css = "" , sheets = document . styleSheets ; for ( let i = 0 ; i < sheets . length ; i ++ ) { let rules = ( < any > sheets [ i ] ) . cssRules ; if ( rules ) { for ( let j = 0 ; j < rules . length ; j ++ ) { let rule = rules [ j ] , fontFace = rule . cssText . match ( /^@font-face/ ) ; if ( element . querySelector ( rule . selectorText ) || fontFace ) { css += rule . cssText ; } } } } return css ; } param value returns { boolean } static isPrimitiveType ( value ) { return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "undefined" ; } param value returns { boolean } static isPureObjectType ( value ) { return typeof value === "object" && ! Array . isArray ( value ) && value !== null ; } /**
     * Remove all ranges of window.
     */ static removeAllRanges ( ) { window . getSelection ( ) . removeAllRanges ( ) ; } param { HTMLElement } element static focusWithCaretAtEnd ( element ) { let range = document . createRange ( ) , sel = window . getSelection ( ) ; element . focus ( ) ; range . selectNodeContents ( element ) ; range . collapse ( false ) ; sel . removeAllRanges ( ) ; sel . addRange ( range ) ; } }