Skip to content

Commit

Permalink
feat(plugin): cordova function override. fixes #437
Browse files Browse the repository at this point in the history
  • Loading branch information
mlynch committed Sep 24, 2016
1 parent a092a31 commit f60d08b
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 9 deletions.
28 changes: 19 additions & 9 deletions src/plugins/backgroundmode.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Cordova, Plugin } from './plugin';
import { Cordova, CordovaFunctionOverride, Plugin } from './plugin';

import { Observable } from 'rxjs/Observable';

/**
* @name Background Mode
Expand Down Expand Up @@ -80,17 +82,25 @@ export class BackgroundMode {
@Cordova({
platforms: ['Android']
})
static update(options?: Configure): void { }
static configure(options?: Configure): void { }

/**
* Sets a callback for a specific event
* Can be used to get notified or run function when the background mode has been activated, deactivated or failed.
* @param {string} eventName The name of the event. Available events: activate, deactivate, failure
* Called when background mode is activated.
*/
@Cordova({
sync: true
})
static on(eventName: string, callback: any): void { }
@CordovaFunctionOverride()
static onactivate(): Observable<any> { return; };

/**
* Called when background mode is deactivated.
*/
@CordovaFunctionOverride()
static ondeactivate(): Observable<any> { return; };

/**
* Called when background mode fails
*/
@CordovaFunctionOverride()
static onfailure(): Observable<any> { return; };

}

Expand Down
57 changes: 57 additions & 0 deletions src/plugins/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,47 @@ function wrapEventObservable(event: string): Observable<any> {
});
}

/**
* Certain plugins expect the user to override methods in the plugin. For example,
* window.cordova.plugins.backgroundMode.onactivate = function() { ... }.
*
* Unfortunately, this is brittle and would be better wrapped as an Observable. overrideFunction
* does just this.
*/
function overrideFunction(pluginObj: any, methodName: string, args: any[], opts: any = {}): Observable<any> {
return new Observable(observer => {

let pluginInstance = getPlugin(pluginObj.pluginRef);

if (!pluginInstance) {
// Do this check in here in the case that the Web API for this plugin is available (for example, Geolocation).
if (!window.cordova) {
cordovaWarn(pluginObj.name, methodName);
observer.error({
error: 'cordova_not_available'
});
}

pluginWarn(pluginObj, methodName);
observer.error({
error: 'plugin_not_installed'
});
return;
}

let method = pluginInstance[methodName];
if (!method) {
observer.error({
error: 'no_such_method'
});
observer.complete();
return;
}
pluginInstance[methodName] = observer.next.bind(observer);
});
}


/**
* @private
* @param pluginObj
Expand Down Expand Up @@ -364,3 +405,19 @@ export function InstanceProperty(target: any, key: string, descriptor: TypedProp

return descriptor;
}

/**
* @private
*
* Wrap a stub function in a call to a Cordova plugin, checking if both Cordova
* and the required plugin are installed.
*/
export function CordovaFunctionOverride(opts: any = {}) {
return (target: Object, methodName: string, descriptor: TypedPropertyDescriptor<any>) => {
return {
value: function(...args: any[]) {
return overrideFunction(this, methodName, opts);
}
};
};
}

0 comments on commit f60d08b

Please sign in to comment.