<commit_before>/* -*- js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80; */
"use strict";

require("sockjs");
let Sock = window.SockJS,
    Genfun = require("genfun"),
    {addMethod} = Genfun,
    {clone, init} = require("./proto"),
    {partial, forEach, contains, without} = require("lodash");

let SocketConn = clone(),
    onOpen = new Genfun(),
    onMessage = new Genfun(),
    onClose = new Genfun();

addMethod(init, [SocketConn], function(conn, url) {
  conn.url = url;
  conn.observers = {};
  conn.socket = new Sock(url);
  conn.socket.onopen = partial(notifyObservers, conn, onOpen);
  conn.socket.onmessage = partial(notifyObservers, conn, onMessage);
  conn.socket.onclose = partial(notifyObservers, conn, onClose);
});

addMethod(onOpen, [], function() {});
addMethod(onMessage, [], function() {});
addMethod(onClose, [], function() {});

function notifyObservers(conn, handler, msg) {
  if (msg.type === "message") {
    let data = JSON.parse(msg.data),
        observers = conn.observers[data.namespace] ||
          (console.warn("Unknown namespace: ", data.namespace),
           []);
    forEach(observers, function(obs) {
      return handler.call(conn, obs, data.data);
    });
  } else {
    forEach(conn.observers, function(arr) {
      forEach(arr, function(obs) {
        return handler.call(conn, obs);
      });
    });
  }
}

function listen(conn, observer, namespace) {
  if (!conn.observers[namespace]) { conn.observers[namespace] = []; }
  if (!contains(conn.observers[namespace], observer)) {
    conn.observers[namespace].push(observer);
  }
}

function unlisten(conn, observer) {
  conn.observers = without(conn.observers, observer);
}

function send(conn, namespace, data) {
  conn.socket.send(JSON.stringify({namespace: namespace, data: data}));
}

module.exports = {
  SocketConn: SocketConn,
  onOpen: onOpen,
  onMessage: onMessage,
  onClose: onClose,
  listen: listen,
  unlisten: unlisten,
  send: send
};
<commit_msg>Set connection state in sockConn for observability<commit_after>/* -*- js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80; */
"use strict";

require("sockjs");
let Sock = window.SockJS,
    Genfun = require("genfun"),
    {addMethod} = Genfun,
    {clone, init} = require("./proto"),
    {partial, forEach, contains, without} = require("lodash");

let SocketConn = clone(),
    onOpen = new Genfun(),
    onMessage = new Genfun(),
    onClose = new Genfun();

addMethod(init, [SocketConn], function(conn, url) {
  conn.url = url;
  conn.state = can.compute("close");
  conn.observers = {};
  conn.socket = new Sock(url);
  conn.socket.onopen = partial(notifyObservers, conn, onOpen);
  conn.socket.onmessage = partial(notifyObservers, conn, onMessage);
  conn.socket.onclose = partial(notifyObservers, conn, onClose);
});

addMethod(onOpen, [], function() {});
addMethod(onMessage, [], function() {});
addMethod(onClose, [], function() {});

function notifyObservers(conn, handler, msg) {
  if (msg.type === "message") {
    let data = JSON.parse(msg.data),
        observers = conn.observers[data.namespace] ||
          (console.warn("Unknown namespace: ", data.namespace),
           []);
    forEach(observers, function(obs) {
      return handler.call(conn, obs, data.data);
    });
  } else {
    conn.state(msg.type);
    forEach(conn.observers, function(arr) {
      forEach(arr, function(obs) {
        return handler.call(conn, obs);
      });
    });
  }
}

function listen(conn, observer, namespace) {
  if (!conn.observers[namespace]) { conn.observers[namespace] = []; }
  if (!contains(conn.observers[namespace], observer)) {
    conn.observers[namespace].push(observer);
  }
}

function unlisten(conn, observer) {
  conn.observers = without(conn.observers, observer);
}

function send(conn, namespace, data) {
  conn.socket.send(JSON.stringify({namespace: namespace, data: data}));
}

module.exports = {
  SocketConn: SocketConn,
  onOpen: onOpen,
  onMessage: onMessage,
  onClose: onClose,
  listen: listen,
  unlisten: unlisten,
  send: send
};
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the MIT license
 * If a copy of the MIT license was not distributed with this file, you can
 * obtain one at http://www.mozillapopcorn.org/butter-license.txt */

