/**
 * An interface used to define a writer used by trace to print (log).
 */ export interface TraceWriter { write ( message , category , type ? ) : void ; } /**
 * An interface used to trace information about specific event.
 */ export interface TraceEventListener { filter : string ; on ( object , name , data ? ) : void ; } /**
 * An interface used to for handling trace error
 */ export interface TraceErrorHandler { handlerError ( error ) : any ; } let enabled = false ; let _categories = { } ; const _writers = [ ] ; const _eventListeners = [ ] ; let _errorHandler ; export namespace Trace { /**
     * Enables the trace module.
     */ export function enable ( ) { enabled = true ; } /**
     * Disables the trace module.
     */ export function disable ( ) { enabled = false ; } /**
     * A function that returns whether the tracer is enabled and there is a point in writing messages.
     * Check this to avoid writing complex string templates.
     * Send error messages even if tracing is disabled.
     */ export function isEnabled ( ) { return enabled ; } param writer export function addWriter ( writer ) { _writers . push ( writer ) ; } param writer export function removeWriter ( writer ) { const index = _writers . indexOf ( writer ) ; if ( index >= 0 ) { _writers . splice ( index , 1 ) ; } } /**
     * Clears all the writers from the trace module.
     */ export function clearWriters ( ) { if ( _writers . length > 0 ) { _writers . splice ( 0 , _writers . length ) ; } } param categories export function setCategories ( categories ) { _categories = { } ; addCategories ( categories ) ; } param categories export function addCategories ( categories ) { const split = categories . split ( ',' ) ; for ( let i = 0 ; i < split . length ; i ++ ) { _categories [ split [ i ] . trim ( ) ] = true ; } } param category export function isCategorySet ( category ) { return category in _categories ; } param message param category param type export function write ( message , category , type ? ) { let i ; if ( type === messageType . error ) { for ( i = 0 ; i < _writers . length ; i ++ ) { _writers [ i ] . write ( message , category , type ) ; } return ; } if ( ! enabled ) { return ; } if ( ! ( category in _categories ) ) { return ; } for ( i = 0 ; i < _writers . length ; i ++ ) { _writers [ i ] . write ( message , category , type ) ; } } param object param name param data export function notifyEvent ( object , name , data ? ) { if ( ! enabled ) { return ; } let i , listener , filters ; for ( i = 0 ; i < _eventListeners . length ; i ++ ) { listener = _eventListeners [ i ] ; if ( listener . filter ) { filters = listener . filter . split ( ',' ) ; filters . forEach ( ( value ) => { if ( value . trim ( ) === name ) { listener . on ( object , name , data ) ; } } ) ; } else { listener . on ( object , name , data ) ; } } } export function addEventListener ( listener ) { _eventListeners . push ( listener ) ; } export function removeEventListener ( listener ) { const index = _eventListeners . indexOf ( listener ) ; if ( index >= 0 ) { _eventListeners . splice ( index , 1 ) ; } } export namespace messageType { export const log = 0 ; export const info = 1 ; export const warn = 2 ; export const error = 3 ; } /**
     * all predefined categories.
     */ export namespace categories { export const Accessibility = 'Accessibility' ; export const VisualTreeEvents = 'VisualTreeEvents' ; export const Layout = 'Layout' ; export const Style = 'Style' ; export const ViewHierarchy = 'ViewHierarchy' ; export const NativeLifecycle = 'NativeLifecycle' ; export const Debug = 'Debug' ; export const Navigation = 'Navigation' ; export const Test = 'Test' ; export const Binding = 'Binding' ; export const BindingError = 'BindingError' ; export const Error = 'Error' ; export const Animation = 'Animation' ; export const Transition = 'Transition' ; export const Livesync = 'Livesync' ; export const ModuleNameResolver = 'ModuleNameResolver' ; export const separator = ',' ; export const All = [ VisualTreeEvents , Layout , Style , ViewHierarchy , NativeLifecycle , Debug , Navigation , Test , Binding , Error , Animation , Transition , Livesync , ModuleNameResolver ] . join ( separator ) ; export function concat ( ... args ) { let result ; for ( let i = 0 ; i < args . length ; i ++ ) { if ( ! result ) { result = args [ i ] ; continue ; } result = result . concat ( separator , args [ i ] ) ; } return result ; } } class ConsoleWriter implements TraceWriter { public write ( message , category , type ? ) { if ( ! console ) { return ; } let msgType ; if ( type === undefined ) { msgType = messageType . log ; } else { msgType = type ; } switch ( msgType ) { case messageType . log : console . log ( category + ': ' + message ) ; break ; case messageType . info : console . info ( category + ': ' + message ) ; break ; case messageType . warn : console . warn ( category + ': ' + message ) ; break ; case messageType . error : console . error ( category + ': ' + message ) ; break ; } } } addWriter ( new ConsoleWriter ( ) ) ; export class DefaultErrorHandler implements TraceErrorHandler { handlerError ( error ) { throw error ; } } setErrorHandler ( new DefaultErrorHandler ( ) ) ; export function getErrorHandler ( ) { return _errorHandler ; } export function setErrorHandler ( handler ) { _errorHandler = handler ; } param error export function error ( error ) { if ( ! _errorHandler ) { return ; } if ( typeof error === 'string' ) { error = new Error ( error ) ; } _errorHandler . handlerError ( error ) ; } }