summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--test/AfbAngular.js193
-rw-r--r--test/angular.html21
-rw-r--r--test/index.html1
3 files changed, 215 insertions, 0 deletions
diff --git a/test/AfbAngular.js b/test/AfbAngular.js
new file mode 100644
index 00000000..3db1ad59
--- /dev/null
+++ b/test/AfbAngular.js
@@ -0,0 +1,193 @@
+(function (){'use strict';
+
+ // some default values
+ // note that how default values are defined/used may change
+ var defaults = {
+ token: '123456789',
+ api: '/api'
+ };
+
+ var CALL = 2;
+ var RETOK = 3;
+ var RETERR = 4;
+ var EVENT = 5;
+
+ var PROTO1 = "x-afb-ws-json1";
+
+ // Definition of the Angular module
+ var AfbClientModule = angular.module('AfbClient', []);
+
+ // The instanciation of the module
+ AfbClientModule.factory('AfbClient', [ '$location', function ($location) {
+ var refid = $location.host();
+ var params = $location.search();
+ return clients[refid] || (client[refid] = new AfbContext(refid, params));
+ }]);
+
+ // prototype for handling context by uuid and token
+ function AfbContext(refid, params) {
+ this.refid = refid;
+ this.api = params.api || defaults.api;
+ this.uhttp = params.uhttp || this.api+'/';
+ this.uws = params.uws || this.api;
+ this.token = params.token || defaults.token;
+ this.uuid = params.uuid;
+ this.ws = null;
+ }
+
+ AfbContext.prototype = {
+ call: function(method, query) { return getws(this).call(method, query); },
+ get: function(method, query) { return $http.get(this.uhttp+method, mixtu(this, query)); },
+ post: function(method, query) { return $http.post(this.uhttp+method, mixtu(this, query)); },
+ };
+
+ function getws(ctxt) {
+ return ctxt.ws || (ctxt.ws = new AfbWebSocket(ctxt));
+ }
+
+ function mixtu(ctxt, query) {
+ return ("token" in query) ? query : angular.extend({token:ctxt.token},query);
+ }
+
+ // prototype for websocket
+ function AfbWebSocket(ctxt) {
+ var protos = [ PROTO1 ];
+ this.context = ctxt;
+ var url = "ws:" + ctxt.refid + ctxt.uws;
+ var q = ctxt.uuid ? ("?x-afb-uuid=" + ctxt.uuid) : "";
+ if (ctxt.token)
+ q = (q ? (q + "&") : "?") + ("x-afb-token=" + ctxt.token);
+ this.pendings = {};
+ this.awaitens = {};
+ this.counter = 0;
+ this.ws = new WebSocket(url + q, protos);
+ this.ws.onopen = onopen.bind(this);
+ this.ws.onerror = onerror.bind(this);
+ this.ws.onclose = onclose.bind(this);
+ this.ws.onmessage = onmessage.bind(this);
+ this.onopen = onopen;
+ this.onabort = onabort;
+ }
+
+ AfbWebSocket.prototype = {
+ call: function(method, query) {
+ return new Promise((function(resolve, reject){
+ var id = String(this.counter = 4095 & (this.counter + 1));
+ while (id in this.pendings) id = String(this.counter = 4095 & (this.counter + 1));
+ this.pendings[id] = [ resolve, reject ];
+ var arr = [CALL, id, method, request ];
+ var tok = this.context.token; if (tok) arr.push(tok);
+ this.ws.send(angular.toJson(arr, 0));
+ }).bind(this));
+ },
+ addEvent: function (name, handler) {
+ (this.awaitens[name] || (this.awaitens[name] = [])).push(handler);
+ },
+ removeEvent: function (name, handler) {
+ var a = this.awaitens[name];
+ if (a) {
+ var i = a.indexOf(handler);
+ if (i >= 0) a.splice(i, 1);
+ }
+ }
+
+ };
+
+ function onmessage(ev) {
+ var obj = angular.fromJson(ev.data);
+ var id = obj[1];
+ var ans = obj[2];
+ if (obj[3])
+ this.context.token = obj[3];
+ switch (obj[0]) {
+ case RETOK: reply(this.pendings, id, ans, 0); break;
+ case RETERR: reply(this.pendings, id, ans, 1); break;
+ case EVENT: fire(this.awaitens, id, ans); break;
+
+ }
+ }
+
+ function fire(awaitens, name, data) {
+ var a = awaitens[name];
+ if (a) a.forEach(function(handler){handler(data);});
+ var i = name.indexOf("/");
+ if (i >= 0) {
+ a = awaitens[name.substring(0,i)];
+ if (a) a.forEach(function(handler){handler(data);});
+ }
+ a = awaitens["*"];
+ if (a) a.forEach(function(handler){handler(data);});
+ }
+
+ function reply(pendings, id, ans, offset) {
+ if (id in pendings) {
+ var p = pendings[id];
+ delete pendings[id];
+ var f = p[offset];
+ if (f) f(ans);
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+ AFB_websocket = function(onopen, onabort) {
+ }
+
+ function onerror(event) {
+ var f = this.onabort;
+ if (f) {
+ delete this.onopen;
+ delete this.onabort;
+ f && f(this);
+ }
+ this.onerror && this.onerror(this);
+ }
+
+ function onopen(event) {
+ var f = this.onopen;
+ delete this.onopen;
+ delete this.onabort;
+ f && f(this);
+ }
+
+ function onclose(event) {
+ for (var id in this.pendings) {
+ var ferr = this.pendings[id].onerror;
+ ferr && ferr(null, this);
+ }
+ this.pendings = {};
+ this.onclose && this.onclose();
+ }
+
+ function close() {
+ this.ws.close();
+ }
+
+ function call(method, request) {
+ }
+
+/*
+ // Factory is a singleton and share its context within all instances.
+ AfbClientModule.factory('AppCall', function ($http, AppConfig, $log) {
+ var myCalls = {
+ get : function(plugin, action, query, callback) {
+ if (!query.token) query.token = AppConfig.session.token; // add token to provided query
+ $http.get('/api/' + plugin + '/' + action , {params: query}).then (callback, callback);
+ }
+ };
+ return myCalls;
+ });
+*/
+
+
+
+
+
+})();
diff --git a/test/angular.html b/test/angular.html
new file mode 100644
index 00000000..f7e25756
--- /dev/null
+++ b/test/angular.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<html>
+<body>
+ <div ng-controller="MyController">
+ Hello {{greetMe}}!
+ </div>
+ <script src="http://code.angularjs.org/1.5.5/angular.js"></script>
+ <script src="AfbAngular.js"></script>
+
+ <script>
+ angular.module('myApp', [])
+ .controller('MyController', ['$scope', function ($scope) {
+ $scope.greetMe = 'World';
+ }]);
+
+ angular.element(document).ready(function() {
+ angular.bootstrap(document, ['myApp']);
+ });
+ </script>
+</body>
+</html>
diff --git a/test/index.html b/test/index.html
index 5103a833..014ae461 100644
--- a/test/index.html
+++ b/test/index.html
@@ -9,3 +9,4 @@
<li><a href="sample-post.html">Sample post</a>
<li><a href="websock.html">websockets</a>
<li><a href="AFB.html">AFB.js</a>
+ <li><a href="angular.html">AfbAngular.js</a>