define([], function(){

  var DEFAULT_DIRS = {
        "popcorn-js": "../external/popcorn-js",
        "css": "css"
      },
      VAR_REGEX = /\{([\w\-\._]+)\}/,
      CSS_POLL_INTERVAL = 10;

  var DEFAULT_CHECK_FUNCTION = function(){
    var index = 0;
    return function(){
      return index++ > 0;
    };
  };

  return function( config ){

    var _configDirs = config.dirs;

    function fixUrl( url ){
      var match,
          replacement;

      while ( VAR_REGEX.test( url ) ) {
        match = VAR_REGEX.exec( url );
        replacement = _configDirs[ match[ 1 ] ] || DEFAULT_DIRS[ match[ 1 ] ] || "";
        console.log( match, replacement );
        url = url.replace( match[0], replacement );
      }

      return url.replace( "//", "/" );
    }

    var _loaders = {
      js: function( url, exclude, callback, checkFn ){
        checkFn = checkFn || DEFAULT_CHECK_FUNCTION();

        url = fixUrl( url );

        if( !checkFn() ){
          var scriptElement = document.createElement( "script" );
          scriptElement.src = url;
          scriptElement.type = "text/javascript";
          document.head.appendChild( scriptElement );
          scriptElement.onload = scriptElement.onreadystatechange = callback;
        }
        else{
          callback();
        }
      },
      css: function( url, exclude, callback, checkFn ){
        var scriptElement;
        checkFn = checkFn || function(){
          if( !scriptElement ){
            return false;
          }
          for( var i = 0; i < document.styleSheets.length; ++i ){
            if( document.styleSheets[ i ].href === scriptElement.href ){
              return true;
            }
          }
          return false;
        };

        url = fixUrl( url );
        if( !checkFn() ){
          scriptElement = document.createElement( "link" );
          scriptElement.rel = "stylesheet";
          scriptElement.href = url;
          document.head.appendChild( scriptElement );
        }

        var interval = setInterval(function(){
          if( checkFn() ){
            clearInterval( interval );
            callback();
          }
        }, CSS_POLL_INTERVAL );

      }
    };

    function generateLoaderCallback( items, callback ){
      var loaded = 0;
      return function(){
        ++loaded;
        if( loaded === items.length ){
          if( callback ){
            callback();
          }
        }
      };
    }

    function generateNextFunction( items, callback ){
      var index = 0;
      function next(){
        if( index === items.length ){
          callback();
        }
        else{
          Loader.load( items[ index++ ], next );
        }
      }
      return next;
    }

    var Loader = {

      load: function( items, callback, ordered ){
        if( items instanceof Array && items.length > 0 ){
          var onLoad = generateLoaderCallback( items, callback );
          if( !ordered ){
            for( var i = 0; i < items.length; ++i ){
              Loader.load( items[ i ], onLoad );
            }
          }
          else {
            var next = generateNextFunction( items, callback );
            next();
          }

        }
        else {
          var item = items;

          if( _loaders[ item.type ] ){
            if( item.url ){
              _loaders[ item.type ]( item.url, item.exclude, callback, item.check );
            }
            else{
              throw new Error( "Attempted to load resource without url." );
            }
          }
          else {
            throw new Error( "Loader type " + item.type + " not found! Attempted: " + item.url );
          }

        }
      }
    };

    return Loader;

  };

});<commit_msg>remove console.log() [#718]<commit_after>/* This Source Code Form is subject to the terms of the MIT license
 * If a copy of the MIT license was not distributed with this file, you can
 * obtain one at http://www.mozillapopcorn.org/butter-license.txt */

define([], function(){

  var DEFAULT_DIRS = {
        "popcorn-js": "../external/popcorn-js",
        "css": "css"
      },
      VAR_REGEX = /\{([\w\-\._]+)\}/,
      CSS_POLL_INTERVAL = 10;

  var DEFAULT_CHECK_FUNCTION = function(){
    var index = 0;
    return function(){
      return index++ > 0;
    };
  };

  return function( config ){

    var _configDirs = config.dirs;

    function fixUrl( url ){
      var match,
          replacement;

      while ( VAR_REGEX.test( url ) ) {
        match = VAR_REGEX.exec( url );
        replacement = _configDirs[ match[ 1 ] ] || DEFAULT_DIRS[ match[ 1 ] ] || "";
        url = url.replace( match[0], replacement );
      }

      return url.replace( "//", "/" );
    }

    var _loaders = {
      js: function( url, exclude, callback, checkFn ){
        checkFn = checkFn || DEFAULT_CHECK_FUNCTION();

        url = fixUrl( url );

        if( !checkFn() ){
          var scriptElement = document.createElement( "script" );
          scriptElement.src = url;
          scriptElement.type = "text/javascript";
          document.head.appendChild( scriptElement );
          scriptElement.onload = scriptElement.onreadystatechange = callback;
        }
        else{
          callback();
        }
      },
      css: function( url, exclude, callback, checkFn ){
        var scriptElement;
        checkFn = checkFn || function(){
          if( !scriptElement ){
            return false;
          }
          for( var i = 0; i < document.styleSheets.length; ++i ){
            if( document.styleSheets[ i ].href === scriptElement.href ){
              return true;
            }
          }
          return false;
        };

        url = fixUrl( url );
        if( !checkFn() ){
          scriptElement = document.createElement( "link" );
          scriptElement.rel = "stylesheet";
          scriptElement.href = url;
          document.head.appendChild( scriptElement );
        }

        var interval = setInterval(function(){
          if( checkFn() ){
            clearInterval( interval );
            callback();
          }
        }, CSS_POLL_INTERVAL );

      }
    };

    function generateLoaderCallback( items, callback ){
      var loaded = 0;
      return function(){
        ++loaded;
        if( loaded === items.length ){
          if( callback ){
            callback();
          }
        }
      };
    }

    function generateNextFunction( items, callback ){
      var index = 0;
      function next(){
        if( index === items.length ){
          callback();
        }
        else{
          Loader.load( items[ index++ ], next );
        }
      }
      return next;
    }

    var Loader = {

      load: function( items, callback, ordered ){
        if( items instanceof Array && items.length > 0 ){
          var onLoad = generateLoaderCallback( items, callback );
          if( !ordered ){
            for( var i = 0; i < items.length; ++i ){
              Loader.load( items[ i ], onLoad );
            }
          }
          else {
            var next = generateNextFunction( items, callback );
            next();
          }

        }
        else {
          var item = items;

          if( _loaders[ item.type ] ){
            if( item.url ){
              _loaders[ item.type ]( item.url, item.exclude, callback, item.check );
            }
            else{
              throw new Error( "Attempted to load resource without url." );
            }
          }
          else {
            throw new Error( "Loader type " + item.type + " not found! Attempted: " + item.url );
          }

        }
      }
    };

    return Loader;

  };

});<|endoftext|>


<commit_before>/**
 * seneschal.module.js
 * Created by anonymous on 08/12/15 17:00.
 */

(function() {
    'use strict';

    angular
        .module('seneschal', [

            /* Shared */
            'appFoundation',
            'widgets',

            /* components */
            'dashboard'

        ]);

})();

<commit_msg>Deleted seneschal.module<commit_after>/**
 * seneschal.module.js
 * Created by anonymous on 08/12/15 17:00.
 */

(function() {
    'use strict';

    angular
        .module('seneschal', [

            /* Shared */
            'appFoundation',
            'widgets'

        ]);

})();

<|endoftext|>


<commit_before>/* =========================================================================
 * Dependencies
 * ========================================================================= */
var appConfig = require('src/config/appConfig');

var packageJson = require('./package.json');

var gulp = require('gulp');
var inject = require('gulp-inject'); // jshint ignore:line
var jshint = require('gulp-jshint');
var less = require('gulp-less');
var replace = require('gulp-replace');
var sh = require('shelljs');
var wrap = require('gulp-wrap');
var electronConnect = require('electron-connect');
var runSequence = require('run-sequence');
var mocha = require('gulp-mocha');

require('gulp-task-list')(gulp);

/* =========================================================================
 * Constants
 * ========================================================================= */
const APP_NAME = packageJson.name;

const BUILD_DIR = 'build';
const RELEASE_DIR = 'release';

const VENDOR_JS = [
  BUILD_DIR + '/ui/vendor/bootstrap/dist/js/bootstrap.js',
  BUILD_DIR + '/ui/vendor/console-polyfill/index.js',
  BUILD_DIR + '/ui/vendor/angular/angular.js',
  BUILD_DIR + '/ui/vendor/angular-resource/angular-resource.js',
  BUILD_DIR + '/ui/vendor/angular-ui-router/release/angular-ui-router.js',
  BUILD_DIR + '/ui/vendor/angular-bootstrap/ui-bootstrap-tpls.js',
  BUILD_DIR + '/ui/vendor/underscore/underscore.js',
  BUILD_DIR + '/ui/vendor/angular-animate/angular-animate.js',
  BUILD_DIR + '/ui/vendor/angular-sanitize/angular-sanitize.js',
  BUILD_DIR + '/ui/vendor/angular-scroll/angular-scroll.js',
  BUILD_DIR + '/ui/vendor/jquery.splitter/js/jquery.splitter-0.15.0.js',
  // BUILD_DIR + '/ui/vendor/toastr/toastr.js',
  BUILD_DIR + '/ui/vendor/moment/moment.js',
  BUILD_DIR + '/ui/vendor/angular/angular.js',
  BUILD_DIR + '/ui/vendor/ng-prettyjson/src/ng-prettyjson.js',
  BUILD_DIR + '/ui/vendor/ng-prettyjson/src/ng-prettyjson-tmpl.js',
  BUILD_DIR + '/ui/vendor/Keypress/keypress.js',
  BUILD_DIR + '/ui/vendor/codemirror/lib/codemirror.js',
  BUILD_DIR + '/ui/vendor/codemirror/mode/javascript/javascript.js',
  BUILD_DIR + '/ui/vendor/codemirror/addon/hint/show-hint.js',
  BUILD_DIR + '/ui/vendor/codemirror/addon/hint/javascript-hint.js'
];

const LESSOPTIONS = {
  compress: false
};

const VENDOR_CSS = [
  BUILD_DIR + '/ui/vendor/jquery.splitter/css/jquery.splitter.css',
  BUILD_DIR + '/ui/vendor/toastr/toastr.css',
  BUILD_DIR + '/ui/vendor/codemirror/lib/codemirror.css',
  BUILD_DIR + '/ui/vendor/ng-prettyjson/src/ng-prettyjson.css',
  BUILD_DIR + '/ui/vendor/codemirror/lib/codemirror.css',
  BUILD_DIR + '/ui/vendor/codemirror/addon/hint/show-hint.css'
];

const MOCHA_SETTINGS = {
  reporter: 'spec',
  growl: true,
  useColors: true,
  useInlineDiffs: true
};

/* =========================================================================
 * Tasks
 * ========================================================================= */
/**
 * List gulp tasks
 */
gulp.task('?', function(next) {
  sh.exec('gulp task-list');
  next();
});

gulp.task('clean', function(next) {
  sh.rm('-rf', BUILD_DIR);
  sh.rm('-rf', RELEASE_DIR);
  next();
});

gulp.task('copy', ['clean', 'copy-vendor'], function() {
  return _init(gulp.src(['package.json', 'src/**/*.*']))
    .pipe(gulp.dest(BUILD_DIR));
});

gulp.task('copy-vendor', ['clean'], function() {
  return _init(gulp.src('src/broswer/vendor/**/**/*.js'))
    .pipe(wrap('(function(){<%= contents %>\n})();'))
    .pipe(gulp.dest(BUILD_DIR + '/ui/vendor'));
});

gulp.task('replace', ['copy'], function() {
  return _replace(gulp.src(['build/**/**/*', '!build/ui/vendor/**/*.js']))
    .pipe(gulp.dest(BUILD_DIR));
});

gulp.task('css', function() {
  var target = gulp.src(BUILD_DIR + '/ui/index.html');

  var sources = gulp.src(BUILD_DIR + '/ui/less/main.less')
    .pipe(less(LESSOPTIONS))
    .pipe(gulp.dest(BUILD_DIR + '/ui/css'));

  return target.pipe(inject(sources, {
      starttag: '<!-- injectSrcCss:css -->',
      endtag: '<!-- endinjectSrcCss -->',
      transform: function(filepath) {
        var path = filepath.replace('/build/ui/', '');
        return '<link rel="stylesheet" href="' + path + '"/>';
      }
    }))
    .pipe(gulp.dest(BUILD_DIR + '/ui'));
});

gulp.task('css-vendor', function() {
  var target = gulp.src(BUILD_DIR + '/ui/index.html');

  var sources = gulp.src(VENDOR_CSS)
    .pipe(less(LESSOPTIONS))
    .pipe(gulp.dest(BUILD_DIR + '/css'));

  return target.pipe(inject(sources, {
      starttag: '<!-- injectVendorCss:css -->',
      endtag: '<!-- endinjectVendorCss -->',
      transform: function(filepath) {
        var path = filepath.replace('/build', '');
        return '<link rel="stylesheet" href="..' + path + '"/>';
      }
    }))
    .pipe(gulp.dest(BUILD_DIR + '/ui'));
});

gulp.task('js', function() {
  var target = gulp.src(BUILD_DIR + '/ui/index.html');

  var sources = gulp.src([BUILD_DIR + '/ui/**/*.js', '!' + BUILD_DIR + '/ui/vendor/**/*.js']);

  return target.pipe(inject(sources, {
      starttag: '<!-- injectSrcJs:js -->',
      endtag: '<!-- endinjectSrcJs -->',
      transform: function(filepath) {
        var path = filepath.replace('/build/ui/', '');
        return '<script src="' + path + '"></script>';
      }
    }))
    .pipe(gulp.dest(BUILD_DIR + '/ui'));
});

gulp.task('js-vendor', function() {
  var target = gulp.src(BUILD_DIR + '/ui/index.html');

  var sources = gulp.src(VENDOR_JS);

  return target.pipe(inject(sources, {
      starttag: '<!-- injectVendorJs:js -->',
      endtag: '<!-- endinjectVendorJs -->',
      transform: function(filepath) {
        var path = filepath.replace('/build/ui/', '');
        return '<script src="' + path + '"></script>';
      }
    }))
    .pipe(gulp.dest(BUILD_DIR + '/ui'));
});

gulp.task('jshint', ['replace'], function() {
  return _init(gulp.src(['src/**/*.js', '!src/ui/vendor/**/*.js']))
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

gulp.task('release', ['build'], function(done) {
  sh.exec('./node_modules/.bin/electron-packager ' + BUILD_DIR + ' ' + APP_NAME + ' --out=' + RELEASE_DIR + ' --platform=darwin  --arch=x64 --version=0.30.2', done);
});

gulp.task('build', ['clean', 'copy', 'replace'], function(next) {
  runSequence('css', 'css-vendor', 'js', 'js-vendor', next);
});

gulp.task('serve', ['build'], function() {
  var electron = electronConnect.server.create({
    path: './' + BUILD_DIR
  });

  // Start browser process
  electron.start();
});

gulp.task('default', ['serve']);

gulp.task('test', function(next) {
  runSequence('jshint', 'test-int', 'test-unit', next);
});

gulp.task('test-int', function() {
  return gulp.src('tests/integration/**/**/**-test.js')
    .pipe(mocha(MOCHA_SETTINGS));
});

gulp.task('test-unit', function() {
  return gulp.src('tests/unit/**/**/**-test.js')
    .pipe(mocha(MOCHA_SETTINGS));
});

/* =========================================================================
 * Helper Functions
 * ========================================================================= */
function _init(stream) {
  stream.setMaxListeners(0);
  return stream;
}

function _replace(stream) {
  _init(stream);

  for (var key in appConfig) {
    stream.pipe(replace('@@' + key, appConfig[key], {
      skipBinary: true
    }));
  }

  return stream;
}
<commit_msg>better copy tasks<commit_after>/* =========================================================================
 * Dependencies
 * ========================================================================= */
var appConfig = require('src/config/appConfig');

var packageJson = require('./package.json');

var gulp = require('gulp');
var inject = require('gulp-inject'); // jshint ignore:line
var jshint = require('gulp-jshint');
var less = require('gulp-less');
var replace = require('gulp-replace');
var sh = require('shelljs');
var wrap = require('gulp-wrap');
var electronConnect = require('electron-connect');
var runSequence = require('run-sequence');
var mocha = require('gulp-mocha');

require('gulp-task-list')(gulp);

/* =========================================================================
 * Constants
 * ========================================================================= */
const APP_NAME = packageJson.name;

const BUILD_DIR = 'build';
const RELEASE_DIR = 'release';

const VENDOR_JS = [
  BUILD_DIR + '/ui/vendor/bootstrap/dist/js/bootstrap.js',
  BUILD_DIR + '/ui/vendor/console-polyfill/index.js',
  BUILD_DIR + '/ui/vendor/angular/angular.js',
  BUILD_DIR + '/ui/vendor/angular-resource/angular-resource.js',
  BUILD_DIR + '/ui/vendor/angular-ui-router/release/angular-ui-router.js',
  BUILD_DIR + '/ui/vendor/angular-bootstrap/ui-bootstrap-tpls.js',
  BUILD_DIR + '/ui/vendor/underscore/underscore.js',
  BUILD_DIR + '/ui/vendor/angular-animate/angular-animate.js',
  BUILD_DIR + '/ui/vendor/angular-sanitize/angular-sanitize.js',
  BUILD_DIR + '/ui/vendor/angular-scroll/angular-scroll.js',
  BUILD_DIR + '/ui/vendor/jquery.splitter/js/jquery.splitter-0.15.0.js',
  // BUILD_DIR + '/ui/vendor/toastr/toastr.js',
  BUILD_DIR + '/ui/vendor/moment/moment.js',
  BUILD_DIR + '/ui/vendor/angular/angular.js',
  BUILD_DIR + '/ui/vendor/ng-prettyjson/src/ng-prettyjson.js',
  BUILD_DIR + '/ui/vendor/ng-prettyjson/src/ng-prettyjson-tmpl.js',
  BUILD_DIR + '/ui/vendor/Keypress/keypress.js',
  BUILD_DIR + '/ui/vendor/codemirror/lib/codemirror.js',
  BUILD_DIR + '/ui/vendor/codemirror/mode/javascript/javascript.js',
  BUILD_DIR + '/ui/vendor/codemirror/addon/hint/show-hint.js',
  BUILD_DIR + '/ui/vendor/codemirror/addon/hint/javascript-hint.js'
];

const LESSOPTIONS = {
  compress: false
};

const VENDOR_CSS = [
  BUILD_DIR + '/ui/vendor/jquery.splitter/css/jquery.splitter.css',
  BUILD_DIR + '/ui/vendor/toastr/toastr.css',
  BUILD_DIR + '/ui/vendor/codemirror/lib/codemirror.css',
  BUILD_DIR + '/ui/vendor/ng-prettyjson/src/ng-prettyjson.css',
  BUILD_DIR + '/ui/vendor/codemirror/lib/codemirror.css',
  BUILD_DIR + '/ui/vendor/codemirror/addon/hint/show-hint.css'
];

const MOCHA_SETTINGS = {
  reporter: 'spec',
  growl: true,
  useColors: true,
  useInlineDiffs: true
};

/* =========================================================================
 * Tasks
 * ========================================================================= */
/**
 * List gulp tasks
 */
gulp.task('?', function(next) {
  sh.exec('gulp task-list');
  next();
});

gulp.task('clean', function(next) {
  sh.rm('-rf', BUILD_DIR);
  sh.rm('-rf', RELEASE_DIR);
  next();
});

gulp.task('copy', ['clean'], function(next) {
  runSequence('copy-src', 'copy-vendor', next);
});

gulp.task('copy-src', function() {
  return _init(gulp.src(['package.json', 'src/**/*.*', '!src/ui/vendor/**/*.js']))
    .pipe(gulp.dest(BUILD_DIR));
});

gulp.task('copy-modules', function() {
  return _init(gulp.src(['node_modules/**/*.*']))
    .pipe(gulp.dest(BUILD_DIR + '/node_modules'));
});

gulp.task('copy-vendor', function() {
  return _init(gulp.src('src/ui/vendor/**/**/*.js'))
    .pipe(wrap('(function(){<%= contents %>\n})();'))
    .pipe(gulp.dest(BUILD_DIR + '/ui/vendor'));
});

gulp.task('replace', ['copy'], function() {
  return _replace(gulp.src(['build/**/**/*', '!build/ui/vendor/**/*.*', '!build/node_modules/**/*.*']))
    .pipe(gulp.dest(BUILD_DIR));
});

gulp.task('css', function() {
  var target = gulp.src(BUILD_DIR + '/ui/index.html');

  var sources = gulp.src(BUILD_DIR + '/ui/less/main.less')
    .pipe(less(LESSOPTIONS))
    .pipe(gulp.dest(BUILD_DIR + '/ui/css'));

  return target.pipe(inject(sources, {
      starttag: '<!-- injectSrcCss:css -->',
      endtag: '<!-- endinjectSrcCss -->',
      transform: function(filepath) {
        var path = filepath.replace('/build/ui/', '');
        return '<link rel="stylesheet" href="' + path + '"/>';
      }
    }))
    .pipe(gulp.dest(BUILD_DIR + '/ui'));
});

gulp.task('css-vendor', function() {
  var target = gulp.src(BUILD_DIR + '/ui/index.html');

  var sources = gulp.src(VENDOR_CSS)
    .pipe(less(LESSOPTIONS))
    .pipe(gulp.dest(BUILD_DIR + '/css'));

  return target.pipe(inject(sources, {
      starttag: '<!-- injectVendorCss:css -->',
      endtag: '<!-- endinjectVendorCss -->',
      transform: function(filepath) {
        var path = filepath.replace('/build', '');
        return '<link rel="stylesheet" href="..' + path + '"/>';
      }
    }))
    .pipe(gulp.dest(BUILD_DIR + '/ui'));
});

gulp.task('js', function() {
  var target = gulp.src(BUILD_DIR + '/ui/index.html');

  var sources = gulp.src([BUILD_DIR + '/ui/**/*.js', '!' + BUILD_DIR + '/ui/vendor/**/*.js']);

  return target.pipe(inject(sources, {
      starttag: '<!-- injectSrcJs:js -->',
      endtag: '<!-- endinjectSrcJs -->',
      transform: function(filepath) {
        var path = filepath.replace('/build/ui/', '');
        return '<script src="' + path + '"></script>';
      }
    }))
    .pipe(gulp.dest(BUILD_DIR + '/ui'));
});

gulp.task('js-vendor', function() {
  var target = gulp.src(BUILD_DIR + '/ui/index.html');

  var sources = gulp.src(VENDOR_JS);

  return target.pipe(inject(sources, {
      starttag: '<!-- injectVendorJs:js -->',
      endtag: '<!-- endinjectVendorJs -->',
      transform: function(filepath) {
        var path = filepath.replace('/build/ui/', '');
        return '<script src="' + path + '"></script>';
      }
    }))
    .pipe(gulp.dest(BUILD_DIR + '/ui'));
});

gulp.task('jshint', ['replace'], function() {
  return _init(gulp.src(['src/**/*.js', '!src/ui/vendor/**/*.js']))
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

gulp.task('release', ['build'], function(done) {
  sh.exec('./node_modules/.bin/electron-packager ' + BUILD_DIR + ' ' + APP_NAME + ' --out=' + RELEASE_DIR + ' --platform=darwin  --arch=x64 --version=0.30.2', done);
});

gulp.task('build', ['clean', 'copy', 'replace'], function(next) {
  runSequence('css', 'css-vendor', 'js', 'js-vendor', next);
});

gulp.task('serve', ['build'], function() {
  var electron = electronConnect.server.create({
    path: './' + BUILD_DIR
  });

  // Start browser process
  electron.start();
});

gulp.task('default', ['serve']);

gulp.task('test', function(next) {
  runSequence('jshint', 'test-int', 'test-unit', next);
});

gulp.task('test-int', function() {
  return gulp.src('tests/integration/**/**/**-test.js')
    .pipe(mocha(MOCHA_SETTINGS));
});

gulp.task('test-unit', function() {
  return gulp.src('tests/unit/**/**/**-test.js')
    .pipe(mocha(MOCHA_SETTINGS));
});

/* =========================================================================
 * Helper Functions
 * ========================================================================= */
function _init(stream) {
  stream.setMaxListeners(0);
  return stream;
}

function _replace(stream) {
  _init(stream);

  for (var key in appConfig) {
    stream.pipe(replace('@@' + key, appConfig[key], {
      skipBinary: true
    }));
  }

  return stream;
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Day from './day';
import moment from 'moment';

import { API_EVENTS_URL } from '../../common/constants';

function getActiveEvent (postDays, futureEvents, active) {
  if (active < 0 && postDays.length > 0) {
    return postDays[0].props.events[0].index;
  } else if (active < 0 && futureEvents[0]) {
    return futureEvents[0].index;
  }

  return active;
}

class Calendar extends Component {
  constructor(props) {
    super(props);

    this.state = {
      active: -1,
      preDaysSectionActive: false
    };
  }

  eventClickHandler(id) {
    this.setState(Object.assign({}, this.state, { active: id }));
    setTimeout(() => {
      window.location = `#event-${id}`;
    }, 0);
  }

  preDaysClickHandler() {
    this.setState(Object.assign({}, this.state, { preDaysSectionActive: !this.state.preDaysSectionActive }));
  }

  partitionEvents(pastEvents, futureEvents, active) {
    let preDay, postDay;

    if (pastEvents.length) {
      preDay = <Day events={pastEvents} active={active} eventClickHandler={this.eventClickHandler}/>;
    }
    if (futureEvents.length) {
      postDay = <Day events={futureEvents} active={active} eventClickHandler={this.eventClickHandler}/>;
    }

    return { preDay, postDay };
  }

  buildEvents(events) {
    let id = 0;
    let previousEventDate;

    let pastEvents = [];
    let futureEvents = [];

    let preDays = [];
    let postDays = [];
    let preDaysSection = '';

    const NOW = moment();

    events.forEach(function (event, index) {
      event.index = index;
      const currentEventDate = moment(event.end_time);

      if (currentEventDate.isAfter(previousEventDate, 'day')) {
        const active = getActiveEvent(postDays, futureEvents, this.state.active);
        const { preDay, postDay } = this.partitionEvents(pastEvents, futureEvents, active);

        if (preDay) {
          preDays.push(preDay);
        }
        if (postDay) {
          postDays.push(postDay);
        }

        pastEvents = [];
        futureEvents = [];
      }
      if (currentEventDate.isAfter(NOW)) {
        futureEvents.push(event);
      }
      else {
        pastEvents.push(event);
      }

      previousEventDate = currentEventDate;
      id++;
    }, this);

    const active = getActiveEvent(postDays, futureEvents, this.state.active);
    const { preDay, postDay } = this.partitionEvents(pastEvents, futureEvents, active);
    if (preDay) {
      preDays.push(preDay);
    }
    if (postDay) {
      postDays.push(postDay);
    }

    let toggleCalendarSection = (
      <button className="cal-button--preDays" onClick={this.preDaysClickHandler}>
        {( this.state.preDaysSectionActive ? 'Skjul' : 'Vis' ) + ' tidligere arrangementer' }
      </button>
    );

    if (preDays.length > 0 && this.state.preDaysSectionActive) {
      preDaysSection = (

          { preDays }

      );
    }
    else if (preDays.length <= 0) {
      toggleCalendarSection = '';
    }
    else {
      preDaysSection = '';
    }

    return {
      postDaysSection: postDays,
      toggleCalendarSection,
      preDaysSection
    };
  }

  render() {
    const { events, error } = this.props;

    if (events.length === 0 && error === null) {
      return
Laster inn kalender
;
    }

    if (error !== null) {
      return (

          En uventet feil har oppstått ved henting av program. Vennligst prøv igjen senere.

      );
    }

    let { postDaysSection, toggleCalendarSection, preDaysSection } = this.buildEvents(events);

    return (

        { preDaysSection }
        { toggleCalendarSection }
        { postDaysSection }

    );
  }
}

export default Calendar;
<commit_msg>Extract toggleCalendarSection from buildEvents function<commit_after>import React, { Component } from 'react';
import Day from './day';
import moment from 'moment';

import { API_EVENTS_URL } from '../../common/constants';

function getActiveEvent (postDays, futureEvents, active) {
  if (active < 0 && postDays.length > 0) {
    return postDays[0].props.events[0].index;
  } else if (active < 0 && futureEvents[0]) {
    return futureEvents[0].index;
  }

  return active;
}

class Calendar extends Component {
  constructor(props) {
    super(props);

    this.state = {
      active: -1,
      preDaysSectionActive: false
    };
  }

  eventClickHandler(id) {
    this.setState(Object.assign({}, this.state, { active: id }));
    setTimeout(() => {
      window.location = `#event-${id}`;
    }, 0);
  }

  preDaysClickHandler() {
    this.setState(Object.assign({}, this.state, { preDaysSectionActive: !this.state.preDaysSectionActive }));
  }

  partitionEvents(pastEvents, futureEvents, active) {
    let preDay, postDay;

    if (pastEvents.length) {
      preDay = <Day events={pastEvents} active={active} eventClickHandler={this.eventClickHandler}/>;
    }
    if (futureEvents.length) {
      postDay = <Day events={futureEvents} active={active} eventClickHandler={this.eventClickHandler}/>;
    }

    return { preDay, postDay };
  }

  buildEvents(events) {
    let id = 0;
    let previousEventDate;

    let pastEvents = [];
    let futureEvents = [];

    let preDays = [];
    let postDays = [];
    let preDaysSection = '';

    const NOW = moment();

    events.forEach((event, index) => {
      event.index = index;
      const currentEventDate = moment(event.end_time);

      if (currentEventDate.isAfter(previousEventDate, 'day')) {
        const active = getActiveEvent(postDays, futureEvents, this.state.active);
        const { preDay, postDay } = this.partitionEvents(pastEvents, futureEvents, active);

        if (preDay) {
          preDays.push(preDay);
        }
        if (postDay) {
          postDays.push(postDay);
        }

        pastEvents = [];
        futureEvents = [];
      }
      if (currentEventDate.isAfter(NOW)) {
        futureEvents.push(event);
      }
      else {
        pastEvents.push(event);
      }

      previousEventDate = currentEventDate;
      id++;
    });

    const active = getActiveEvent(postDays, futureEvents, this.state.active);
    const { preDay, postDay } = this.partitionEvents(pastEvents, futureEvents, active);
    if (preDay) {
      preDays.push(preDay);
    }
    if (postDay) {
      postDays.push(postDay);
    }

    if (preDays.length > 0 && this.state.preDaysSectionActive) {
      preDaysSection = (

          { preDays }

      );
    }
    else {
      preDaysSection = '';
    }

    return {
      postDaysSection: postDays,
      preDaysSection,
      preDays,
    };
  }

  render() {
    const { events, error } = this.props;

    if (events.length === 0 && error === null) {
      return
Laster inn kalender
;
    }

    if (error !== null) {
      return (

          En uventet feil har oppstått ved henting av program. Vennligst prøv igjen senere.

      );
    }

    let { postDaysSection, preDaysSection, preDays } = this.buildEvents(events);

    return (

        { preDaysSection }
        {
          preDays.length > 0 ?
            <button className="cal-button--preDays" onClick={this.preDaysClickHandler}>
              {( this.state.preDaysSectionActive ? 'Skjul' : 'Vis' ) + ' tidligere arrangementer' }
            </button>
          :
            ''
        }
        { postDaysSection }

    );
  }
}

export default Calendar;
<|endoftext|>


<commit_before>(function(){
  var $section = $('#gradrates'),
      $source = $section.find('table'),
      data = $source.tabulate().toArray().reverse(),
      colors = ['#99c', '#639', '#306'],
      options = {
        'color': colors,
        'tooltip': function() {
          // TODO: replace with Handlebars
          return this.__data__.series + " bachelor's graduation rate
" +
            d3.format(",.2f")(this.__data__.y) + "%";
        }
      },
      Chart = D3BarChart.extend({
        get_layers: function(){
          // set up a layer for each series
          var self = this;
          var layers = self.plot.selectAll("g.layer")
            .data(this._data)
            .enter().append("g")
              .attr("class", "layer")
              .style("fill", function(d, i) { return self.options.color(i); });
          // shift grouped bars so they're adjacent to each other
          layers
            .attr("transform", function(d, i) {
              var offset = 20 - 10 * i;
              return "translate(" + offset + ",0)";
            });
          return layers;
        },

        get_bar_width: function(){
          var len_series = this._data.length; // m, i, rows
          var len_x = this._data[0].length;   // n, j, cols
          var bar_width = this.options.plot_box.w / len_x;  // bar_width is an outer width
          bar_width = bar_width - 20 - 10;
          return bar_width;
        },

        // y-axis shows percentage
        get_y_domain: function(){
          return [0, 100];
        }
      });

  new Chart($section.find('.d3-viz'), data, options);

})();
<commit_msg>A little additional cleanup<commit_after>(function(){
  var $section = $('#gradrates'),
      data = $section.find('table').tabulate().toArray().reverse(),
      options = {
        'color': ['#99c', '#639', '#306'],
        'tooltip': function() {
          // TODO: replace with Handlebars
          return this.__data__.series + " bachelor's graduation rate
" +
            d3.format(",.2f")(this.__data__.y) + "%";
        }
      };

  var Chart = D3BarChart.extend({
    get_layers: function(){
      // set up a layer for each series
      var self = this;
      var layers = self.plot.selectAll("g.layer")
        .data(this._data)
        .enter().append("g")
          .attr("class", "layer")
          .style("fill", function(d, i) { return self.options.color(i); });
      // shift grouped bars so they're adjacent to each other
      layers
        .attr("transform", function(d, i) {
          var offset = 20 - 10 * i;
          return "translate(" + offset + ",0)";
        });
      return layers;
    },

    get_bar_width: function(){
      var len_series = this._data.length; // m, i, rows
      var len_x = this._data[0].length;   // n, j, cols
      var bar_width = this.options.plot_box.w / len_x;  // bar_width is an outer width
      bar_width = bar_width - 20 - 10;
      return bar_width;
    },

    // y-axis shows percentage
    get_y_domain: function(){
      return [0, 100];
    }
  });

  new Chart($section.find('.d3-viz'), data, options);

})();
<|endoftext|>


<commit_before>"use strict";

var FRAME_ID = "#eyebrowse-frame";
var TEMPLATE_HTML = {};
// only request the bubble every BUBBLE_THRESHOLD milliseconds
var BUBBLE_THRESHOLD = 5 * 60 * 1000; // 5 minutes
var LAST_BUBBLE = Date.now() - BUBBLE_THRESHOLD; // we should initially show the bubble

function truncate(str, length) {
    if (str.length > length) {
        return str.substring(0, length);
    } else {
        return str;
    }
}

function createTrackPrompt(url) {
    return getPromptTemplate("#track-prompt", {
        "url": new URL(url).hostname,
    });
}

function createLoginPrompt() {
    return getPromptTemplate("#login-prompt");
}

function createBubblePrompt(data, baseUrl) {
    if (data.active_users.length === 0 && data.message === "") {
        return null;
    }

    var msg = truncate(data.message, 51);

    if (data.user_url === "") {
        msg = truncate(data.message, 78);
    }

    msg = createMentionTag(msg);

    var template = getPromptTemplate("#bubble-prompt", {
        "msg": msg,
        "user_url": data.user_url,
        "username": data.username,
        "about_message": data.about_message,
        "users": data.active_users
    });

    var images = template.find(".eyebrowse-bubble-user-icon");
    for (var i = 0; i < images.length; i++) {
        $(images[i]).attr("src", data.active_users[i].pic_url);
    }
    return template;
}

function inDefaultBlacklist(url) {
	var hostname = new URL(url).hostname;
	if (hostname.indexOf('google.com') > -1) {
		return true;
	}
	return false;
}

/*
    Call the eyebrowse server to get an iframe with a prompt
    Can either be a login or track type prompt.
*/
function setup(baseUrl, promptType, user, url, protocol) {
    if ($(FRAME_ID).length) {
        $(FRAME_ID).css("z-index", 999999999);
        return;
    }

    var frameHtml;

    if (promptType === "trackPrompt") {

    	if (inDefaultBlacklist(url)) return;

        frameHtml = createTrackPrompt(url);
        addFrame(frameHtml);

        chrome.extension.sendMessage(JSON.stringify({
            "action": "nag",
            "url": window.document.URL
        }));

        $("#eyebrowse-allow-btn").click(function() {
            $(FRAME_ID).remove();
            var msg = {
                "action": "filterlist",
                "type": "whitelist",
                "url": url
            };
            chrome.extension.sendMessage(JSON.stringify(msg));
        });

        $("#eyebrowse-deny-btn").click(function() {
            $(FRAME_ID).remove();
            var msg = {
                "action": "filterlist",
                "type": "blacklist",
                "url": url
            };
            chrome.extension.sendMessage(JSON.stringify(msg));
        });

    } else if (promptType === "loginPrompt") {
        frameHtml = createLoginPrompt();
        addFrame(frameHtml);

        $("#eyebrowse-ignore-btn").click(function() {
            $(FRAME_ID).remove();
            var msg = {
                "action": "ignore"
            };
            chrome.extension.sendMessage(JSON.stringify(msg));
        });

    } else if (promptType === "bubbleInfo" && protocol === "http:") { // TODO fix with ssl certs for eyebrowse
        if (LAST_BUBBLE !== -1 && Date.now() - LAST_BUBBLE >= BUBBLE_THRESHOLD) {
            LAST_BUBBLE = Date.now();
            $.ajax({
                url: baseUrl + "/ext/bubbleInfo/",
                type: "POST",
                data: {
                    "url": url,
                    "csrfmiddlewaretoken": user.csrf,
                },
                success: function(data) {
                    frameHtml = createBubblePrompt(data, baseUrl);
                    addFrame(frameHtml);
                },
                error: function(data) {
                  LAST_BUBBLE = -1;
                }
            });
        }
    }
}

/*
 * Add the prompt css to the main page
 */
function addStyle() {
    if (!$("#eyebrowse-frame-css").length) {
        var url = chrome.extension.getURL("../css/prompt.css");
        var link = $("<link id='eyebrowse-frame-css' href='" + url + "' rel='stylesheet' />")[0];

        (document.head || document.body).appendChild(link);
    }
}

/*
 * Helper function which adds a popup frame to the page
 */
function addFrame(frameHtml) {
    if (frameHtml === null) {
        return;
    }

    addStyle();
    $("body").append(frameHtml);

    // Remove the element after it fades out. The fading & delay is taken care by CSS
    $(FRAME_ID).bind("animationend webkitAnimationEnd", function(evt) {
        if (evt.originalEvent.animationName === "fade") {
            this.parentNode.removeChild(this);
        }
    });

    $("#eyebrowse-close-btn").click(function() {
        $(FRAME_ID).remove();
    });
}

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
    var protocol = window.location.protocol;
    var url = document.URL;
    var action = request.action;

    if (action === "prompt") {
        setup(request.baseUrl, request.type, request.user, url, protocol);
    }
});
<commit_msg>Disable popup notifications<commit_after>"use strict";

var FRAME_ID = "#eyebrowse-frame";
var TEMPLATE_HTML = {};
// only request the bubble every BUBBLE_THRESHOLD milliseconds
var BUBBLE_THRESHOLD = 5 * 60 * 1000; // 5 minutes
var LAST_BUBBLE = Date.now() - BUBBLE_THRESHOLD; // we should initially show the bubble

function truncate(str, length) {
    if (str.length > length) {
        return str.substring(0, length);
    } else {
        return str;
    }
}

function createTrackPrompt(url) {
    return getPromptTemplate("#track-prompt", {
        "url": new URL(url).hostname,
    });
}

function createLoginPrompt() {
    return getPromptTemplate("#login-prompt");
}

function createBubblePrompt(data, baseUrl) {
    if (data.active_users.length === 0 && data.message === "") {
        return null;
    }

    var msg = truncate(data.message, 51);

    if (data.user_url === "") {
        msg = truncate(data.message, 78);
    }

    msg = createMentionTag(msg);

    var template = getPromptTemplate("#bubble-prompt", {
        "msg": msg,
        "user_url": data.user_url,
        "username": data.username,
        "about_message": data.about_message,
        "users": data.active_users
    });

    var images = template.find(".eyebrowse-bubble-user-icon");
    for (var i = 0; i < images.length; i++) {
        $(images[i]).attr("src", data.active_users[i].pic_url);
    }
    return template;
}

function inDefaultBlacklist(url) {
	var hostname = new URL(url).hostname;
	if (hostname.indexOf('google.com') > -1) {
		return true;
	}
	return false;
}

/*
    Call the eyebrowse server to get an iframe with a prompt
    Can either be a login or track type prompt.
*/
function setup(baseUrl, promptType, user, url, protocol) {
    if ($(FRAME_ID).length) {
        $(FRAME_ID).css("z-index", 999999999);
        return;
    }

    var frameHtml;

    if (promptType === "trackPrompt") {

    	if (inDefaultBlacklist(url)) return;

        frameHtml = createTrackPrompt(url);
        addFrame(frameHtml);

        chrome.extension.sendMessage(JSON.stringify({
            "action": "nag",
            "url": window.document.URL
        }));

        $("#eyebrowse-allow-btn").click(function() {
            $(FRAME_ID).remove();
            var msg = {
                "action": "filterlist",
                "type": "whitelist",
                "url": url
            };
            chrome.extension.sendMessage(JSON.stringify(msg));
        });

        $("#eyebrowse-deny-btn").click(function() {
            $(FRAME_ID).remove();
            var msg = {
                "action": "filterlist",
                "type": "blacklist",
                "url": url
            };
            chrome.extension.sendMessage(JSON.stringify(msg));
        });

    } else if (promptType === "loginPrompt") {
        frameHtml = createLoginPrompt();
        addFrame(frameHtml);

        $("#eyebrowse-ignore-btn").click(function() {
            $(FRAME_ID).remove();
            var msg = {
                "action": "ignore"
            };
            chrome.extension.sendMessage(JSON.stringify(msg));
        });

    } else if (promptType === "bubbleInfo" && protocol === "http:") { // TODO fix with ssl certs for eyebrowse
        if (LAST_BUBBLE !== -1 && Date.now() - LAST_BUBBLE >= BUBBLE_THRESHOLD) {
            LAST_BUBBLE = Date.now();
            $.ajax({
                url: baseUrl + "/ext/bubbleInfo/",
                type: "POST",
                data: {
                    "url": url,
                    "csrfmiddlewaretoken": user.csrf,
                },
                success: function(data) {
                    frameHtml = createBubblePrompt(data, baseUrl);
                    addFrame(frameHtml);
                },
                error: function(data) {
                  LAST_BUBBLE = -1;
                }
            });
        }
    }
}

/*
 * Add the prompt css to the main page
 */
function addStyle() {
    if (!$("#eyebrowse-frame-css").length) {
        var url = chrome.extension.getURL("../css/prompt.css");
        var link = $("<link id='eyebrowse-frame-css' href='" + url + "' rel='stylesheet' />")[0];

        (document.head || document.body).appendChild(link);
    }
}

/*
 * Helper function which adds a popup frame to the page
 */
function addFrame(frameHtml) {
    if (frameHtml === null) {
        return;
    }

    addStyle();
    $("body").append(frameHtml);

    // Remove the element after it fades out. The fading & delay is taken care by CSS
    $(FRAME_ID).bind("animationend webkitAnimationEnd", function(evt) {
        if (evt.originalEvent.animationName === "fade") {
            this.parentNode.removeChild(this);
        }
    });

    $("#eyebrowse-close-btn").click(function() {
        $(FRAME_ID).remove();
    });
}

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
    var protocol = window.location.protocol;
    var url = document.URL;
    var action = request.action;

    if (action === "prompt") {
        // disable notifications
        // setup(request.baseUrl, request.type, request.user, url, protocol);
    }
});
<|endoftext|>


<commit_before>/*
 * Plugin Name: Vanilla-JS Infinite Scroll
 * Version: 0.3.2
 * Plugin URL: https://github.com/Darklg/JavaScriptUtilities
 * JavaScriptUtilities Vanilla-JS may be freely distributed under the MIT license.
 */

function vanilla_infinite_scroll(el, opts) {
    'use strict';

    /*jshint validthis: true */
    var self = this;

    /* Filter arguments */
    opts = opts || {};
    if (!el) {
        return;
    }
    self.el = el;

    /* Options
    -------------------------- */

    var overflowItem = (opts.overflowItem || (el.style.overflow == 'auto'));
    var callbackUrl = self.el.getAttribute('data-callbackurl') || opts.callbackUrl || false;
    var returnType = self.el.getAttribute('data-returntype') || opts.returnType || 'html';
    var offsetScroll = parseInt(self.el.getAttribute('data-offsetscroll') || opts.offsetScroll || 500, 10);
    var stopInfiniteScroll = false;

    /* Callbacks */
    var callbackBeforeResponse = opts.callbackBeforeResponse || function(self, responseText) {};
    var callbackAfterResponse = opts.callbackAfterResponse || function(self, responseText) {};
    var callbackResponse = opts.callbackResponse || function(self, responseText) {
        self.el.setAttribute('data-currentpage', self.nextPage);
        self.el.insertAdjacentHTML('beforeend', responseText);
        self.nextPage = self.incrementationMethod(self.nextPage);
    };

    /* Pagination */
    self.incrementationMethod = opts.incrementationMethod || function(pageNb) {
        return pageNb + 1;
    };
    self.currentPage = parseInt(self.el.getAttribute('data-currentpage') || opts.currentPage || 1, 10);
    self.nextPage = parseInt(self.el.getAttribute('data-currentpage') || opts.currentPage || self.incrementationMethod(self.currentPage), 10);

    /* Internal settings */
    var canInfiniteScroll = true,
        scrollLevel = 0,
        scrollMax = 0,
        scrollListener = window;

    if (overflowItem) {
        /* Overflow auto, check events  */
        scrollListener = el;
    }

    /* Methods
    -------------------------- */

    function init() {
        self.set_events();
    }

    self.set_events = function() {
        resize_event();
        scroll_event();
        window.addEventListener('resize', resize_event, false);
        window.addEventListener('scroll', resize_event, false);
        scrollListener.addEventListener('scroll', scroll_event, false);
    };

    self.unset_events = function() {
        window.removeEventListener('resize', resize_event, false);
        window.removeEventListener('scroll', resize_event, false);
        scrollListener.removeEventListener('scroll', scroll_event, false);
    };

    function resize_event() {
        /* Set Scroll Max */
        if (overflowItem) {
            scrollMax = self.el.scrollHeight - offsetScroll;
            return false;
        }
        var elBounds = self.el.getBoundingClientRect();
        scrollMax = getBodyScrollTop() + elBounds.top + elBounds.height - offsetScroll;
    }

    function scroll_event() {

        if (stopInfiniteScroll) {
            self.unset_events();
            return false;
        }

        if (!canInfiniteScroll) {
            return false;
        }

        /* Check visibility */
        if (!isVisible(self.el)) {
            return false;
        }

        // Get scroll level
        scrollLevel = overflowItem ? getElementScrollBottom(self.el) : getBodyScrollBottom();

        // If scroll level not over scrollmax
        if (scrollLevel < scrollMax) {
            return false;
        }

        // Disable infinite scroll
        disable_infinite_scroll();

        // Load callbackurl
        var data = {
            page: self.nextPage
        };
        if (callbackUrl) {
            ajaxRequest(callbackUrl, success_callback, data);
        }
    }

    function success_callback(responseText) {
        if (!responseText) {
            self.unset_events();
        }
        if (returnType == 'json') {
            responseText = JSON.parse(responseText);
        }

        // Multiple callbacks
        callbackBeforeResponse(self, responseText);
        callbackResponse(self, responseText);
        callbackAfterResponse(self, responseText);

        // Trigger resize to update values
        setTimeout(function() {
            triggerResize();
        }, 50);

        setTimeout(function() {
            // Enable infinite event
            enable_infinite_scroll();

            // Try a new scroll event
            scroll_event();
        }, 100);
    }

    /* Enable / Disable infinite scroll */
    function enable_infinite_scroll() {
        canInfiniteScroll = true;
        self.el.setAttribute('aria-busy', 'false');
        self.el.setAttribute('data-loading', 'false');
    }

    function disable_infinite_scroll() {
        canInfiniteScroll = false;
        self.el.setAttribute('aria-busy', 'true');
        self.el.setAttribute('data-loading', 'true');
    }

    /* Generic Utilities
    -------------------------- */

    function isVisible(elem) {
        return elem.offsetParent !== null;
    }

    function triggerResize() {
        var e = window.document.createEvent('UIEvents');
        e.initUIEvent('resize', true, false, window, 0);
        window.dispatchEvent(e);
    }

    function ajaxRequest(url, callbackFun, data) {
        if (window.jQuery) {
            jQuery.ajax({
                url: url,
                success: callbackFun,
                data: data
            });
            return;
        }
        new jsuAJAX({
            url: url,
            callback: callbackFun,
            data: data
        });
    }

    function getElementScrollBottom(elem) {
        return elem.scrollTop + elem.offsetHeight;
    }

    function getBodyScrollTop() {
        return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
    }

    function getBodyScrollBottom() {
        return getBodyScrollTop() + Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
    }
    init();
}
<commit_msg>v 0.3.3<commit_after>/*
 * Plugin Name: Vanilla-JS Infinite Scroll
 * Version: 0.3.3
 * Plugin URL: https://github.com/Darklg/JavaScriptUtilities
 * JavaScriptUtilities Vanilla-JS may be freely distributed under the MIT license.
 */

function vanilla_infinite_scroll(el, opts) {
    'use strict';

    /*jshint validthis: true */
    var self = this;

    /* Filter arguments */
    opts = opts || {};
    if (!el) {
        return;
    }
    self.el = el;

    /* Options
    -------------------------- */

    var overflowItem = (opts.overflowItem || (el.style.overflow == 'auto'));
    var callbackUrl = self.el.getAttribute('data-callbackurl') || opts.callbackUrl || false;
    var moreDatas = self.el.getAttribute('data-moredatas') || opts.moreDatas || {};
    var returnType = self.el.getAttribute('data-returntype') || opts.returnType || 'html';
    var offsetScroll = parseInt(self.el.getAttribute('data-offsetscroll') || opts.offsetScroll || 500, 10);
    var stopInfiniteScroll = false;

    /* Callbacks */
    var callbackBeforeResponse = opts.callbackBeforeResponse || function(self, responseText) {};
    var callbackAfterResponse = opts.callbackAfterResponse || function(self, responseText) {};
    var callbackResponse = opts.callbackResponse || function(self, responseText) {
        self.el.setAttribute('data-currentpage', self.nextPage);
        self.el.insertAdjacentHTML('beforeend', responseText);
        self.nextPage = self.incrementationMethod(self.nextPage);
    };

    /* Pagination */
    self.incrementationMethod = opts.incrementationMethod || function(pageNb) {
        return pageNb + 1;
    };
    self.currentPage = parseInt(self.el.getAttribute('data-currentpage') || opts.currentPage || 1, 10);
    self.nextPage = parseInt(self.el.getAttribute('data-currentpage') || opts.currentPage || self.incrementationMethod(self.currentPage), 10);

    /* Internal settings */
    var canInfiniteScroll = true,
        scrollLevel = 0,
        scrollMax = 0,
        scrollListener = window;

    if (overflowItem) {
        /* Overflow auto, check events  */
        scrollListener = el;
    }

    /* Methods
    -------------------------- */

    function init() {
        self.set_events();
    }

    self.set_events = function() {
        resize_event();
        scroll_event();
        window.addEventListener('resize', resize_event, false);
        window.addEventListener('scroll', resize_event, false);
        scrollListener.addEventListener('scroll', scroll_event, false);
    };

    self.unset_events = function() {
        window.removeEventListener('resize', resize_event, false);
        window.removeEventListener('scroll', resize_event, false);
        scrollListener.removeEventListener('scroll', scroll_event, false);
    };

    function resize_event() {
        /* Set Scroll Max */
        if (overflowItem) {
            scrollMax = self.el.scrollHeight - offsetScroll;
            return false;
        }
        var elBounds = self.el.getBoundingClientRect();
        scrollMax = getBodyScrollTop() + elBounds.top + elBounds.height - offsetScroll;
    }

    function scroll_event() {

        if (stopInfiniteScroll) {
            self.unset_events();
            return false;
        }

        if (!canInfiniteScroll) {
            return false;
        }

        /* Check visibility */
        if (!isVisible(self.el)) {
            return false;
        }

        // Get scroll level
        scrollLevel = overflowItem ? getElementScrollBottom(self.el) : getBodyScrollBottom();

        // If scroll level not over scrollmax
        if (scrollLevel < scrollMax) {
            return false;
        }

        // Disable infinite scroll
        disable_infinite_scroll();

        // Load callbackurl
        var data = {
            page: self.nextPage
        };

        (function() {
            if (moreDatas) {
                return;
            }
            if (typeof moreDatas != 'object') {
                moreDatas = JSON.parse(moreDatas);
            }
            for (var attrname in moreDatas) {
                data[attrname] = moreDatas[attrname];
            }
        }());

        if (callbackUrl) {
            ajaxRequest(callbackUrl, success_callback, data);
        }
    }

    function success_callback(responseText) {
        if (!responseText) {
            self.unset_events();
        }
        if (returnType == 'json') {
            responseText = JSON.parse(responseText);
        }

        // Multiple callbacks
        callbackBeforeResponse(self, responseText);
        callbackResponse(self, responseText);
        callbackAfterResponse(self, responseText);

        // Trigger resize to update values
        setTimeout(function() {
            triggerResize();
        }, 50);

        setTimeout(function() {
            // Enable infinite event
            enable_infinite_scroll();

            // Try a new scroll event
            scroll_event();
        }, 100);
    }

    /* Enable / Disable infinite scroll */
    function enable_infinite_scroll() {
        canInfiniteScroll = true;
        self.el.setAttribute('aria-busy', 'false');
        self.el.setAttribute('data-loading', 'false');
    }

    function disable_infinite_scroll() {
        canInfiniteScroll = false;
        self.el.setAttribute('aria-busy', 'true');
        self.el.setAttribute('data-loading', 'true');
    }

    /* Generic Utilities
    -------------------------- */

    function isVisible(elem) {
        return elem.offsetParent !== null;
    }

    function triggerResize() {
        var e = window.document.createEvent('UIEvents');
        e.initUIEvent('resize', true, false, window, 0);
        window.dispatchEvent(e);
    }

    function ajaxRequest(url, callbackFun, data) {
        if (window.jQuery) {
            jQuery.ajax({
                url: url,
                success: callbackFun,
                data: data
            });
            return;
        }
        new jsuAJAX({
            url: url,
            callback: callbackFun,
            data: data
        });
    }

    function getElementScrollBottom(elem) {
        return elem.scrollTop + elem.offsetHeight;
    }

    function getBodyScrollTop() {
        return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
    }

    function getBodyScrollBottom() {
        return getBodyScrollTop() + Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
    }
    init();
}
<|endoftext|>


<commit_before>var app = {
    // Application Constructor
    initialize: function() {
      this.bindEvents();
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // 'load', 'deviceready', 'offline', and 'online'.
    bindEvents: function() {
      document.addEventListener('deviceready', this.onDeviceReady, false);
      document.addEventListener("offline", checkConnection, false);
      document.addEventListener("pause", onPause, false);
      document.addEventListener("resume", onResume, false);
    },
    // deviceready Event Handler
    //
    // The scope of 'this' is the event. In order to call the 'receivedEvent'
    // function, we must explicitly call 'app.receivedEvent(...);'
    onDeviceReady: function() {
      app.receivedEvent('deviceready');
      screen.lockOrientation('portrait');
      localStorage.setItem("saldo_actual",0);
      localStorage.setItem("wisi","false");
    },
    // Update DOM on a Received Event
    receivedEvent: function(id) {
      getDeviceProperty();
      detectGEO();
    }
  };

  function detectGEO(){
    var options = {
      enableHighAccuracy: true,
      timeout: 5000,
      maximumAge: 75000
    };
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(onSuccess, onError, options);
    } else {
      console.log('Geolocalización no soportada');
    }
  }

// onSuccess Geolocation    //
function onSuccess(position) {
  localStorage.removeItem("position");
  lat1= position.coords.latitude;
  lng1= position.coords.longitude;
  var pos= {lat:lat1,lng:lng1};
  localStorage.setItem("position",JSON.stringify(pos));
  console.log('Coordenadas detectadas');
}

function onError(error) {
  console.log('Error detectando coordenadas');
}

function getDeviceProperty()
{
     var deviceOS  = device.platform  ;  //fetch the device operating system
     var deviceOSVersion = device.version ;  //fetch the device OS version
     localStorage.setItem("OS",deviceOS);
   }

   function onPause() {
    localStorage.setItem("wisi","false");
    console.log("paused");
    if(!localStorage.scanear)searchWISI();
  }

  function searchWISI(){
    WifiWizard.isWifiEnabled(winEnabled, failEnabled);
  }
  function winEnabled(){
    console.log("WIFI encendido");
    window.setTimeout(function(){
      WifiWizard.getScanResults(listHandler, fail);
      console.log("Check available WIFIs");
    },60000);//1 minuto 60000
  }
  function failEnabled(){
    console.log("WIFI apagado");
    myApp.alert("Debe encender su WIFI para continuar", "");
  }

  function onResume() {
    localStorage.setItem("wisi","true");
    localStorage.setItem("scanner","false");
    console.log("resume");
  }

  function checkConnection() {
    var state=true;
    var networkState = navigator.connection.type;
    var states = {};
    states[Connection.UNKNOWN]  = 'Unknown connection';
    states[Connection.ETHERNET] = 'Ethernet connection';
    states[Connection.WIFI]     = 'WiFi connection';
    states[Connection.CELL_2G]  = 'Cell 2G connection';
    states[Connection.CELL_3G]  = 'Cell 3G connection';
    states[Connection.CELL_4G]  = 'Cell 4G connection';
    states[Connection.CELL]     = 'Cell generic connection';
    states[Connection.NONE]     = 'No network connection';

    if(states[networkState]=='No network connection'){
        //navigator.vibrate(1000);
        //alert('Internet no disponible!');
        state=false;
      }
      return state;
    }

    function fail(e){
      console.log("Detect active "+e);
    }

  function listHandler(a){
    if(localStorage.wisi=="false"){
      for(var i=0; i<a.length; i++){
        if(a[i]["SSID"]=="WISI TE CONECTA"||a[i]["SSID"]=="VALENCIA_V"){
          console.log("WIFI deectado")
          if(localStorage.wisi=="false"){
              cordova.plugins.notification.local.schedule({ message:"Red WISI detectada",sound: "file://sounds/HTC Happy.mp3" });
              localStorage.setItem("wisi","true");
              navigator.vibrate(1000);
              exists++;
            }
          }
        }
        searchWISI();
      }
  }<commit_msg>WIFI detect<commit_after>var app = {
    // Application Constructor
    initialize: function() {
      this.bindEvents();
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // 'load', 'deviceready', 'offline', and 'online'.
    bindEvents: function() {
      document.addEventListener('deviceready', this.onDeviceReady, false);
      document.addEventListener("offline", checkConnection, false);
      document.addEventListener("pause", onPause, false);
      document.addEventListener("resume", onResume, false);
    },
    // deviceready Event Handler
    //
    // The scope of 'this' is the event. In order to call the 'receivedEvent'
    // function, we must explicitly call 'app.receivedEvent(...);'
    onDeviceReady: function() {
      app.receivedEvent('deviceready');
      screen.lockOrientation('portrait');
      localStorage.setItem("saldo_actual",0);
      localStorage.setItem("wisi","false");
    },
    // Update DOM on a Received Event
    receivedEvent: function(id) {
      getDeviceProperty();
      detectGEO();
    }
  };

  function detectGEO(){
    var options = {
      enableHighAccuracy: true,
      timeout: 5000,
      maximumAge: 75000
    };
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(onSuccess, onError, options);
    } else {
      console.log('Geolocalización no soportada');
    }
  }

// onSuccess Geolocation    //
function onSuccess(position) {
  localStorage.removeItem("position");
  lat1= position.coords.latitude;
  lng1= position.coords.longitude;
  var pos= {lat:lat1,lng:lng1};
  localStorage.setItem("position",JSON.stringify(pos));
  console.log('Coordenadas detectadas');
}

function onError(error) {
  console.log('Error detectando coordenadas');
}

function getDeviceProperty()
{
     var deviceOS  = device.platform  ;  //fetch the device operating system
     var deviceOSVersion = device.version ;  //fetch the device OS version
     localStorage.setItem("OS",deviceOS);
   }

   function onPause() {
    localStorage.setItem("wisi","false");
    console.log("paused");
    if(!localStorage.scanear)searchWISI();
  }

  function searchWISI(){
    WifiWizard.isWifiEnabled(winEnabled, failEnabled);
  }
  function winEnabled(){
    console.log("WIFI encendido");
    window.setTimeout(function(){
      WifiWizard.getScanResults(listHandler, fail);
      console.log("Check available WIFIs");
    },60000);//1 minuto 60000
  }
  function failEnabled(){
    console.log("WIFI apagado");
    myApp.alert("Debe encender su WIFI para continuar", "");
  }

  function onResume() {
    localStorage.setItem("wisi","true");
    localStorage.setItem("scanner","false");
    console.log("resume");
  }

  function checkConnection() {
    var state=true;
    var networkState = navigator.connection.type;
    var states = {};
    states[Connection.UNKNOWN]  = 'Unknown connection';
    states[Connection.ETHERNET] = 'Ethernet connection';
    states[Connection.WIFI]     = 'WiFi connection';
    states[Connection.CELL_2G]  = 'Cell 2G connection';
    states[Connection.CELL_3G]  = 'Cell 3G connection';
    states[Connection.CELL_4G]  = 'Cell 4G connection';
    states[Connection.CELL]     = 'Cell generic connection';
    states[Connection.NONE]     = 'No network connection';

    if(states[networkState]=='No network connection'){
        //navigator.vibrate(1000);
        //alert('Internet no disponible!');
        state=false;
      }
      return state;
    }

    function fail(e){
      console.log("Detect active "+e);
    }

  function listHandler(a){
    if(localStorage.wisi=="false"){
      for(var i=0; i<a.length; i++){
        if(a[i]["SSID"]=="WISI TE CONECTA"||a[i]["SSID"]=="VALENCIA_V"){
          console.log("WIFI detectado")
          if(localStorage.wisi=="false"){
              cordova.plugins.notification.local.schedule({ message:"Red WISI detectada",sound: "file://sounds/HTC Happy.mp3" });
              localStorage.setItem("wisi","true");
              navigator.vibrate(1000);
            }
          }
        }
        searchWISI();
      }
  }<|endoftext|>


<commit_before>/* jshint node:true */
"use strict";

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON("package.json"),

    watch: {
      sass: {
        files: ["scss/**/*.{scss,sass}"],
        tasks: ["sass:compile"]
      },
      js: {
        files: ["js/**/*.js", "tests/**/*.js"],
        tasks: ["jshint:all", "browserify:dist", "uglify:dev"]
      },
      images: {
        files: ["assets/images/**/*.{png,jpg,jpeg,gif}"],
        tasks: ["imagemin"]
      },
      livereload: {
        files: ["dist/**/*.css", "dist/**/*.{js,json}", "dist/images/**/*.{png,jpg,jpeg,gif,webp,svg}"],
        options: {
          livereload: true
        }
      }
    },

    sass: {
      compile: {
        files: {
          "dist/app.css": "scss/app.scss",
          "dist/ie.css": "scss/ie.scss"
        },
        options: {
          sourceComments: "normal"
        }
      }
    },

    cssmin: {
      minify: {
        options: {
          report: "gzip"
        },
        files: {
          "dist/app.css": ["dist/app.css"],
          "dist/ie.css": ["dist/ie.css"]
        }
      }
    },

    copy: {
      main: {
        files: [
          {expand: true, src: ["assets/images/**", "!images/**/*"], dest: "dist/"},
        ]
      }
    },

    imagemin: {
      bundle: {
        files: [{
          expand: true,
          cwd: "assets/images/",
          src: ["**/*.{png,jpg,jpeg,gif}"],
          dest: "dist/assets/images"
        }]
      }
    },

    jshint: {
      options: {
        force: true,
        jshintrc: true,
        reporter: require("jshint-stylish")
      },
      all: ["js/**/*.js", "!js/vendor/**/*.js", "!js/polyfills/**/*.js",  "tests/**/*.js", "!tests/lib/**/*.js"]
    },

    qunit: {
      all: ["tests/*.html"]
    },

    browserify: {
      dist: {
        src: ['js/app.js'],
        dest: 'dist/app.js',
        options: {
          transform: ['debowerify']
        }
      }
    },

    uglify: {
      prod: {
        options: {
          report: "gzip"
        },
        files: {
          "dist/app.js": ["dist/app.js"],
        }
      },
      dev: {
        options: {
          mangle: false,
          compress: false,
          beautify: true
        },
        files: {
          "dist/app.js": ["dist/app.js"],
        }
      }
    },

    docco: {
      docs: {
        src: ["js/*.js"],
        options: {
          output: "dist/docs"
        }
      }
    },

    shell: {
      scsslint: {
        command: "scss-lint scss/ --config .scss-lint.yaml",
        options: {
          stdout: true
        }
      },

      clean: {
        command: "rm -rf dist/*"
      }
    }

  });

  grunt.registerTask("default", ["build", "watch"]);

  // code linting
  grunt.registerTask("lint", ["jshint:all", "shell:scsslint"]);

  // testing
  grunt.registerTask("test", ["test:css", "test:js"]);
  grunt.registerTask("test:css", ["shell:wraith"]);
  grunt.registerTask("test:js", ["qunit"]);

  // build
  grunt.registerTask("build", ["lint", "sass:compile", "imagemin", "browserify:dist", "uglify:dev", "copy:main"]);
  grunt.registerTask("prod", ["shell:clean", "sass:compile", "cssmin:minify", "copy:main", "imagemin", "browserify:dist", "uglify:prod"]); // used when preparing code for distribution

  grunt.loadNpmTasks("grunt-sass");
  grunt.loadNpmTasks("grunt-contrib-cssmin");
  grunt.loadNpmTasks("grunt-contrib-imagemin");
  grunt.loadNpmTasks("grunt-contrib-copy");
  grunt.loadNpmTasks("grunt-contrib-jshint");
  grunt.loadNpmTasks("grunt-contrib-qunit");
  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks("grunt-contrib-uglify");
  grunt.loadNpmTasks("grunt-contrib-watch");
  grunt.loadNpmTasks("grunt-shell");
};
<commit_msg>Updated Gruntfile with temporary image pipeline (for future imagemin integration).<commit_after>/* jshint node:true */
"use strict";

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON("package.json"),

    watch: {
      sass: {
        files: ["scss/**/*.{scss,sass}"],
        tasks: ["sass:compile"]
      },
      js: {
        files: ["js/**/*.js", "tests/**/*.js"],
        tasks: ["jshint:all", "browserify:dist", "uglify:dev"]
      },
      images: {
        files: ["assets/images/**/*.{png,jpg,jpeg,gif}"],
        tasks: ["imagemin"]
      },
      livereload: {
        files: ["dist/**/*.css", "dist/**/*.{js,json}", "dist/images/**/*.{png,jpg,jpeg,gif,webp,svg}"],
        options: {
          livereload: true
        }
      }
    },

    sass: {
      compile: {
        files: {
          "dist/app.css": "scss/app.scss",
          "dist/ie.css": "scss/ie.scss"
        },
        options: {
          sourceComments: "normal"
        }
      }
    },

    cssmin: {
      minify: {
        options: {
          report: "gzip"
        },
        files: {
          "dist/app.css": ["dist/app.css"],
          "dist/ie.css": ["dist/ie.css"]
        }
      }
    },

    copy: {
      main: {
        files: [
          {expand: true, src: ["images/**"], dest: "dist/"},
        ]
      }
    },

    imagemin: {
      bundle: {
        files: [{
          expand: true,
          cwd: "assets/images/",
          src: ["**/*.{png,jpg,jpeg,gif}"],
          dest: "dist/assets/images"
        }]
      }
    },

    jshint: {
      options: {
        force: true,
        jshintrc: true,
        reporter: require("jshint-stylish")
      },
      all: ["js/**/*.js", "!js/vendor/**/*.js", "tests/**/*.js", "!tests/lib/**/*.js"]
    },

    qunit: {
      all: ["tests/*.html"]
    },

    browserify: {
      dist: {
        src: ['js/app.js'],
        dest: 'dist/app.js',
        options: {
          transform: ['debowerify']
        }
      }
    },

    uglify: {
      prod: {
        options: {
          report: "gzip"
        },
        files: {
          "dist/app.js": ["dist/app.js"],
        }
      },
      dev: {
        options: {
          mangle: false,
          compress: false,
          beautify: true
        },
        files: {
          "dist/app.js": ["dist/app.js"],
        }
      }
    },

    docco: {
      docs: {
        src: ["js/*.js"],
        options: {
          output: "dist/docs"
        }
      }
    },

    shell: {
      scsslint: {
        command: "scss-lint scss/ --config .scss-lint.yaml",
        options: {
          stdout: true
        }
      },

      clean: {
        command: "rm -rf dist/*"
      }
    }

  });

  grunt.registerTask("default", ["build", "watch"]);

  // code linting
  grunt.registerTask("lint", ["jshint:all", "shell:scsslint"]);

  // testing
  grunt.registerTask("test", ["test:css", "test:js"]);
  grunt.registerTask("test:css", ["shell:wraith"]);
  grunt.registerTask("test:js", ["qunit"]);

  // build
  grunt.registerTask("build", ["lint", "sass:compile", "browserify:dist", "uglify:dev", "copy:main"]);
  grunt.registerTask("prod", ["shell:clean", "sass:compile", "cssmin:minify", "copy:main", "browserify:dist", "uglify:prod"]); // used when preparing code for distribution

  grunt.loadNpmTasks("grunt-sass");
  grunt.loadNpmTasks("grunt-contrib-cssmin");
  grunt.loadNpmTasks("grunt-contrib-imagemin");
  grunt.loadNpmTasks("grunt-contrib-copy");
  grunt.loadNpmTasks("grunt-contrib-jshint");
  grunt.loadNpmTasks("grunt-contrib-qunit");
  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks("grunt-contrib-uglify");
  grunt.loadNpmTasks("grunt-contrib-watch");
  grunt.loadNpmTasks("grunt-shell");
};
<|endoftext|>


