Skip to content

Commit

Permalink
feat(ionicnative): add instance wrapper
Browse files Browse the repository at this point in the history
closes #86

#79
  • Loading branch information
ihadeed committed Mar 29, 2016
1 parent 4ead1ae commit 0ec737a
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 32 deletions.
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {File} from './plugins/file';
import {Flashlight} from './plugins/flashlight';
import {Geolocation} from './plugins/geolocation';
import {Globalization} from './plugins/globalization';
import {GoogleMaps} from './plugins/googlemaps';
import {Hotspot} from './plugins/hotspot';
import {ImagePicker} from './plugins/imagepicker';
import {InAppBrowser} from './plugins/inappbrowser';
Expand All @@ -41,6 +42,7 @@ import {SMS} from './plugins/sms';
import {SocialSharing} from './plugins/socialsharing';
import {SpinnerDialog} from './plugins/spinnerdialog';
import {Splashscreen} from './plugins/splashscreen';
import {SQLite} from './plugins/sqlite';
import {StatusBar} from './plugins/statusbar';
import {Toast} from './plugins/toast';
import {TouchID} from './plugins/touchid';
Expand Down Expand Up @@ -72,6 +74,7 @@ export {
Flashlight,
Geolocation,
Globalization,
GoogleMaps,
Hotspot,
ImagePicker,
InAppBrowser,
Expand All @@ -84,6 +87,7 @@ export {
SocialSharing,
SpinnerDialog,
Splashscreen,
SQLite,
StatusBar,
Toast,
TouchID,
Expand Down Expand Up @@ -119,6 +123,7 @@ window['IonicNative'] = {
Flashlight: Flashlight,
Geolocation: Geolocation,
Globalization: Globalization,
GoogleMaps : GoogleMaps,
Hotspot: Hotspot,
ImagePicker: ImagePicker,
InAppBrowser: InAppBrowser,
Expand All @@ -131,6 +136,7 @@ window['IonicNative'] = {
SocialSharing: SocialSharing,
SpinnerDialog: SpinnerDialog,
Splashscreen: Splashscreen,
SQLite: SQLite,
StatusBar: StatusBar,
Toast: Toast,
TouchID: TouchID,
Expand Down
35 changes: 35 additions & 0 deletions src/plugins/googlemaps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {Cordova, Plugin} from "./plugin";
import {Observable} from "rxjs/Observable";
import {CordovaInstance} from "./plugin";
/**
* Created by Ibrahim on 3/29/2016.
*/
declare var plugin : any;
/**
* @name Google Maps
*/
@Plugin({
pluginRef: 'plugin.google.maps'
})
export class GoogleMaps {

private _objectInstance : any;

constructor (elementId : string, public niggasIn = "paris") {
this._objectInstance = {};//plugin.google.maps.Map.getMap(document.getElementById(elementId));
}

@Cordova({
eventObservable: true,
event: 'plugin.google.maps.event.MAP_READY'
})
static onInit () : Observable<GoogleMaps> {return}

@CordovaInstance({
sync: true
})
setDebuggable (isDebuggable : boolean) : void {}

setClickable (isClickable : boolean) : void {}

}
119 changes: 87 additions & 32 deletions src/plugins/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,45 +54,53 @@ export const cordovaWarn = function(pluginName: string, method: string) {
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');
}
};
function setIndex (args:any[], opts:any={}, resolve? : Function, reject?: Function) : any {
// If the plugin method expects myMethod(success, err, options)
if (opts.callbackOrder == 'reverse') {
// Get those arguments in the order [resolve, reject, ...restOfArgs]
args.unshift(reject);
args.unshift(resolve);
} 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);
}

return args;
}
function systemCheck (pluginInstance : any, pluginObj : any, methodName, resolve?: Function, reject?: Function) : boolean {
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);
reject && reject({
error: 'cordova_not_available'
});
return false;
}

pluginWarn(pluginObj, methodName);
reject && reject({
error: 'plugin_not_installed'
});
return false;
}
return;
}
function callCordovaPlugin(pluginObj:any, methodName:string, args:any[], opts:any={}, resolve?: Function, reject?: Function) {
// 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') {
// Get those arguments in the order [resolve, reject, ...restOfArgs]
args.unshift(reject);
args.unshift(resolve);
} 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);
}
args = setIndex (args, opts, resolve, reject);

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);
reject && reject({
error: 'cordova_not_available'
});
return;
}

pluginWarn(pluginObj, methodName);
reject && reject({
error: 'plugin_not_installed'
});
return;
}
if(!systemCheck(pluginInstance, pluginObj, methodName, resolve, reject)) return;

