import { Observable } from 'rxjs/Observable' ; import { fromEvent } from 'rxjs/observable/fromEvent' ; import { checkReady } from './bootstrap' ; import { CordovaOptions } from './decorators' ; import { cordovaWarn , getPlugin , getPromise , pluginWarn } from './util' ; checkReady ( ) ; export const ERR_CORDOVA_NOT_AVAILABLE = { error : 'cordova_not_available' } ; export const ERR_PLUGIN_NOT_INSTALLED = { error : 'plugin_not_installed' } ; return { boolean | { error : string } } private export function checkAvailability ( pluginRef , methodName ? , pluginName ? ) ; export function checkAvailability ( pluginObj , methodName ? , pluginName ? ) ; export function checkAvailability ( plugin , methodName ? , pluginName ? ) { let pluginRef , pluginInstance , pluginPackage ; if ( typeof plugin === 'string' ) { pluginRef = plugin ; } else { pluginRef = plugin . constructor . getPluginRef ( ) ; pluginName = plugin . constructor . getPluginName ( ) ; pluginPackage = plugin . constructor . getPluginInstallName ( ) ; } pluginInstance = getPlugin ( pluginRef ) ; if ( ! pluginInstance || ( ! ! methodName && typeof pluginInstance [ methodName ] === 'undefined' ) ) { if ( ! window . cordova ) { cordovaWarn ( pluginName , methodName ) ; return ERR_CORDOVA_NOT_AVAILABLE ; } pluginWarn ( pluginName , pluginPackage , methodName ) ; return ERR_PLUGIN_NOT_INSTALLED ; } return true ; } private export function instanceAvailability ( pluginObj , methodName ? ) { return ( pluginObj . _objectInstance && ( ! methodName || typeof pluginObj . _objectInstance [ methodName ] !== 'undefined' ) ) ; } function setIndex ( args , opts = { } , resolve ? , reject ? ) { if ( opts . sync ) { return args ; } if ( opts . callbackOrder === 'reverse' ) { args . unshift ( reject ) ; args . unshift ( resolve ) ; } else if ( opts . callbackStyle === 'node' ) { args . push ( ( err , result ) => { if ( err ) { reject ( err ) ; } else { resolve ( result ) ; } } ) ; } else if ( opts . callbackStyle === 'object' && opts . successName && opts . errorName ) { let obj = { } ; obj [ opts . successName ] = resolve ; obj [ opts . errorName ] = reject ; args . push ( obj ) ; } else if ( typeof opts . successIndex !== 'undefined' || typeof opts . errorIndex !== 'undefined' ) { const setSuccessIndex = ( ) => { if ( opts . successIndex > args . length ) { args [ opts . successIndex ] = resolve ; } else { args . splice ( opts . successIndex , 0 , resolve ) ; } } ; const setErrorIndex = ( ) => { if ( opts . errorIndex > args . length ) { args [ opts . errorIndex ] = reject ; } else { args . splice ( opts . errorIndex , 0 , reject ) ; } } ; if ( opts . successIndex > opts . errorIndex ) { setErrorIndex ( ) ; setSuccessIndex ( ) ; } else { setSuccessIndex ( ) ; setErrorIndex ( ) ; } } else { args . push ( resolve ) ; args . push ( reject ) ; } return args ; } function callCordovaPlugin ( pluginObj , methodName , args , opts = { } , resolve ? , reject ? ) { args = setIndex ( args , opts , resolve , reject ) ; const availabilityCheck = checkAvailability ( pluginObj , methodName ) ; if ( availabilityCheck === true ) { const pluginInstance = getPlugin ( pluginObj . constructor . getPluginRef ( ) ) ; return pluginInstance [ methodName ] . apply ( pluginInstance , args ) ; } else { return availabilityCheck ; } } function wrapPromise ( pluginObj , methodName , args , opts = { } ) { let pluginResult , rej ; const p = getPromise ( ( resolve , reject ) => { if ( opts . destruct ) { pluginResult = callCordovaPlugin ( pluginObj , methodName , args , opts , ( ... args ) => resolve ( args ) , ( ... args ) => reject ( args ) ) ; } else { pluginResult = callCordovaPlugin ( pluginObj , methodName , args , opts , resolve , reject ) ; } rej = reject ; } ) ; if ( pluginResult && pluginResult . error ) { p . catch ( ( ) => { } ) ; typeof rej === 'function' && rej ( pluginResult . error ) ; } return p ; } function wrapOtherPromise ( pluginObj , methodName , args , opts = { } ) { return getPromise ( ( resolve , reject ) => { const pluginResult = callCordovaPlugin ( pluginObj , methodName , args , opts ) ; if ( pluginResult ) { if ( pluginResult . error ) { reject ( pluginResult . error ) ; } else if ( pluginResult . then ) { pluginResult . then ( resolve ) . catch ( reject ) ; } } else { reject ( { error : 'unexpected_error' } ) ; } } ) ; } function wrapObservable ( pluginObj , methodName , args , opts = { } ) { return new Observable ( observer => { let pluginResult ; if ( opts . destruct ) { pluginResult = callCordovaPlugin ( pluginObj , methodName , args , opts , ( ... args ) => observer . next ( args ) , ( ... args ) => observer . error ( args ) ) ; } else { pluginResult = callCordovaPlugin ( pluginObj , methodName , args , opts , observer . next . bind ( observer ) , observer . error . bind ( observer ) ) ; } if ( pluginResult && pluginResult . error ) { observer . error ( pluginResult . error ) ; observer . complete ( ) ; } return ( ) => { try { if ( opts . clearFunction ) { if ( opts . clearWithArgs ) { return callCordovaPlugin ( pluginObj , opts . clearFunction , args , opts , observer . next . bind ( observer ) , observer . error . bind ( observer ) ) ; } return callCordovaPlugin ( pluginObj , opts . clearFunction , [ ] ) ; } } catch ( e ) { console . warn ( 'Unable to clear the previous observable watch for' , pluginObj . constructor . getPluginName ( ) , methodName ) ; console . warn ( e ) ; } } ; } ) ; } function callInstance ( pluginObj , methodName , args , opts = { } , resolve ? , reject ? ) { args = setIndex ( args , opts , resolve , reject ) ; if ( instanceAvailability ( pluginObj , methodName ) ) { return pluginObj . _objectInstance [ methodName ] . apply ( pluginObj . _objectInstance , args ) ; } } private param event param element returns { Observable } export function wrapEventObservable ( event , element = window ) { return fromEvent ( element , event ) ; } private export function overrideFunction ( pluginObj , methodName , args , opts = { } ) { return new Observable ( observer => { const availabilityCheck = checkAvailability ( pluginObj , null , pluginObj . constructor . getPluginName ( ) ) ; if ( availabilityCheck === true ) { const pluginInstance = getPlugin ( pluginObj . constructor . getPluginRef ( ) ) ; pluginInstance [ methodName ] = observer . next . bind ( observer ) ; return ( ) => ( pluginInstance [ methodName ] = ( ) => { } ) ; } else { observer . error ( availabilityCheck ) ; observer . complete ( ) ; } } ) ; } private export const wrap = function ( pluginObj , methodName , opts = { } ) { return ( ... args ) => { if ( opts . sync ) { return callCordovaPlugin ( pluginObj , methodName , args , opts ) ; } else if ( opts . observable ) { return wrapObservable ( pluginObj , methodName , args , opts ) ; } else if ( opts . eventObservable && opts . event ) { return wrapEventObservable ( opts . event , opts . element ) ; } else if ( opts . otherPromise ) { return wrapOtherPromise ( pluginObj , methodName , args , opts ) ; } else { return wrapPromise ( pluginObj , methodName , args , opts ) ; } } ; } ; private export function wrapInstance ( pluginObj , methodName , opts = { } ) { return ( ... args ) => { if ( opts . sync ) { return callInstance ( pluginObj , methodName , args , opts ) ; } else if ( opts . observable ) { return new Observable ( observer => { let pluginResult ; if ( opts . destruct ) { pluginResult = callInstance ( pluginObj , methodName , args , opts , ( ... args ) => observer . next ( args ) , ( ... args ) => observer . error ( args ) ) ; } else { pluginResult = callInstance ( pluginObj , methodName , args , opts , observer . next . bind ( observer ) , observer . error . bind ( observer ) ) ; } if ( pluginResult && pluginResult . error ) { observer . error ( pluginResult . error ) ; observer . complete ( ) ; } return ( ) => { try { if ( opts . clearWithArgs ) { return callInstance ( pluginObj , opts . clearFunction , args , opts , observer . next . bind ( observer ) , observer . error . bind ( observer ) ) ; } return callInstance ( pluginObj , opts . clearFunction , [ ] ) ; } catch ( e ) { console . warn ( 'Unable to clear the previous observable watch for' , pluginObj . constructor . getPluginName ( ) , methodName ) ; console . warn ( e ) ; } } ; } ) ; } else if ( opts . otherPromise ) { return getPromise ( ( resolve , reject ) => { let result ; if ( opts . destruct ) { result = callInstance ( pluginObj , methodName , args , opts , ( ... args ) => resolve ( args ) , ( ... args ) => reject ( args ) ) ; } else { result = callInstance ( pluginObj , methodName , args , opts , resolve , reject ) ; } if ( result && ! ! result . then ) { result . then ( resolve , reject ) ; } else { reject ( ) ; } } ) ; } else { let pluginResult , rej ; const p = getPromise ( ( resolve , reject ) => { if ( opts . destruct ) { pluginResult = callInstance ( pluginObj , methodName , args , opts , ( ... args ) => resolve ( args ) , ( ... args ) => reject ( args ) ) ; } else { pluginResult = callInstance ( pluginObj , methodName , args , opts , resolve , reject ) ; } rej = reject ; } ) ; if ( pluginResult && pluginResult . error ) { p . catch ( ( ) => { } ) ; typeof rej === 'function' && rej ( pluginResult . error ) ; } return p ; } } ; }