<commit_before>var dbRef = new Firebase("https://webrtcdemo.firebaseIO.com/");
var roomRef = dbRef.child("rooms");

/**
room >
	124124 >
		candidate:A
		candidate:B
		offer
		answer
*/

function id () {
	return (Math.random() * 10000 + 10000 | 0).toString();
}

function send (room, key, data) {
	roomRef.child(room).child(key).set(data);
}

function recv (room, type, cb) {
	roomRef.child(room).child(type).on("value", function (snapshot, key) {
		var data = snapshot.val();
		if (data) { cb(data); }
	});
}

var ROOM = location.hash.substr(1);
var type = "answerer";
var otherType = "offerer";

if (!ROOM) {
	ROOM = id();
	type = "offerer";
	otherType = "answerer";
}

var ME = id();
console.log("Your ROOM", ROOM)
console.log("You are", type)

var server = {
	iceServers: [
		//{url: "stun:23.21.150.121"}
		{url: "stun:stun.l.google.com:19302"},
		//{url: "turn:turn:numb.viagenie.ca", credential: "webrtcdemo", username: "louis%40mozilla.com"}
	]
};

var options = {
	optional: [
		{DtlsSrtpKeyAgreement: true},
		{RtpDataChannels: true}
	]
}

var PeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var pc = new PeerConnection(server, options);

var SessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
var IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;

var first = false;
pc.onicecandidate = function (e) {
	// take the first candidate that isn't null
	if (first || !e.candidate) { return; }
	first = true;

	recv(ROOM, "candidate:" + otherType, function (candidate) {
		console.log("GET CANDIDATE");
		pc.addIceCandidate(new IceCandidate(JSON.parse(candidate)));
	});

	send(ROOM, "candidate:"+type, JSON.stringify(e.candidate));
};

//datachannel or audio/video?
var channel = pc.createDataChannel("RTCDataChannel", {});

pc.ondatachannel = function (e) {
	console.log("channel data on");
	var channel = e.channel;
	channel.onopen = function () { console.log("channel opened"); }
	channel.onerror = function (e) { console.log("channel error", e); }
	channel.onmessage = function (e) { console.log("channel message", e); }
	channel.onclose = function (e) { console.log("channel closed", e); }
}

var constraints = {
	mandatory: {
        OfferToReceiveAudio: true,
        OfferToReceiveVideo: true
    }
};

if (type === "offerer") {
	pc.createOffer(function (offer) {
		pc.setLocalDescription(offer);
		send(ROOM, "offer", JSON.stringify(offer));

		recv(ROOM, "answer", function (answer) {
			console.log("GOT ANSWER", answer.length);
			pc.setRemoteDescription(new SessionDescription(JSON.parse(answer)));
		});

		console.log("OFFER", offer)
	}, function (err) {
		console.error(err);
	}, constraints);

} else {
	recv(ROOM, "offer", function (offer) {
		console.log("GOT OFFER", offer.length);
		pc.setRemoteDescription(new SessionDescription(JSON.parse(offer)));

		pc.createAnswer(function (answer) {
			console.log("ANSWER", answer);
			pc.setLocalDescription(answer);

			send(ROOM, "answer", JSON.stringify(answer));
		}, function (err) {
			console.error(err);
		}, constraints);
	});
}<commit_msg>* Chrome requires the event bindings before the data connection opens<commit_after>var dbRef = new Firebase("https://webrtcdemo.firebaseIO.com/");
var roomRef = dbRef.child("rooms");