// console.log('Cordova calling', pluginObj.name, methodName, args);

Expand Down Expand Up @@ -141,6 +149,36 @@ function wrapObservable(pluginObj:any, methodName:string, args:any[], opts:any =
});
}

function callInstance(pluginObj:any, methodName : string, args:any[], opts:any = {}, resolve? : Function, reject? : Function){
console.log("C", methodName);
args = setIndex(args);
console.log("D", methodName, pluginObj, pluginObj._objectInstance);

return pluginObj._objectInstance[methodName].apply(pluginObj._objectInstance, args);
}

function wrapInstance (pluginObj:any, methodName:string, args:any[], opts:any = {}){

if (opts.sync) {
return callInstance(pluginObj, methodName, args, opts);
} else if (opts.observable) {
//console.log("It's an observable");
return new Observable(observer => {
//args = setIndex(args);
callInstance(pluginObj, methodName,args, opts, observer.next.bind(observer), observer.error.bind(observer));
return () => {
console.log("Observer cancelled.");
}
});
} else {
console.log("B", methodName);
return getPromise((resolve, reject) => {
//args = setIndex(args);
callInstance(pluginObj, methodName, args, opts, resolve, reject);
});
}
}

/**
* Wrap the event with an observable
* @param event
Expand All @@ -164,7 +202,9 @@ function wrapEventObservable (event : string) : Observable<any> {
export const wrap = function(pluginObj:any, methodName:string, opts:any = {}) {
return (...args) => {

if (opts.sync)
if(opts.instanceMethod) {
return wrapInstance(pluginObj, methodName, args, opts);
} else if (opts.sync)
return callCordovaPlugin(pluginObj, methodName, args, opts);

else if (opts.observable)
Expand Down Expand Up @@ -231,6 +271,21 @@ export function Cordova(opts:any = {}) {
}
}



export function CordovaInstance(opts:any = {}) {
return (target: Object, methodName: string, descriptor: TypedPropertyDescriptor<any>) => {
//let originalMethod = descriptor.value;
opts['instanceMethod'] = true;
return {
value: function(...args: any[]) {
console.log("A", methodName);
return wrap(this, methodName, opts).apply(this, args);
}
}
}
}

/**
* @private
*
Expand Down
106 changes: 106 additions & 0 deletions src/plugins/sqlite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import {CordovaInstance, Plugin, Cordova} from './plugin';
declare var sqlitePlugin;
/**
* @name SQLite
*/
@Plugin({
pluginRef: 'sqlitePlugin'
})
export class SQLite {

private _objectInstance : any;
get databaseFeatures() : any {
return this._objectInstance.databaseFeatures;
}

constructor (config : any) {
new Promise((resolve, reject) => {
sqlitePlugin.openDatabase(config, resolve, reject);
}).then(
db => this._objectInstance = db,
error => console.warn(error)
);
}

@CordovaInstance({
sync: true
})
addTransaction (transaction : any) : void {}

@CordovaInstance()
transaction (fn : any) : Promise<any> {return}

@CordovaInstance()
readTransaction (fn : any) : Promise<any> {return}

@CordovaInstance({
sync: true
})
startNextTransaction () : void {}

@CordovaInstance()
close () : Promise<any> {return}

@CordovaInstance({
sync: true
})
start () : void {}

@CordovaInstance()
executeSql (statement : string, params : any) : Promise<any> {return}

@CordovaInstance()
addSatement (sql, values) : Promise<any> {return}

@CordovaInstance()
sqlBatch (sqlStatements : any) : Promise<any> {return}

@CordovaInstance({
sync: true
})
abortallPendingTransactions () : void {}

@CordovaInstance({
sync: true
})
handleStatementSuccess (handler, response) : void {}


@CordovaInstance({
sync: true
})
handleStatementFailure (handler, response) : void {}


@CordovaInstance({
sync: true
})
run () : void {}


@CordovaInstance({
sync: true
})
abort (txFailure) : void {}


@CordovaInstance({
sync: true
})
finish () : void {}



@CordovaInstance({
sync: true
})
abortFromQ (sqlerror) : void {}


@Cordova()
static echoTest () : Promise<any> {return}

@Cordova()
static deleteDatabase (first) : Promise<any> {return}

}
3 changes: 3 additions & 0 deletions test/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="sql.js"></script>
<script src="../../dist/ionic.native.js"></script>
<script src="app.js"></script>
</head>
Expand All @@ -10,5 +11,7 @@ <h2>Test</h2>
<script>
angular.module('app', []);
</script>
<!-- div to test googlemaps plugin -->
<div id="gmap"></div>
</body>
</html>

0 comments on commit 0ec737a

Please sign in to comment.