2015-11-29 08:26:55 +08:00
import { get } from '../util' ;
declare var window ;
declare var Promise ;
2015-12-01 02:34:54 +08:00
import { Observable } from '@reactivex/rxjs/dist/cjs/Rx' ;
2015-11-30 07:20:11 +08:00
export const getPlugin = function ( pluginRef : string ) : any {
return get ( window , pluginRef ) ;
}
export const isInstalled = function ( pluginRef : string ) : boolean {
return ! ! getPlugin ( pluginRef ) ;
}
export const pluginWarn = function ( pluginName : string , method : string , plugin : string ) {
if ( method ) {
console . warn ( 'Native: tried calling ' + pluginName + '.' + method +
', but the ' + pluginName + ' plugin is not installed. Install the ' +
plugin + ' plugin' ) ;
} else {
console . warn ( 'Native: tried accessing the ' + pluginName + ' plugin but it\'s not installed. Install the ' + plugin + ' plugin' ) ;
}
}
export const cordovaWarn = function ( pluginName : string , method : string ) {
if ( method ) {
console . warn ( 'Native: tried calling ' + pluginName + '.' + method + ', but Cordova is not available. Make sure to include cordova.js or run in a device/simulator' ) ;
} else {
console . warn ( 'Native: tried accessing the ' + pluginName + ' plugin but Cordova is not available. Make sure to include cordova.js or run in a device/simulator' ) ;
}
}
2015-12-01 02:34:54 +08:00
function callCordovaPlugin ( pluginObj :any , methodName :string , args :any [ ] , opts :any = { } , resolve :any , reject :any ) {
if ( ! window . cordova ) {
cordovaWarn ( pluginObj . name , methodName ) ;
2015-12-01 03:27:25 +08:00
/ *
2015-12-01 02:34:54 +08:00
reject ( {
error : 'cordova_not_available'
2015-11-29 08:26:55 +08:00
} )
2015-12-01 02:34:54 +08:00
return ;
2015-12-01 03:27:25 +08:00
* /
2015-12-01 02:34:54 +08:00
}
// Try to figure out where the success/error callbacks need to be bound
// to our promise resolve/reject handlers.
// If the plugin method expects myMethod(success, err, options)
if ( opts . callbackOrder == 'reverse' ) {
2015-12-01 03:27:25 +08:00
// Get those arguments in the order [reject, resolve, ...restOfArgs]
args . unshift ( reject ) ;
args . unshift ( resolve ) ;
2015-12-01 02:34:54 +08:00
} else if ( typeof opts . successIndex !== 'undefined' || typeof opts . errorIndex !== 'undefined' ) {
// If we've specified a success/error index
args . splice ( opts . successIndex , 0 , resolve ) ;
args . splice ( opts . errorIndex , 0 , reject ) ;
} else {
// Otherwise, let's tack them on to the end of the argument list
// which is 90% of cases
args . push ( resolve ) ;
args . push ( reject ) ;
}
let pluginInstance = getPlugin ( pluginObj . pluginRef ) ;
if ( ! pluginInstance ) {
pluginWarn ( pluginObj . name , methodName , pluginObj . name ) ;
reject ( {
error : 'plugin_not_installed'
} ) ;
return ;
}
console . log ( 'Cordova calling' , pluginObj . name , methodName , args ) ;
2015-12-01 03:27:25 +08:00
// TODO: Illegal invocation needs window context
return get ( window , pluginObj . pluginRef ) [ methodName ] . apply ( pluginInstance , args ) ;
2015-12-01 02:34:54 +08:00
}
function wrapPromise ( pluginObj :any , methodName :string , args :any [ ] , opts :any = { } ) {
return new Promise ( ( resolve , reject ) = > {
callCordovaPlugin ( pluginObj , methodName , args , opts , resolve , reject ) ;
} )
}
function wrapObservable ( pluginObj :any , methodName :string , args :any [ ] , opts :any = { } ) {
2015-12-01 03:27:25 +08:00
return new Observable ( observer = > {
console . log ( 'Calling inside observable' , observer ) ;
let pluginResult = callCordovaPlugin ( pluginObj , methodName , args , opts , ( d ) = > {
console . log ( 'WATCH RESP' , d ) ;
observer . next ( d )
} , observer . error ) ;
2015-12-01 02:34:54 +08:00
return ( ) = > {
return get ( window , pluginObj . pluginRef ) [ opts . clearFunction ] . apply ( pluginObj , pluginResult ) ;
}
} ) ;
}
export const wrap = function ( pluginObj :any , methodName :string , opts :any = { } ) {
return ( . . . args ) = > {
if ( opts . observable ) {
console . log ( "Wrapping observable" ) ;
return wrapObservable ( pluginObj , methodName , args , opts ) ;
} else {
return wrapPromise ( pluginObj , methodName , args , opts ) ;
}
2015-11-29 08:26:55 +08:00
}
}
2015-11-30 09:54:45 +08:00
/ * *
* Class decorator specifying Plugin metadata . Required for all plugins .
* /
2015-11-29 08:26:55 +08:00
export function Plugin ( config ) {
return function ( cls ) {
// Add these fields to the class
for ( let k in config ) {
cls [ k ] = config [ k ] ;
}
return cls ;
}
}
2015-11-30 09:54:45 +08:00
/ * *
* Wrap a stub function in a call to a Cordova plugin , checking if both Cordova
* and the required plugin are installed .
* /
2015-11-29 08:26:55 +08:00
export function Cordova ( opts :any = { } ) {
2015-11-30 09:54:45 +08:00
return ( target : Object , methodName : string , descriptor : TypedPropertyDescriptor < any > ) = > {
let originalMethod = descriptor . value ;
return {
value : function ( . . . args : any [ ] ) {
2015-11-30 11:50:58 +08:00
return wrap ( this , methodName , opts ) . apply ( this , args ) ;
2015-11-30 09:54:45 +08:00
}
2015-11-29 08:26:55 +08:00
}
}
}
2015-11-30 07:20:11 +08:00
2015-11-30 09:54:45 +08:00
/ * *
* Before calling the original method , ensure Cordova and the plugin are installed .
* /
2015-11-30 07:20:11 +08:00
export function RequiresPlugin ( target : Function , key : string , descriptor : TypedPropertyDescriptor < any > ) {
let originalMethod = descriptor . value ;
descriptor . value = function ( . . . args : any [ ] ) {
console . log ( 'Calling' , this ) ;
if ( ! window . cordova ) {
cordovaWarn ( this . name , null ) ;
return ;
}
let pluginInstance = getPlugin ( this . pluginRef ) ;
if ( ! pluginInstance ) {
pluginWarn ( this . name , null , this . name ) ;
return ;
}
originalMethod . apply ( this , args ) ;
}
return descriptor ;
}