/**
room >
	124124 >
		candidate:A
		candidate:B
		offer
		answer
*/

function id () {
	return (Math.random() * 10000 + 10000 | 0).toString();
}

function send (room, key, data) {
	roomRef.child(room).child(key).set(data);
}

function recv (room, type, cb) {
	roomRef.child(room).child(type).on("value", function (snapshot, key) {
		var data = snapshot.val();
		if (data) { cb(data); }
	});
}

var ROOM = location.hash.substr(1);
var type = "answerer";
var otherType = "offerer";

if (!ROOM) {
	ROOM = id();
	type = "offerer";
	otherType = "answerer";
}

var ME = id();
console.log("Your ROOM", ROOM)
console.log("You are", type)

var server = {
	iceServers: [
		//{url: "stun:23.21.150.121"}
		{url: "stun:stun.l.google.com:19302"},
		//{url: "turn:turn:numb.viagenie.ca", credential: "webrtcdemo", username: "louis%40mozilla.com"}
	]
};

var options = {
	optional: [
		{DtlsSrtpKeyAgreement: true},
		{RtpDataChannels: true}
	]
}

var PeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var pc = new PeerConnection(server, options);

var SessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
var IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;

var first = false;
pc.onicecandidate = function (e) {
	// take the first candidate that isn't null
	if (first || !e.candidate) { return; }
	first = true;

	recv(ROOM, "candidate:" + otherType, function (candidate) {
		console.log("GET CANDIDATE", otherType);
		pc.addIceCandidate(new IceCandidate(JSON.parse(candidate)));
	});

	send(ROOM, "candidate:"+type, JSON.stringify(e.candidate));
};

