From 147a639499fb894ae92521384b84e0f84fed48ae Mon Sep 17 00:00:00 2001
From: Joao Mesquita <jmesquita@indicium.com.ar>
Date: Fri, 21 Aug 2015 18:17:14 -0300
Subject: [PATCH] FS-8009 Now we are using grunt for building as well and
 replace contrib-connect for browser-sync because we like use the new kids on
 the block.

---
 html5/verto/verto_communicator/.gitignore     |   4 +
 html5/verto/verto_communicator/.jshintrc      |  18 +
 html5/verto/verto_communicator/Gruntfile.js   | 313 ++++++++++++++++--
 html5/verto/verto_communicator/README.md      |   8 +
 html5/verto/verto_communicator/bower.json     |  12 +-
 html5/verto/verto_communicator/index.html     |  10 +-
 .../verto_communicator/js/controllers.js      |  15 +-
 .../verto_communicator/js/verto-service.js    |   4 +-
 html5/verto/verto_communicator/package.json   |  32 +-
 9 files changed, 361 insertions(+), 55 deletions(-)
 create mode 100644 html5/verto/verto_communicator/.gitignore
 create mode 100644 html5/verto/verto_communicator/.jshintrc
 create mode 100644 html5/verto/verto_communicator/README.md

diff --git a/html5/verto/verto_communicator/.gitignore b/html5/verto/verto_communicator/.gitignore
new file mode 100644
index 0000000000..7274d6169c
--- /dev/null
+++ b/html5/verto/verto_communicator/.gitignore
@@ -0,0 +1,4 @@
+dist/
+.tmp/
+bower_components/
+node_modules/
diff --git a/html5/verto/verto_communicator/.jshintrc b/html5/verto/verto_communicator/.jshintrc
new file mode 100644
index 0000000000..bea9497bb7
--- /dev/null
+++ b/html5/verto/verto_communicator/.jshintrc
@@ -0,0 +1,18 @@
+{
+  "bitwise": true,
+  "browser": true,
+  "curly": true,
+  "eqeqeq": true,
+  "esnext": true,
+  "latedef": true,
+  "noarg": true,
+  "node": true,
+  "strict": true,
+  "undef": true,
+  "unused": true,
+  "globals": {
+    "angular": false,
+    "jQuery": false,
+    "$": false
+  }
+}
\ No newline at end of file
diff --git a/html5/verto/verto_communicator/Gruntfile.js b/html5/verto/verto_communicator/Gruntfile.js
index d956edc06a..0cbf3d4475 100644
--- a/html5/verto/verto_communicator/Gruntfile.js
+++ b/html5/verto/verto_communicator/Gruntfile.js
@@ -1,68 +1,313 @@
 /*jslint node: true */
 'use strict';
 
