summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--www/js/controllers.js2
-rw-r--r--www/lib/ng-websocket/.bower.json43
-rw-r--r--www/lib/ng-websocket/Gulpfile.js15
-rw-r--r--www/lib/ng-websocket/LICENSE21
-rw-r--r--www/lib/ng-websocket/README.md1010
-rw-r--r--www/lib/ng-websocket/bower.json32
-rw-r--r--www/lib/ng-websocket/ng-websocket.js370
-rw-r--r--www/lib/ng-websocket/package.json31
8 files changed, 1523 insertions, 1 deletions
diff --git a/www/js/controllers.js b/www/js/controllers.js
index e6b1b9ce..80afa2fe 100644
--- a/www/js/controllers.js
+++ b/www/js/controllers.js
@@ -4,7 +4,7 @@
-angular.module('zmApp.controllers', ['ionic', 'ngCordova', 'ng-mfb','angularCircularNavigation', 'jett.ionic.content.banner', 'ionic-pullup' ])
+angular.module('zmApp.controllers', ['ionic', 'ngCordova', 'ng-mfb','angularCircularNavigation', 'jett.ionic.content.banner', 'ionic-pullup', 'ngWebsocket' ])
.controller('zmApp.BaseController', function($scope, $ionicSideMenuDelegate, $ionicPlatform, $timeout, $rootScope) {
$scope.openMenu = function () {
diff --git a/www/lib/ng-websocket/.bower.json b/www/lib/ng-websocket/.bower.json
new file mode 100644
index 00000000..ce61f3c1
--- /dev/null
+++ b/www/lib/ng-websocket/.bower.json
@@ -0,0 +1,43 @@
+{
+ "name": "ng-websocket",
+ "version": "0.2.1",
+ "authors": [
+ "Vincenzo (Wilk) Ferrari <wilk3ert@gmail.com>"
+ ],
+ "description": "AngularJS HTML5 WebSocket powerful library",
+ "main": "ng-websocket.js",
+ "keywords": [
+ "angular",
+ "angularjs",
+ "websocket",
+ "ng",
+ "html5",
+ "service",
+ "provider"
+ ],
+ "license": "MIT",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "angular": "~1.3.2"
+ },
+ "devDependencies": {
+ "angular-mocks": "~1.3.2"
+ },
+ "homepage": "https://github.com/wilk/ng-websocket",
+ "_release": "0.2.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v0.2.1",
+ "commit": "09f128e2bf3c485d016ab1f5d0c263b379862c9e"
+ },
+ "_source": "git://github.com/wilk/ng-websocket.git",
+ "_target": "~0.2.1",
+ "_originalSource": "ng-websocket",
+ "_direct": true
+} \ No newline at end of file
diff --git a/www/lib/ng-websocket/Gulpfile.js b/www/lib/ng-websocket/Gulpfile.js
new file mode 100644
index 00000000..c3a248e2
--- /dev/null
+++ b/www/lib/ng-websocket/Gulpfile.js
@@ -0,0 +1,15 @@
+var gulp = require('gulp'),
+ karma = require('gulp-karma');
+
+gulp.task('test', function () {
+ return gulp.src([
+ 'bower_components/angular/angular.js',
+ 'bower_components/angular-mocks/angular-mocks.js',
+ 'ng-websocket.js',
+ 'test/unit/**/*.js'
+ ])
+ .pipe(karma({
+ configFile: 'test/karma.conf.js',
+ action: 'run'
+ }));
+}); \ No newline at end of file
diff --git a/www/lib/ng-websocket/LICENSE b/www/lib/ng-websocket/LICENSE
new file mode 100644
index 00000000..f0042000
--- /dev/null
+++ b/www/lib/ng-websocket/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Vincenzo Ferrari
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/www/lib/ng-websocket/README.md b/www/lib/ng-websocket/README.md
new file mode 100644
index 00000000..946bea4c
--- /dev/null
+++ b/www/lib/ng-websocket/README.md
@@ -0,0 +1,1010 @@
+ng-websocket
+============
+
+**AngularJS HTML5 WebSocket** powerful wrapper module to develop with ease and fun!
+
+# Index
+
+ - [Introduction](#introduction)
+ - [Requirements](#requirements)
+ - [Installation](#installation)
+ - [Usage](#usage)
+ - [Tutorial](#tutorial)
+ - [Features](#features)
+ - [Lazy Initialization](#lazy)
+ - [Auto Reconnection](#reconnect)
+ - [Enqueue Unsent Messages](#enqueue)
+ - [Mock Websocket Server](#mock)
+ - [Testing](#testing)
+ - [API](#api)
+ - [$websocketProvider](#websocketProvider)
+ - [$setup](#setup)
+ - [$websocket](#websocket)
+ - [$new](#new)
+ - [$get](#get)
+ - [ngWebsocket](#ngWebsocket)
+ - [Constructor](#constructor)
+ - [Constants](#constants)
+ - [Events](#events)
+ - [$on](#on)
+ - [$un](#un)
+ - [$emit](#emit)
+ - [$open](#open)
+ - [$close](#close)
+ - [$status](#status)
+ - [$ready](#ready)
+ - [$mockup](#mockup)
+ - [$$mockWebsocket](#mockWebsocket)
+ - [Contribute](#contribute)
+ - [License](#license)
+
+# Introduction
+
+**ngWebsocket** is a library that provides a provider and a service to handle **HTML5 WebSocket** with ease
+in pure **AngularJS** style!
+The idea behind this module is to give four kinds of object to handle websockets:
+
+ - **$websocketProvider**: the provider is on top of usage. In fact, you can setup a general configuration for each ngWebsocket you're going to create
+ - **$websocket**: following an Angular service that lets you to handle different websocket instance among your application
+ - **ngWebsocket**: an instance of the HTML5 WebSocket wrapper (this is actually the core of this module): it provides lots of feature to work with websockets
+ - **$$mockWebsocket**: this is a smart implementation of a websocket backend that lets you to developer and test your app without a real responding server
+
+For each of these objects an API is available and fully documented in this document.
+
+# Requirements
+
+The only requirement needed is [AngularJS](https://angularjs.org/) that you can install it via [Bower](http://bower.io/).
+
+# Installation
+
+Use [Bower](http://bower.io/) to install this module:
+
+```bash
+$ bower install ng-websocket
+```
+
+Or simply `git clone` the repo and install the dependencies with [NPM](https://www.npmjs.org/):
+
+```bash
+$ git clone https://github.com/wilk/ngWebsocket
+$ cd ngWebsocket
+$ npm install
+```
+
+# Usage
+
+After the [Installation](#installation), require it in your Angular application.
+
+Firstly, in your `index.html`:
+
+```html
+<html>
+ <head>
+ <script src="bower_components/ng-websocket/ng-websocket.js"></script>
+ </head>
+</html>
+```
+
+Then, in your Angular application definition (assumed `app.js`):
+
+```javascript
+ 'use strict';
+
+ angular.module('MyApp', ['ngWebsocket']);
+```
+
+Now, you're ready to use it!
+
+# Tutorial
+
+Need to use HTML5 WebSocket to build your cool web application, huh?
+No problem, dude! Check this out!
+
+```javascript
+'use strict';
+
+angular.module('MyCoolWebApp', ['ngWebsocket'])
+ .run(function ($websocket) {
+ var ws = $websocket.$new('ws://localhost:12345'); // instance of ngWebsocket, handled by $websocket service
+
+ ws.$on('$open', function () {
+ console.log('Oh my gosh, websocket is really open! Fukken awesome!');
+
+ ws.$emit('ping', 'hi listening websocket server'); // send a message to the websocket server
+
+ var data = {
+ level: 1,
+ text: 'ngWebsocket rocks!',
+ array: ['one', 'two', 'three'],
+ nested: {
+ level: 2,
+ deeper: [{
+ hell: 'yeah'
+ }, {
+ so: 'good'
+ }]
+ }
+ };
+
+ ws.$emit('pong', data);
+ });
+
+ ws.$on('pong', function (data) {
+ console.log('The websocket server has sent the following data:');
+ console.log(data);
+
+ ws.$close();
+ });
+
+ ws.$on('$close', function () {
+ console.log('Noooooooooou, I want to have more fun with ngWebsocket, damn it!');
+ });
+ });
+```
+
+Easy, right?
+
+Well, let's chain it!
+
+```javascript
+'use strict';
+
+angular.module('MyCoolChainedWebApp', ['ngWebsocket'])
+ .run(function ($websocket) {
+ var ws = $websocket.$new('ws://localhost:12345')
+ .$on('$open', function () {
+ console.log('Oh my gosh, websocket is really open! Fukken awesome!');
+
+ var data = {
+ level: 1,
+ text: 'ngWebsocket rocks!',
+ array: ['one', 'two', 'three'],
+ nested: {
+ level: 2,
+ deeper: [{
+ hell: 'yeah'
+ }, {
+ so: 'good'
+ }]
+ }
+ };
+
+ ws.$emit('ping', 'hi listening websocket server') // send a message to the websocket server
+ .$emit('pong', data);
+ })
+ .$on('pong', function (data) {
+ console.log('The websocket server has sent the following data:');
+ console.log(data);
+
+ ws.$close();
+ })
+ .$on('$close', function () {
+ console.log('Noooooooooou, I want to have more fun with ngWebsocket, damn it!');
+ });
+ });
+```
+
+Your back-end team is lazy? No problem: we can do it on our own!
+
+```javascript
+'use strict';
+
+angular.module('MyIndipendentCoolWebApp', ['ngWebsocket'])
+ .run(function ($websocket) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ mock: {
+ fixtures: {
+ 'custom event': {
+ data: 'websocket server mocked response'
+ },
+ 'another event': {
+ data: {
+ damn: 'dude',
+ that: 'is awesome!'
+ }
+ }
+ }
+ }
+ });
+
+ ws.$on('$open', function () {
+ ws.$emit('an event', 'a parrot response') // by default it responde with the same incoming data
+ .$emit('custom event') // otherwise it uses the given fixtures
+ .$emit('another event'); // even for objects
+ })
+ .$on('an event', function (message) {
+ console.log(message); // it prints 'a parrot response'
+ })
+ .$on('custom event', function (message) {
+ console.log(message); // it prints 'websocket server mocked response'
+ })
+ .$on('another event', function (message) {
+ console.log(message); // it prints the object {damn: 'dude', that: 'is awesome!'}
+ });
+ });
+```
+
+# Features
+
+ngWebsocket comes from Italy with lots of interesting stuff, folks!
+Why not just a wrapper? Because we can do more with happiness and fun!
+
+So, let's discover the awesome features list!
+
+## Lazy
+
+Using basic HTML5 WebSocket object, you experienced that the connection is open immediately, just after the websocket is created with **new** constructor.
+By default, the same behaviour is used by ngWebsocket but you can simply change it with this powerful feature:
+
+```javascript
+angular.run(function ($websocket, $timeout) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ lazy: true
+ });
+
+ ws.$on('$open', function () {
+ console.log('The ngWebsocket has open!'); // It will print after 5 (or more) seconds
+ });
+
+ $timeout(function () {
+ ws.$open(); // Open the connction only at this point. It will fire the '$open' event
+ }, 5000);
+});
+```
+
+With [$websocket.$open](#open) function, you can open the connection when you want, especially after the coffee break.
+
+**Default: disabled**
+
+## Reconnect
+
+Ok, your websocket connection went down due to a bad wifi connection and you don't want to make another connection
+manually, right?
+So, what about an automated feature that do this for you?
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ reconnect: true // it will reconnect after 2 seconds
+ });
+
+ ws.$on('$open', function () {
+ console.log('Here we are and I\'m pretty sure to get back here for another time at least!');
+ })
+ .$on('$close', function () {
+ console.log('Got close, damn you silly wifi!');
+ });
+});
+```
+
+With this feature, if the connection goes down, it will open again after 2 seconds by default.
+If you need to get the connection back in fewer time, just use the **reconnectInterval** time slice:
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ reconnect: true,
+ reconnectInterval: 500 // it will reconnect after 0.5 seconds
+ });
+
+ ws.$on('$open', function () {
+ console.log('Here we are and I\'m pretty sure to get back here for another time at least!');
+ })
+ .$on('$close', function () {
+ console.log('Got close, damn you silly wifi!');
+ });
+});
+```
+
+**Pay attention, good sir**: if you close the ngWebsocket with the [**$close**](#close) method, it won't get the connection back
+until the [**$open**](#open) is invoked!
+
+**Default: enabled**
+
+## Enqueue
+
+From great powers come great responsability. Keep this in mind while reading this feature.
+
+Sometimes, it would be useful if someone save our websocket communication, especially when the connection is down.
+With this powerful feature, it's possible to store every unsent message in a queue and then flush them just the connection get up again.
+
+How? Enabling enqueue feature, of course!
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ lazy: true,
+ enqueue: true
+ });
+
+ ws.$emit('dude event', 'hi dude!'); // this message couldn't be forwarded because of the lazy property (the websocket is still closed)
+
+ ws.$on('$open', function () {
+ console.log('I\'m sure the above message gets sent before this log is printed in the console ;)');
+ });
+
+ ws.$open(); // when the websocket gets open, flushes every message stored in the internal queue
+});
+```
+
+**BUT** this means that each message is stored into a memory queue and it can get really big, especially if your application sends many messages in a short time slice.
+
+**Default: disabled**
+
+## Mock
+
+Dulcis in fundo, a websocket server implementation to use and test your application, without a real websocket server listening!
+Yep, you well heard!
+
+Think about this situation: you're developing the front-end part of your company application and the backend team is lazy (because every developer is lazy),
+so you couldn't start writing your section because you need to send/retrieve data to/from the server.
+
+No problem, you can!
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ mock: true
+ });
+
+ ws.$on('$open', function () {
+ ws.$emit('hi', 'dude');
+ })
+ .$on('hi', function (message) {
+ console.log(message); // it prints 'dude'
+ });
+});
+```
+
+By default, the mock feature simulate a parrot websocket server: this means that every message sent with
+a certain event, will have a response with the same structure, with the same event and the same data.
+
+However, you can setup some fixtures that simulate what your lazy back-end team is going to do after beer time:
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ mock: {
+ fixtures: {
+ hi: {
+ data: 'dude, this is a custom message!'
+ }
+ }
+ }
+ });
+
+ ws.$on('$open', function () {
+ ws.$emit('hi');
+ })
+ .$on('hi', function (message) {
+ console.log(message); // it prints 'dude, this is a custom message'
+ });
+});
+```
+
+**Default: disabled**
+
+# Testing
+
+This module uses [Karma](http://karma-runner.github.io/0.12/index.html) with [Jasmine](http://jasmine.github.io/) for unit testing, so before launching any test check out if all dependencies are correctly installed:
+
+```bash
+$ npm install
+```
+
+After that, launch the test:
+
+```bash
+$ npm test
+```
+
+# API
+
+ngWebsocket APIs are composed by four different modules:
+
+ - **$websocketProvider**
+ - **$websocket**
+ - **ngWebsocket**
+ - **$$mockWebsocket** (private but configurable)
+
+## $websocketProvider
+
+Following the API of ngWebsocket Provider
+
+### $setup
+
+If you need to setup your custom default configuration for each ngWebsocket istance, pass it to this method:
+
+```javascript
+angular.config(function ($websocketProvider) {
+ $websocketProvider.$setup({
+ lazy: false,
+ reconnect: true,
+ reconnectInterval: 2000,
+ mock: false,
+ enqueue: false
+ });
+});
+```
+
+**Usage**
+
+```javascript
+$setup(config)
+```
+
+**Arguments**
+
+| **Param** | **Type** | **Details** |
+| --------- | -------- | ----------- |
+| config | Object | default ngWebsocket configuration |
+
+**Returns**
+
+| **Type** | **Details** |
+| -------- | ----------- |
+| $websocketProvider | the $websocketProvider |
+
+## $websocket
+
+Following the API of the $websocket Service
+
+### $get
+
+Every ngWebsocket instance created with [$websocket.$new](#new) method are stored within the $websocket service.
+To get one of them, you can use **$get** with the url of the websocket you're looking for:
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$get('ws://localhost:12345');
+});
+```
+
+The url is needed because it is stored using the url as the key of an hashmap.
+
+**Usage**
+
+```javascript
+$get(url)
+```
+
+**Arguments**
+
+| **Param** | **Type** | **Details** |
+| --------- | -------- | ----------- |
+| url | String | the websocket url |
+
+**Returns**
+
+| **Type** | **Details** |
+| -------- | ----------- |
+| ngWebsocket | an instance of ngWebsocket or undefined |
+
+### $new
+
+There are two ways to create a new instance of ngWebsocket:
+
+**string (url)**
+
+The url is always needed and it has to start with the websocket schema (ws:// or wss://):
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new('ws://localhost:12345');
+});
+```
+
+A new instance is returned and the internal WebSocket has already started the connection with the websocket server on the backend.
+
+**object**
+
+All of the following configurations can be changed:
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new(
+ url: 'ws://localhost:12345',
+ lazy: false,
+ reconnect: true,
+ reconnectInterval: 2000,
+ mock: false,
+ enqueue: false
+ );
+});
+```
+
+For more information see the [ngWebsocket Constructor section](#constructor).
+
+**Usage**
+
+```javascript
+$new(url|config)
+```
+
+**Arguments**
+
+| **Param** | **Type** | **Details** |
+| --------- | -------- | ----------- |
+| url/config | String/Object | websocket url or a configuration set |
+
+**Returns**
+
+| **Type** | **Details** |
+| -------- | ----------- |
+| ngWebsocket | an instance of ngWebsocket |
+
+## ngWebsocket
+
+ngWebsocket is the core of this module.
+In a few words, it's a wrapper for the HTML5 WebSocket object, extending it with different features.
+It acts like an EventEmitter and it provides a common way to attach a handler for each fired event.
+
+Following the API in detail.
+
+### Constructor
+
+The constructor of the ngWebsocket accepts two kind of parameters:
+
+ - String: the url starting with the WebSocket schema (ws:// or wss://)
+ plus an optional String/String[] containing the protocols (this matches
+ the WebSocket constructor API)
+ - Object: a configuration containing the websocket url
+
+The url is a requirement to create a new ngWebsocket.
+An instance is always created with a factory method by the [$websocket](#websocket) service: in fact,
+it lets to make different websockets that are pointing to different urls.
+
+Example of a basic instantiation:
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new('ws://localhost:12345', ['binary', 'base64']);
+});
+```
+
+Using Object configuration:
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ lazy: false,
+ reconnect: true,
+ reconnectInterval: 2000,
+ enqueue: false,
+ mock: false,
+ protocols: ['binary', 'base64']
+ });
+});
+```
+
+Following the explanation of the configuration object - {Type} PropertyName (default):
+
+ - **{Boolean} lazy (false)**: lazy initialization. A websocket can open the connection when ngWebsocket is instantiated with [$websocket.$new](#new) (false) or afterwards with [$open](#open) (false). For more information see [Features - Lazy Initialization](#lazy)
+ - **{Boolean} reconnect (true)**: auto reconnect behaviour. A websocket can try to reopen the connection when is down (true) or stay closed (false). For more information see [Features - Auto Reconnect](#reconnect)
+ - **{Number} reconnectInterval (2000)**: auto reconnect interval. By default, a websocket try to reconnect after 2000 ms (2 seconds). For more information see [Features - Auto Reconnect](#reconnect)
+ - **{Boolean} enqueue (false)**: enqueue unsent messages. By default, a websocket discards messages when the connection is closed (false) but it can enqueue them and send afterwards the connection gets open back (true). For more information see [Features - Enqueue Unsent Messages](#enqueue)
+ - **{Boolean/Object} mock (false)**: mock a websocket server. By default, a websocket run only if the webserver socket is listening (false) but it can be useful to mock the backend to make the websocket working (true). For more information see [Features - Mock Websocket Server](#mock)
+ - **{String/String[]} (null)**: Either a single protocol string or an array of protocol strings. This is the same as the WebSocket protocols argument.
+
+### Constants
+
+Websocket status constants:
+
+ - **$CONNECTING**: the websocket is trying to open the connection
+ - **$OPEN**: the websocket connection is open
+ - **$CLOSING**: the websocket connection is closing
+ - **$CLOSED**: the websocket connection is closed
+
+### Events
+
+There are custom events fired by ngWebsocket.
+They are useful to setup a listener for certain situations and behaviours:
+
+ - **$open**: the websocket gets open
+ - **$close**: the websocket gets closed
+ - **$error**: an error occurred (callback params: {Error} error)
+ - **$message**: the original message sent from the server (callback params: {String} message). Usually, it's a JSON encoded string containing the event to fire and the data to pass ({"event": "an event", "data": "some data"})
+
+The other events are custom events, setup by the user itself.
+
+### $on
+
+Attach one or more handlers to a specific event.
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new('ws://localhost:12345');
+
+ // Single event handler
+ ws.$on('my event', function myHandler () {...});
+
+ // Different event handlers
+ ws.$on('another event', myHandler, mySecondHandler, myThirdHandler);
+
+ // Different chained event handlers
+ ws.$on('third event', function myHandler () {...})
+ .$on('third event', function mySecondHandler () {...})
+ .$on('third event', function myThirdHandler () {...});
+});
+```
+
+Now the websocket is listening for 'my event' event and the handler 'myHandler' will be called when that event
+is sent by the websocket server. The same thing happens for the other two cases: each event handler is called
+one by one, starting from the first one, ending with the last one.
+
+**Usage**
+
+```javascript
+$on(event, handler|handlers)
+```
+
+**Arguments**
+
+| **Param** | **Type** | **Details** |
+| --------- | -------- | ----------- |
+| event | String | the event to attach a listener |
+| handler/handlers | Function/Function[] | one or more handlers to invoke when the event is fired up |
+
+**Returns**
+
+| **Type** | **Details** |
+| -------- | ----------- |
+| ngWebsocket | the ngWebsocket |
+
+### $un
+
+Detach a handler from a specific event.
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new('ws://localhost:12345');
+
+ ws.$on('my event', function myHandler () {...});
+ ws.$un('my event');
+});
+```
+
+The above websocket has not listener attached at the end of the execution.
+
+
+**Usage**
+
+```javascript
+$un(event)
+```
+
+**Arguments**
+
+| **Param** | **Type** | **Details** |
+| --------- | -------- | ----------- |
+| event | String | the event to detach the listener |
+
+**Returns**
+
+| **Type** | **Details** |
+| -------- | ----------- |
+| ngWebsocket | the ngWebsocket |
+
+### $emit
+
+Send an event to the websocket server.
+
+It's possible to send a lonely event or attaching some data to it.
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new('ws://localhost:12345');
+
+ ws.$on('$open', function () {
+ ws.$emit('lonely event'); // the websocket server will receive only the event name
+ ws.$emit('event with data', 'some data'); // it will send the event with 'some data' string
+ ws.$emit('with object', {some: 'data'}); // it will send the event with the object JSONified
+ });
+});
+```
+
+It's possible to send both simply (like strings and numbers) and complex data (like objects and arrays).
+
+**Usage**
+
+```javascript
+$emit(event, [data])
+```
+
+**Arguments**
+
+| **Param** | **Type** | **Details** |
+| --------- | -------- | ----------- |
+| event | String | the event to send |
+| data (optional) | String/Number/Object | the data to send with the event |
+
+**Returns**
+
+| **Type** | **Details** |
+| -------- | ----------- |
+| ngWebsocket | the ngWebsocket |
+
+### $open
+
+Open the websocket connection if it's closed.
+
+```javascript
+angular.run(function ($websocket, $timeout) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ lazy: true
+ });
+
+ ws.$on('$open', function () {
+ console.log('The websocket now is open');
+ });
+
+ $timeout(function () {
+ ws.$open(); // it will open the websocket after 5 seconds
+ }, 5000);
+```
+
+**Usage**
+
+```javascript
+$open()
+```
+
+**Returns**
+
+| **Type** | **Details** |
+| -------- | ----------- |
+| ngWebsocket | the ngWebsocket |
+
+### $close
+
+It closes the websocket connection if it's open.
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new(url: 'ws://localhost:12345');
+
+ ws.$on('$open', function () {
+ ws.$close(); // it closes the websocket connection
+ });
+
+ ws.$on('$close', function () {
+ console.log('Connection closed!');
+ });
+```
+
+**Usage**
+
+```javascript
+$close()
+```
+
+**Returns**
+
+| **Type** | **Details** |
+| -------- | ----------- |
+| ngWebsocket | the ngWebsocket |
+
+### $status
+
+It returns the current status of the websocket connection.
+It's possible to use the [websocket constants](#constants) to make checks.
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new(url: 'ws://localhost:12345');
+
+ console.log(ws.$status()); // it prints ws.$CONNECTING
+
+ ws.$on('$open', function () {
+ console.log(ws.$status()); // it prints ws.$OPEN
+ ws.$close(); // it closes the websocket connection
+ console.log(ws.$status()); // it prints ws.$CLOSING
+ });
+
+ ws.$on('$close', function () {
+ console.log(ws.$status()); // it prints ws.$CLOSED
+ console.log('Connection closed!');
+ });
+```
+
+**Usage**
+
+```javascript
+$status()
+```
+
+**Returns**
+
+| **Type** | **Details** |
+| -------- | ----------- |
+| Number | a constant number representing the websocket connection readyState |
+
+### $ready
+
+It returns if the websocket connection is open or closed.
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new(url: 'ws://localhost:12345');
+
+ console.log(ws.$ready()); // it prints false
+
+ ws.$on('$open', function () {
+ console.log(ws.$ready()); // it prints true
+ ws.$close(); // it closes the websocket connection
+ console.log(ws.$ready()); // it prints false
+ });
+
+ ws.$on('$close', function () {
+ console.log(ws.$ready()); // it prints false
+ console.log('Connection closed!');
+ });
+```
+
+**Usage**
+
+```javascript
+$ready()
+```
+
+**Returns**
+
+| **Type** | **Details** |
+| -------- | ----------- |
+| Boolean | true if the connection is OPEN, false otherwise |
+
+### $mockup
+
+It returns if the websocket is mocked up or not.
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new(url: 'ws://localhost:12345');
+
+ console.log(ws.$mockup()); // it prints false
+
+ var ws2 = $websocket.$new({
+ url: 'ws://localhost:54321',
+ mock: true
+ });
+
+ console.log(ws.$mockup()); // it prints true
+```
+
+**Usage**
+
+```javascript
+$mockup()
+```
+
+**Returns**
+
+| **Type** | **Details** |
+| -------- | ----------- |
+| Boolean | true if the ngWebsocket istance is mocked up, false otherwise |
+
+## $$mockWebsocket
+
+If you need to develop or test your application without a real websocket backend server, you can setup
+a mockup of it with this feature.
+The only thing to do is to pass a configuration object during the ngWebsocket initialization:
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ mock: {
+ openTimeout: 500,
+ closeTimeout: 1000,
+ messageInterval: 2000,
+ fixtures: {}
+ }
+ });
+```
+
+Following the explanation of the configuration object - {Type} PropertyName (default)::
+
+ - **{Boolean/Object} mock (false)**: could be either a Boolean (default to false) or an object
+ - **{Number} openTimeout (500)**: timeout to make the internal websocket to get open
+ - **{Number} closeTimeout (1000)**: timeout to make the internal websocket to get closed
+ - **{Number} messageInterval (2000)**: the internal websocket sends enqueued message with this interval time
+ - **{Object/String} fixtures ({})**: an object of fixtures, where the keys are the events and the values are the data to respond, or an url to retrieve remote fixtures via HTTP
+
+Fixtures can mock both custom events and data.
+They can be added as a static object with the following structure:
+
+```javascript
+fixtures: {
+ 'incoming event name': {
+ event: 'outgoing event name',
+ data: 'response data'
+ }
+}
+```
+
+The *incoming event name* is the event fired by the websocket while the *outgoing event name* is the one sent by the mocked webserver.
+So, it be useful to map events with a custom response.
+By default, the mock feature acts like a parrot server, responding with the same data on the same received event.
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ mock: {
+ fixtures: {
+ 'mock data': {
+ data: {
+ hello: 'world'
+ }
+ },
+ 'mock data and event': {
+ event: 'custom event',
+ data: {
+ hello: 'mocked world'
+ }
+ }
+ }
+ }
+ });
+
+ ws.$on('$open', function () {
+ ws.$emit('parrot event', 'parrot data')
+ .$emit('mock data')
+ .$emit('mock data and event');
+ })
+ .$on('parrot event', function (message) {
+ console.log(message); // it prints 'parrot data'
+ })
+ .$on('mock data', function (message) {
+ console.log(message); // it prints '{hello: 'world'}'
+ })
+ .$on('custom event', function (message) {
+ console.log(message); // it prints '{hello: 'mocked world'}'
+ });
+```
+
+Fixtures can be loaded through an HTTP request.
+In fact, it be useful to have those in a JSON file or created by the webserver:
+
+```javascript
+angular.run(function ($websocket) {
+ var ws = $websocket.$new({
+ url: 'ws://localhost:12345',
+ mock: {
+ fixtures: '/fixtures.json' // fixtures are located in a file or calculated at run-time by the web server
+ }
+ });
+
+ // Now you're ready to use fixtures because the websocket will be available only when the fixtures are loaded
+});
+```
+
+# Contribute
+
+Wanna contribute, fella?
+That's the right place to find useful information!
+
+How?
+
+ - improve and fix the documentation
+ - test it
+ - make some demos
+ - use it
+ - write new pieces of code
+ - optimize it
+ - find bugs
+
+And don't forget to make **pull requests**, damn it!
+
+# License
+
+Check out LICENSE file (MIT) \ No newline at end of file
diff --git a/www/lib/ng-websocket/bower.json b/www/lib/ng-websocket/bower.json
new file mode 100644
index 00000000..3c3e89b6
--- /dev/null
+++ b/www/lib/ng-websocket/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "ng-websocket",
+ "version": "0.2.1",
+ "authors": [
+ "Vincenzo (Wilk) Ferrari <wilk3ert@gmail.com>"
+ ],
+ "description": "AngularJS HTML5 WebSocket powerful library",
+ "main": "ng-websocket.js",
+ "keywords": [
+ "angular",
+ "angularjs",
+ "websocket",
+ "ng",
+ "html5",
+ "service",
+ "provider"
+ ],
+ "license": "MIT",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "angular": "~1.3.2"
+ },
+ "devDependencies": {
+ "angular-mocks": "~1.3.2"
+ }
+}
diff --git a/www/lib/ng-websocket/ng-websocket.js b/www/lib/ng-websocket/ng-websocket.js
new file mode 100644
index 00000000..92192c73
--- /dev/null
+++ b/www/lib/ng-websocket/ng-websocket.js
@@ -0,0 +1,370 @@
+'use strict';
+
+(function () {
+ /**
+ * @ngdoc provider
+ * @name $websocketProvider
+ * @module ngWebsocket
+ * @description
+ * HTML5 WebSocket provider for AngularJS
+ */
+ function $websocketProvider () {
+ var wsp = this;
+
+ wsp.$$config = {
+ lazy: false,
+ reconnect: true,
+ reconnectInterval: 2000,
+ mock: false,
+ enqueue: false,
+ protocols: null
+ };
+
+ wsp.$setup = function (cfg) {
+ cfg = cfg || {};
+ wsp.$$config = angular.extend({}, wsp.$$config, cfg);
+
+ return wsp;
+ };
+
+ wsp.$get = ['$http', function ($http) {
+ return new $websocketService(wsp.$$config, $http);
+ }];
+ }
+
+ /**
+ * @ngdoc service
+ * @name $websocketService
+ * @module ngWebsocketService
+ * @description
+ * HTML5 Websocket service for AngularJS
+ */
+ function $websocketService (cfg, $http) {
+ var wss = this;
+
+ wss.$$websocketList = {};
+ wss.$$config = cfg || {};
+
+ wss.$get = function (url) {
+ return wss.$$websocketList[url];
+ };
+
+ wss.$new = function (cfg) {
+ cfg = cfg || {};
+
+ // Url or url + protocols initialization
+ if (typeof cfg === 'string') {
+ cfg = {url: cfg};
+
+ // url + protocols
+ if (arguments.length > 1) {
+ if (typeof arguments[1] === 'string' && arguments[1].length > 0) cfg.protocols = [arguments[1]];
+ else if (typeof arguments[1] === 'object' && arguments[1].length > 0) cfg.protocols = arguments[1];
+ }
+ }
+
+ // If the websocket already exists, return that instance
+ var ws = wss.$get(cfg.url);
+ if (typeof ws === 'undefined') {
+ var wsCfg = angular.extend({}, wss.$$config, cfg);
+
+ ws = new $websocket(wsCfg, $http);
+ wss.$$websocketList[wsCfg.url] = ws;
+ }
+
+ return ws;
+ };
+ }
+
+ /**
+ * @ngdoc class
+ * @name $websocket
+ * @module ngWebsocket
+ * @description
+ * HTML5 Websocket wrapper class for AngularJS
+ */
+ function $websocket (cfg, $http) {
+ var me = this;
+
+ if (typeof cfg === 'undefined' || (typeof cfg === 'object' && typeof cfg.url === 'undefined')) throw new Error('An url must be specified for WebSocket');
+
+ me.$$eventMap = {};
+ me.$$ws = undefined;
+ me.$$reconnectTask = undefined;
+ me.$$reconnectCopy = true;
+ me.$$queue = [];
+ me.$$config = {
+ url: undefined,
+ lazy: false,
+ reconnect: true,
+ reconnectInterval: 2000,
+ enqueue: false,
+ mock: false,
+ protocols: null
+ };
+
+ me.$$fireEvent = function () {
+ var args = [];
+
+ Array.prototype.push.apply(args, arguments);
+
+ var event = args.shift(),
+ handlers = me.$$eventMap[event];
+
+ if (typeof handlers !== 'undefined') {
+ for (var i = 0; i < handlers.length; i++) {
+ if (typeof handlers[i] === 'function') handlers[i].apply(me, args);
+ }
+ }
+ };
+
+ me.$$init = function (cfg) {
+ me.$$ws = cfg.mock ? new $$mockWebsocket(cfg.mock, $http) : new WebSocket(cfg.url, cfg.protocols);
+
+ me.$$ws.onmessage = function (message) {
+ try {
+ var decoded = JSON.parse(message.data);
+ me.$$fireEvent(decoded.event, decoded.data);
+ me.$$fireEvent('$message', decoded);
+ }
+ catch (err) {
+ me.$$fireEvent('$message', message.data);
+ }
+ };
+
+ me.$$ws.onerror = function (error) {
+ me.$$fireEvent('$error', error);
+ };
+
+ me.$$ws.onopen = function () {
+ // Clear the reconnect task if exists
+ if (me.$$reconnectTask) {
+ clearInterval(me.$$reconnectTask);
+ delete me.$$reconnectTask;
+ }
+
+ // Flush the message queue
+ if (me.$$config.enqueue && me.$$queue.length > 0) {
+ while (me.$$queue.length > 0) {
+ if (me.$ready()) me.$$send(me.$$queue.shift());
+ else break;
+ }
+ }
+
+ me.$$fireEvent('$open');
+ };
+
+ me.$$ws.onclose = function () {
+ // Activate the reconnect task
+ if (me.$$config.reconnect) {
+ me.$$reconnectTask = setInterval(function () {
+ if (me.$status() === me.$CLOSED) me.$open();
+ }, me.$$config.reconnectInterval);
+ }
+
+ me.$$fireEvent('$close');
+ };
+
+ return me;
+ };
+
+ me.$CONNECTING = 0;
+ me.$OPEN = 1;
+ me.$CLOSING = 2;
+ me.$CLOSED = 3;
+
+ // TODO: it doesn't refresh the view (maybe $apply on something?)
+ /*me.$bind = function (event, scope, model) {
+ me.$on(event, function (message) {
+ model = message;
+ scope.$apply();
+ });
+ };*/
+
+ me.$on = function () {
+ var handlers = [];
+
+ Array.prototype.push.apply(handlers, arguments);
+
+ var event = handlers.shift();
+ if (typeof event !== 'string' || handlers.length === 0) throw new Error('$on accept two parameters at least: a String and a Function or an array of Functions');
+
+ me.$$eventMap[event] = me.$$eventMap[event] || [];
+ for (var i = 0; i < handlers.length; i++) {
+ me.$$eventMap[event].push(handlers[i]);
+ }
+
+ return me;
+ };
+
+ me.$un = function (event) {
+ if (typeof event !== 'string') throw new Error('$un needs a String representing an event.');
+
+ if (typeof me.$$eventMap[event] !== 'undefined') delete me.$$eventMap[event];
+
+ return me;
+ };
+
+ me.$$send = function (message) {
+ if (me.$ready()) me.$$ws.send(JSON.stringify(message));
+ else if (me.$$config.enqueue) me.$$queue.push(message);
+ };
+
+ me.$emit = function (event, data) {
+ if (typeof event !== 'string') throw new Error('$emit needs two parameter: a String and a Object or a String');
+
+ var message = {
+ event: event,
+ data: data
+ };
+
+ me.$$send(message);
+
+ return me;
+ };
+
+ me.$open = function () {
+ me.$$config.reconnect = me.$$reconnectCopy;
+
+ if (me.$status() !== me.$OPEN) me.$$init(me.$$config);
+ return me;
+ };
+
+ me.$close = function () {
+ if (me.$status() !== me.$CLOSED) me.$$ws.close();
+
+ if (me.$$reconnectTask) {
+ clearInterval(me.$$reconnectTask);
+ delete me.$$reconnectTask;
+ }
+
+ me.$$config.reconnect = false;
+
+ return me;
+ };
+
+ me.$status = function () {
+ if (typeof me.$$ws === 'undefined') return me.$CLOSED;
+ else return me.$$ws.readyState;
+ };
+
+ me.$ready = function () {
+ return me.$status() === me.$OPEN;
+ };
+
+ me.$mockup = function () {
+ return me.$$config.mock;
+ };
+
+ // setup
+ me.$$config = angular.extend({}, me.$$config, cfg);
+ me.$$reconnectCopy = me.$$config.reconnect;
+
+ if (!me.$$config.lazy) me.$$init(me.$$config);
+
+ return me;
+ }
+
+ function $$mockWebsocket (cfg, $http) {
+ cfg = cfg || {};
+
+ var me = this,
+ openTimeout = cfg.openTimeout || 500,
+ closeTimeout = cfg.closeTimeout || 1000,
+ messageInterval = cfg.messageInterval || 2000,
+ fixtures = cfg.fixtures || {},
+ messageQueue = [];
+
+ me.CONNECTING = 0;
+ me.OPEN = 1;
+ me.CLOSING = 2;
+ me.CLOSED = 3;
+
+ me.readyState = me.CONNECTING;
+
+ me.send = function (message) {
+ if (me.readyState === me.OPEN) {
+ messageQueue.push(message);
+ return me;
+ }
+ else throw new Error('WebSocket is already in CLOSING or CLOSED state.');
+ };
+
+ me.close = function () {
+ if (me.readyState === me.OPEN) {
+ me.readyState = me.CLOSING;
+
+ setTimeout(function () {
+ me.readyState = me.CLOSED;
+
+ me.onclose();
+ }, closeTimeout);
+ }
+
+ return me;
+ };
+
+ me.onmessage = function () {};
+ me.onerror = function () {};
+ me.onopen = function () {};
+ me.onclose = function () {};
+
+ setInterval(function () {
+ if (messageQueue.length > 0) {
+ var message = messageQueue.shift(),
+ msgObj = JSON.parse(message);
+
+ switch (msgObj.event) {
+ case '$close':
+ me.close();
+ break;
+ default:
+ // Check for a custom response
+ if (typeof fixtures[msgObj.event] !== 'undefined') {
+ msgObj.data = fixtures[msgObj.event].data || msgObj.data;
+ msgObj.event = fixtures[msgObj.event].event || msgObj.event;
+ }
+
+ message = JSON.stringify(msgObj);
+
+ me.onmessage({
+ data: message
+ });
+ }
+ }
+ }, messageInterval);
+
+ var start = function (fixs) {
+ fixs = fixs || {};
+ fixs = fixs instanceof Error ? {} : fixs;
+
+ fixtures = fixs;
+
+ setTimeout(function () {
+ me.readyState = me.OPEN;
+ me.onopen();
+ }, openTimeout);
+ };
+
+ // Get fixtures from a server or a file if it's a string
+ if (typeof fixtures === 'string') {
+ $http.get(fixtures)
+ .success(start)
+ .error(start);
+ }
+ else start(fixtures);
+
+ return me;
+ }
+
+ /**
+ * @ngdoc module
+ * @name $websocket
+ * @module ngWebsocket
+ * @description
+ * HTML5 WebSocket module for AngularJS
+ */
+ angular
+ .module('ngWebsocket', [])
+ .provider('$websocket', $websocketProvider);
+})(); \ No newline at end of file
diff --git a/www/lib/ng-websocket/package.json b/www/lib/ng-websocket/package.json
new file mode 100644
index 00000000..292299d2
--- /dev/null
+++ b/www/lib/ng-websocket/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "ngWebSocket",
+ "version": "0.0.0",
+ "description": "AngularJS WebSocket wrapper",
+ "main": "ng-websocket.js",
+ "scripts": {
+ "postinstall": "bower install",
+ "test": "node_modules/gulp/bin/gulp.js test"
+ },
+ "repository": "",
+ "keywords": [
+ "angular",
+ "websocket",
+ "angularjs",
+ "hmlt5",
+ "ng"
+ ],
+ "author": "Vincenzo (Wilk) Ferrari <wilk3ert@gmail.com>",
+ "license": "MIT",
+ "readmeFilename": "README.md",
+ "gitHead": "3bb59ef67d27eff0e88e637d0999b3e2141ef398",
+ "devDependencies": {
+ "ws": "~0.4.32",
+ "karma": "~0.12.22",
+ "karma-jasmine": "~0.2.0",
+ "karma-mocha-reporter": "~0.3.1",
+ "karma-phantomjs-launcher": "~0.1.4",
+ "gulp-karma": "0.0.4",
+ "gulp": "~3.8.7"
+ }
+}