//datachannel or audio/video?
var channel = pc.createDataChannel("RTCDataChannel", {});
channel.onmessage = function (e) { console.log("pre channel message", e); }

pc.ondatachannel = function (e) {
	console.log("channel data on");
	var channel = e.channel;
	channel.onopen = function () { console.log("channel opened"); }
	channel.onerror = function (e) { console.log("channel error", e); }
	channel.onmessage = function (e) { console.log("channel message", e); }
	channel.onclose = function (e) { console.log("channel closed", e); }
}

var constraints = {
	mandatory: {
        OfferToReceiveAudio: true,
        OfferToReceiveVideo: true
    }
};

if (type === "offerer") {
	pc.createOffer(function (offer) {
		pc.setLocalDescription(offer);
		send(ROOM, "offer", JSON.stringify(offer));

		recv(ROOM, "answer", function (answer) {
			console.log("GOT ANSWER", answer.length);
			pc.setRemoteDescription(new SessionDescription(JSON.parse(answer)));
		});

		console.log("OFFER", offer)
	}, function (err) {
		console.error(err);
	}, constraints);

} else {
	recv(ROOM, "offer", function (offer) {
		console.log("GOT OFFER", offer.length);
		pc.setRemoteDescription(new SessionDescription(JSON.parse(offer)));

		pc.createAnswer(function (answer) {
			console.log("ANSWER", answer);
			pc.setLocalDescription(answer);

			send(ROOM, "answer", JSON.stringify(answer));
		}, function (err) {
			console.error(err);
		}, constraints);
	});
}<|endoftext|>