-var pkg = require('./package.json');
+// var pkg = require('./package.json');
 
 module.exports = function (grunt) {
 
+  // Time how long tasks take. Can help when optimizing build times
+  require('time-grunt')(grunt);
+  
   // load all grunt tasks
-  require('load-grunt-tasks')(grunt);
+  require('jit-grunt')(grunt, {
+    includereplace: 'grunt-include-replace',
+    useminPrepare: 'grunt-usemin'
+  });
+
+  // Configurable paths
+  var config = {
+    app: '.',
+    dist: 'dist'
+  };
+
+  var ip = grunt.option('ip') || 'localhost';
 
   // Project configuration.
   grunt.initConfig({
+    // Project settings
+    config: config,
+
+    // Watch things 
     watch: {
+      bower: {
+        files: ['bower.json'],
+        tasks: ['wiredep']
+      },
       js: {
-        files: ['js/{,*/}*.js'],
-        tasks: ['newer:jshint:all'],
-        options: {
-          livereload: true
-        }
+        files: ['js/verto-service.js'],
+        tasks: ['includereplace:dev']
+      },
+      styles: {
+        files: ['<%= config.app %>/css/{,*/}*.css'],
+        tasks: ['newer:copy:styles', 'postcss']
       },
       gruntfile: {
         files: ['Gruntfile.js']
-      },
-      livereload: {
-        options: {
-          livereload: true
-        },
-        files: [
-          'index.html',
-          'partials/{,*/}*.html',
-          'js/{,*/}*.js',
-          'images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
-        ]
       }
     },
+
+    // Replace so we can have it properly passed from dev
+    includereplace: {
+      dev: {
+        options: {
+          globals: {
+            ip: ip
+          },
+        },
+        src: 'js/verto-service.js',
+        dest: '.tmp/js/verto-service.js'
+      },
+      prod: {
+        options: {
+          globals: {
+            ip: ip
+          },
+        },
+        src: 'js/verto-service.js',
+        dest: 'dist/js/'
+      }      
+    },
     wiredep: {
       app: {
         src: ['index.html'],
         ignorePath:  /\.\.\//
       }
     },
-    connect: {
+
+    postcss: {
       options: {
-        port: 9001,
-        // Change this to '0.0.0.0' to access the server from outside.
-        hostname: 'localhost',
-        livereload: 35729,
-        protocol: 'https'
+        map: true,
+        processors: [
+          // Add vendor prefixed styles
+          require('autoprefixer-core')({
+            browsers: ['> 1%', 'last 2 versions', 'Firefox ESR', 'Opera 12.1']
+          })
+        ]
+      },
+      dist: {
+        files: [{
+          expand: true,
+          cwd: '.tmp/styles/',
+          src: '{,*/}*.css',
+          dest: '.tmp/styles/'
+        }]
+      }
+    },
+
+    browserSync: {
+      options: {
+        notify: false,
+        background: true,
+        https: true,
+        open: false
       },
       livereload: {
         options: {
-          open: false,
-          middleware: function (connect) {
-            return [
-              connect().use(
-                '/js/src',
-                connect.static('../js/src')
-              ),
-              connect.static('.')
-            ];
+          files: [
+            '<%= config.app %>/{,*/}*.html',
+            '.tmp/styles/{,*/}*.css',
+            '<%= config.app %>/images/{,*/}*',
+            '.tmp/js/{,*/}*.js',
+            '<%= config.app %>/js/**/*.js'
+          ],
+          port: 9001,
+          server: {
+            baseDir: ['.tmp', '../js/src/', config.app],
+            routes: {
+              '/bower_components': './bower_components',
+              '/js/src': '../js/src'
+            }
           }
         }
       },
     },
+
+    jshint: {
+      options: {
+        jshintrc: '.jshintrc',
+        reporter: require('jshint-stylish'),
+        ignores: ['js/3rd-party/**/*.js'],
+        force: true // TODO: Remove this once we get files linted correctly!!!
+      },
+      all: {
+        src: [
+          'Gruntfile.js',
+          'js/{,*/}*.js'
+        ]
+      }
+    },
+    clean: {
+      dist: {
+        files: [{
+          dot: true,
+          src: [
+            '.tmp',
+            'dist/{,*/}*',
+            '!dist/.git{,*/}*'
+            ]
+          }]
+        },
+      server: '.tmp'
+    },
+    // Renames files for browser caching purposes
+    filerev: {
+      dist: {
+        src: [
+          'dist/scripts/{,*/}*.js',
+          'dist/css/{,*/}*.css',
+          'dist/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
+          'dist/css/fonts/*'
+        ]
+      }
+    },
+    // Reads HTML for usemin blocks to enable smart builds that automatically
+    // concat, minify and revision files. Creates configurations in memory so
+    // additional tasks can operate on them
+    useminPrepare: {
+      options: {
+        dest: '<%= config.dist %>'
+      },
+      html: '<%= config.app %>/index.html'
+    },
+
+    // Performs rewrites based on rev and the useminPrepare configuration
+    usemin: {
+      options: {
+        assetsDirs: [
+          '<%= config.dist %>',
+          '<%= config.dist %>/images',
+          '<%= config.dist %>/styles'
+        ]
+      },
+      html: ['<%= config.dist %>/{,*/}*.html'],
+      css: ['<%= config.dist %>/styles/{,*/}*.css']
+    },
+
+    // The following *-min tasks produce minified files in the dist folder
+    imagemin: {
+      dist: {
+        files: [{
+          expand: true,
+          cwd: '<%= config.app %>/images',
+          src: '{,*/}*.{gif,jpeg,jpg,png}',
+          dest: '<%= config.dist %>/images'
+        }]
+      }
+    },
+
+    svgmin: {
+      dist: {
+        files: [{
+          expand: true,
+          cwd: '<%= config.app %>/images',
+          src: '{,*/}*.svg',
+          dest: '<%= config.dist %>/images'
+        }]
+      }
+    },
+
+    htmlmin: {
+      dist: {
+        options: {
+          collapseBooleanAttributes: true,
+          collapseWhitespace: true,
+          conservativeCollapse: true,
+          removeAttributeQuotes: true,
+          removeCommentsFromCDATA: true,
+          removeEmptyAttributes: true,
+          removeOptionalTags: true,
+          // true would impact styles with attribute selectors
+          removeRedundantAttributes: false,
+          useShortDoctype: true
+        },
+        files: [{
+          expand: true,
+          cwd: '<%= config.dist %>',
+          src: '{,*/}*.html',
+          dest: '<%= config.dist %>'
+        }]
+      }
+    },
+     // ng-annotate tries to make the code safe for minification automatically
+     // by using the Angular long form for dependency injection.
+     ngAnnotate: {
+       dist: {
+         files: [{
+           expand: true,
+           cwd: '.tmp/concat/scripts',
+           src: '*.js',
+           dest: '.tmp/concat/scripts'
+         }]
+       }
+     },
+     // Copies remaining files to places other tasks can use
+     copy: {
+       dist: {
+         files: [{
+           expand: true,
+           dot: true,
+           cwd: '',
+           dest: 'dist',
+           src: [
+             '*.{ico,png,txt}',
+             '*.html',
+             'images/{,*/}*.{webp}',
+             'css/fonts/{,*/}*.*'
+           ]
+         }, {
+           expand: true,
+           cwd: '.tmp/images',
+           dest: 'dist/images',
+           src: ['generated/*']
+         }, {
+           expand: true,
+           cwd: 'bower_components/bootstrap/dist',
+           src: 'fonts/*',
+           dest: 'dist'
+         }]
+       },
+       styles: {
+         expand: true,
+         cwd: '/css',
+         dest: '.tmp/css/',
+         src: '{,*/}*.css'
+       }
+     },
+     // Run some tasks in parallel to speed up the build process
+     concurrent: {
+       server: [
+         'copy:styles'
+       ],
+       dist: [
+         'copy:styles',
+         'imagemin',
+         'svgmin'
+       ]
+     },
   });
 
-  grunt.registerTask('serve', ['wiredep', 'connect:livereload', 'watch']);
+  grunt.registerTask('serve', ['clean:server',
+      'wiredep',
+      'concurrent:server',
+      'postcss',
+      'includereplace:dev',
+      'browserSync:livereload',
+      'watch']);
+  
+  grunt.registerTask('build', [
+    'clean:dist',
+    'wiredep',
+    'useminPrepare',
+    'concurrent:dist',
+    'postcss',
+    'concat',
+    'cssmin',
+    'ngAnnotate',
+    'uglify',
+    'copy:dist',
+    'filerev',
+    'usemin',
+    'htmlmin'
+  ]);
+
 };
diff --git a/html5/verto/verto_communicator/README.md b/html5/verto/verto_communicator/README.md
new file mode 100644
index 0000000000..707783501f
--- /dev/null
+++ b/html5/verto/verto_communicator/README.md
@@ -0,0 +1,8 @@
+brew install npm
+
+npm install -g grunt grunt-cli bower
+
+cd verto_communicator
+npm install
+bower install
+grunt serve
\ No newline at end of file
diff --git a/html5/verto/verto_communicator/bower.json b/html5/verto/verto_communicator/bower.json
index bc8395cafc..623a51d1cc 100644
--- a/html5/verto/verto_communicator/bower.json
+++ b/html5/verto/verto_communicator/bower.json
@@ -25,7 +25,7 @@
   ],
   "dependencies": {
     "angular-gravatar": "~0.4.1",
-    "bootstrap": "~3.3.5",
+    "bootstrap": "~3.3.4",
     "angular-toastr": "~1.4.1",
     "angular": "~1.3.15",
     "angular-route": "~1.3.15",
@@ -44,17 +44,17 @@
     "bootstrap-material-design": "~0.3.0"
   },
   "resolutions": {
-    "angular": "~1.3.15"
+    "angular": "~1.3.15",
+    "angular-bootstrap": "~0.13.3"
   },
-  "overrides":{
-    "bootstrap" : {
+  "overrides": {
+    "bootstrap": {
       "main": [
-        "less/bootstrap.less",
         "dist/css/bootstrap.css",
         "dist/js/bootstrap.js"
       ]
     },
-    "jquery-json" : {
+    "jquery-json": {
       "main": [
         "src/jquery.json.js"
       ]
diff --git a/html5/verto/verto_communicator/index.html b/html5/verto/verto_communicator/index.html
index cddd8c4ad8..c284bd4bb7 100644
--- a/html5/verto/verto_communicator/index.html
+++ b/html5/verto/verto_communicator/index.html
@@ -11,6 +11,7 @@
 
     <title ng-bind="'[' + title + '] ' + 'FreeSWITCH Verto&trade; Video Transcoding'"></title>
 
+    <!-- build:css(.) css/vendor.css -->
     <!-- bower:css -->
     <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
     <link rel="stylesheet" href="bower_components/angular-toastr/dist/angular-toastr.css" />
@@ -19,9 +20,12 @@
     <link rel="stylesheet" href="bower_components/bootstrap-material-design/dist/css/material.css" />
     <link rel="stylesheet" href="bower_components/bootstrap-material-design/dist/css/ripples.css" />
     <!-- endbower -->
+    <!-- endbuild -->
 
     <!-- CSS -->
+    <!-- build:css(.tmp) css/main.css -->
     <link rel="stylesheet" type="text/css" href="css/verto.css">
+    <!-- endbuild -->
 
 
     <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
@@ -55,6 +59,7 @@
    
     <!--<script type="text/javascript" src="js/jquery/jquery.mobile.min.js"></script>-->
 
+    <!-- build:js(.) scripts/vendor.js -->
     <!-- bower:js -->
     <script src="bower_components/jquery/dist/jquery.js"></script>
     <script src="bower_components/angular/angular.js"></script>
@@ -78,11 +83,12 @@
     <script src="bower_components/bootstrap-material-design/dist/js/material.js"></script>
     <script src="bower_components/bootstrap-material-design/dist/js/ripples.js"></script>
     <!-- endbower -->
+    <!-- endbuild -->
 
+    <!-- build:js(.) scripts/scripts.js -->
     <script type="text/javascript" src="../js/src/jquery.jsonrpcclient.js"></script>
     <script type="text/javascript" src="../js/src/jquery.FSRTC.js"></script>
     <script type="text/javascript" src="../js/src/jquery.verto.js"></script>
-
     <script type="text/javascript" src="js/3rd-party/getScreenId.js"></script>
     <script type="text/javascript" src="js/3rd-party/md5.min.js"></script>
     <script type="text/javascript" src="js/filters.js"></script>
@@ -91,6 +97,8 @@
     <script type="text/javascript" src="js/app.js"></script>
     <script type="text/javascript" src="js/controllers.js"></script>
     <script type="text/javascript" src="js/directives.js"></script>
+    <!-- endbuild -->
+
   </body>
 </html>
 
diff --git a/html5/verto/verto_communicator/js/controllers.js b/html5/verto/verto_communicator/js/controllers.js
index a4bfd07b50..9b10bb6434 100644
--- a/html5/verto/verto_communicator/js/controllers.js
+++ b/html5/verto/verto_communicator/js/controllers.js
@@ -15,7 +15,7 @@ vertoControllers.filter('gravatar',
       }
       var hash = md5(email);
       return 'https://secure.gravatar.com/avatar/' + hash + '?s=' + size + '&d=mm';
-    }
+    };
   });
 
 
@@ -90,8 +90,7 @@ vertoControllers.controller('MainController', ['$scope', '$rootScope',
             toastr.success('Login successful.', 'Welcome');
             $location.path('/dialpad');
           } else {
-            toastr.error('There was an error while trying to login. \
-            Please try again.', 'Error');
+            toastr.error('There was an error while trying to login. Please try again.', 'Error');
           }
         });
       };
@@ -119,7 +118,7 @@ vertoControllers.controller('MainController', ['$scope', '$rootScope',
         verto.disconnect(disconnectCallback);
 
         verto.hangup();
-      }
+      };
 
       if (verto.data.call) {
         prompt({
@@ -223,10 +222,10 @@ vertoControllers.controller('MainController', ['$scope', '$rootScope',
 
     $scope.clearCallHistory = function() {
       storage.data.call_history = [];
-    }
+    };
 
     $scope.toggleChat = function() {
-      if ($scope.chatStatus && $rootScope.activePane == 'chat') {
+      if ($scope.chatStatus && $rootScope.activePane === 'chat') {
         $rootScope.chat_counter = 0;
       }
       angular.element('#wrapper').toggleClass('toggled');
@@ -244,7 +243,7 @@ vertoControllers.controller('MainController', ['$scope', '$rootScope',
     };
 
     $scope.goFullscreen = function() {
-      if (storage.data.userStatus != 'connected') {
+      if (storage.data.userStatus !== 'connected') {
         return;
       }
       $rootScope.fullscreenEnabled = !Fullscreen.isEnabled();
@@ -253,7 +252,7 @@ vertoControllers.controller('MainController', ['$scope', '$rootScope',
       } else {
         Fullscreen.enable(document.getElementsByTagName('body')[0]);
       }
-    }
+    };
 
     $rootScope.$on('call.video', function(event) {
       storage.data.videoCall = true;
diff --git a/html5/verto/verto_communicator/js/verto-service.js b/html5/verto/verto_communicator/js/verto-service.js
index 87b93b73f3..01e4e61049 100644
--- a/html5/verto/verto_communicator/js/verto-service.js
+++ b/html5/verto/verto_communicator/js/verto-service.js
@@ -117,8 +117,8 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
       textTo: $cookieStore.get('verto_demo_textto') || "1000",
       login: $cookieStore.get('verto_demo_login') || "1008",
       password: $cookieStore.get('verto_demo_passwd') || "1234",
-      hostname: $cookieStore.get('verto_demo_hostname') || window.location.hostname,
-      wsURL: $cookieStore.get('verto_demo_wsurl') || ("wss://" + window.location.hostname + ":8082"),
+      hostname: $cookieStore.get('verto_demo_hostname') || '@@ip',
+      wsURL: $cookieStore.get('verto_demo_wsurl') || ("wss://" + '@@ip' + ":8082"),
       useVideo: $cookieStore.get('verto_demo_vid_checked') || true,
       useCamera: $cookieStore.get('verto_demo_camera_checked') || true,
       useStereo: $cookieStore.get('verto_demo_stereo_checked') || true,
diff --git a/html5/verto/verto_communicator/package.json b/html5/verto/verto_communicator/package.json
index 9488260240..61e924189e 100644
--- a/html5/verto/verto_communicator/package.json
+++ b/html5/verto/verto_communicator/package.json
@@ -1,12 +1,36 @@
 {
   "name": "verto_communicator",
   "version": "0.0.1",
+  "description": "HTML5 Based Communications application for use with FreeSWITCH and mod_verto",
   "devDependencies": {
+    "grunt-browser-sync": "^2.1.2",
+    "browser-sync": "^2.8.2",
+    "autoprefixer-core": "^5.2.1",
     "grunt": "^0.4.5",
-    "grunt-contrib-connect": "^0.9.0",
-    "grunt-contrib-jshint": "~0.10.0",
-    "grunt-contrib-watch": "^0.6.1",
+    "grunt-concurrent": "^1.0.0",
+    "grunt-contrib-clean": "^0.6.0",
+    "grunt-contrib-concat": "^0.5.0",
+    "grunt-contrib-copy": "^0.7.0",
+    "grunt-contrib-cssmin": "^0.12.0",
+    "grunt-contrib-htmlmin": "^0.4.0",
+    "grunt-contrib-imagemin": "^0.9.2",
+    "grunt-contrib-jshint": "^0.11.0",
+    "grunt-postcss": "^0.5.3",
+    "grunt-contrib-uglify": "^0.7.0",
+    "grunt-contrib-watch": "latest",
+    "grunt-filerev": "^2.1.2",
+    "grunt-include-replace": "^3.1.0",
+    "grunt-newer": "^1.1.0",
+    "grunt-ng-annotate": "^0.9.2",
+    "grunt-svgmin": "^2.0.0",
+    "grunt-usemin": "^3.0.0",
     "grunt-wiredep": "^2.0.0",
-    "load-grunt-tasks": "^3.2.0"
+    "jit-grunt": "^0.9.1",
+    "jshint-stylish": "^1.0.0",
+    "time-grunt": "^1.0.0"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://freeswitch.org/stash/scm/fs/freeswitch.git"
   }
 }