<commit_before>import TokenClient from 'lib/TokenClient';
import SocketClient from 'lib/SocketClient';
import CommandDispatcher from 'lib/CommandDispatcher';

export default class Client {
  constructor({ host, isSecureConnection, eventBus }) {
    this.conf = { host, isSecureConnection, eventBus };
    this.tokenClientInstance = null;
    this.socketClientInstance = null;
  }

  commands() {
    return most.fromEvent('commands', this.conf.eventBus);
  }

  errors() {
    return most.fromEvent('error', this.conf.eventBus);
  }

  data() {
    return most.fromEvent('data', this.conf.eventBus);
  }

  id(id) {
    return this.data()
      .filter((d) => d.id === id);
  };

  type(type) {
    return this.data()
      .filter((d) => d.type === type);
  };

  tokenClient() {
    if (!this.tokenClientInstance) {
      this.tokenClientInstance = new TokenClient(this.conf)
    }

   return this.tokenClientInstance;
  }

  socketClient() {
    if (!this.socketClientInstance) {
      this.socketClientInstance = new SocketClient(this.conf);
    }

   return this.socketClientInstance;
  }

  commandDispatcher() {
    if (!this.commandDispatcherInstance) {
      const emitter = (cmd) => {
        this.connection.send({
          type: 'command',
          data: cmd
        });
      };

      this.commandDispatcher = new CommandDispatcher(emitter);
    }
    return this.commandDispatcherInstance;
  }
}
<commit_msg>Command convenience API<commit_after>import TokenClient from 'lib/TokenClient';
import SocketClient from 'lib/SocketClient';
import CommandDispatcher from 'lib/CommandDispatcher';

export default class Client {
  constructor({ host, isSecureConnection, eventBus }) {
    this.conf = { host, isSecureConnection, eventBus };
    this.tokenClientInstance = null;
    this.socketClientInstance = null;
  }

  commands() {
    return most.fromEvent('commands', this.conf.eventBus);
  }

  data() {
    return most.fromEvent('data', this.conf.eventBus);
  }

  id(id) {
    return this.data()
      .filter((d) => d.id === id);
  };

  type(type) {
    return this.data()
      .filter((d) => d.type === type);
  };

  tokenClient() {
    if (!this.tokenClientInstance) {
      this.tokenClientInstance = new TokenClient(this.conf)
    }

   return this.tokenClientInstance;
  }

  socketClient() {
    if (!this.socketClientInstance) {
      this.socketClientInstance = new SocketClient(this.conf);
    }

   return this.socketClientInstance;
  }

  commandDispatcher() {
    if (!this.commandDispatcherInstance) {
      const emitter = (cmd) => {
        this.connection.send({
          type: 'command',
          data: cmd
        });
      };

      this.commandDispatcher = new CommandDispatcher(emitter);
    }
    return this.commandDispatcherInstance;
  }

  command() {
    return this.commandDispatcher().dispatch;
  }
}
<|endoftext|>


<commit_before>var app = require('app');
var BrowserWindow = require('browser-window');
var ipc = require('ipc');
var fs = require('fs');

require('crash-reporter').start();

var mainWindow = null;

app.on('window-all-closed', function() {
  //TODO: exit when computer restart, to see what node service should do when system down?
  //app.quit();
});

app.on('ready', function() {
  mainWindow = new BrowserWindow({
	width: 1366,
	height: 768,
	show: false,
	frame: false,
	'node-integration': false,
	preload: __dirname + '/preload.js'
  });

  mainWindow.loadUrl('file://' + __dirname + '/index.html');

  //mainWindow.openDevTools();

  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});

ipc.on('WriteFile', function(event, id, test, buf){
  console.log(id);
  console.log(test);
  /*fs.writeFile(, buf.toPng(), function(err) {
    console.log("write file finished: "+Date.now());
    if(err){
      console.log(err);
    }
  });*/
});<commit_msg>for ipc test<commit_after>var app = require('app');
var BrowserWindow = require('browser-window');
var ipc = require('ipc');
var fs = require('fs');

require('crash-reporter').start();

var mainWindow = null;

app.on('window-all-closed', function() {
  //TODO: exit when computer restart, to see what node service should do when system down?
  //app.quit();
});

app.on('ready', function() {
  mainWindow = new BrowserWindow({
	width: 1366,
	height: 768,
	show: false,
	frame: false,
	'node-integration': false,
	preload: __dirname + '/preload.js'
  });

  mainWindow.loadUrl('file://' + __dirname + '/index.html');

  //mainWindow.openDevTools();

  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});

ipc.on('WriteFile', function(event, id, buf){
  console.log(id);
  console.log(buf.toDataUrl());
  /*fs.writeFile(, buf.toPng(), function(err) {
    console.log("write file finished: "+Date.now());
    if(err){
      console.log(err);
    }
  });*/
});<|endoftext|>