<commit_before>'use strict';

export default class VehicleSetUpController {
    /*@ngInject*/
    constructor($scope, $state, vehicleService, vehicleDetailsService, vehicleModelService, dealerService, $mdDialog) {
        this.$state = $state;
        this.$scope = $scope;
        this.$mdDialog = $mdDialog;
        this.vehicleService = new vehicleService();
        this.vehicleDetailService = new vehicleDetailsService();

        this.vehicle = vehicleService.query();
        this.vehicleModels = vehicleModelService.query();
        this.vehicleDetail = vehicleDetailsService.query();

        this.dealers = dealerService.query();
    }

    createVehicle(form) {
        if (form.$valid) {

            console.log('Create Vehicle');
            console.log(this.$scope);

            this.vehicleService.data = {
                vehicle_master_chassis_no: this.$scope.vehicle.chassisNo,
                vehicle_master_engine_no: this.$scope.vehicle.engineNo,
                VehicleModelId: this.$scope.vehicle.selectedVehicleModel
            };

            this.vehicleService.$save()
                .then(res => {
                    if (res.$resolved) {
                        // console.log("res saving obj");
                        // console.log(res);
                        this.vehicleDetailService.data = {
                            vehicle_detail_name: this.$scope.vehicle.details,
                            vehicle_detail_sales_date: this.$scope.vehicle.salesDate,
                            vehicle_details_import_date: this.$scope.vehicle.importDate,
                            vehicle_detail_allocated_service_date: this.$scope.vehicle.allocatedServiceDate,
                            vehicle_detail_service_date: this.$scope.vehicle.servicingDate,
                            vehicle_detail_last_grade: this.$scope.vehicle.grade,
                            vehicle_details_total_free_service: this.$scope.vehicle.freeService,
                            vehicle_detail_last_milage: this.$scope.vehicle.mileage,
                            DealerId: this.$scope.vehicle.selectedDealer,
                            VehicleMasterId: res._id
                        };
                        this.vehicleDetailService.$save()
                            .then(res => {
                                if (res.$resolved) {
                                    console.log("res saving obj");
                                    console.log(res);
                                    this.showAlert(res);
                                }
                            })
                            .catch(function (req) {
                                console.log("error saving obj");
                            })
                            .finally(function () {
                                console.log("always called")
                            });
                    }
                })
                .catch(function (req) {
                    console.log("error saving obj");
                })
                .finally(function () {
                    console.log("always called")
                });

        }
    }

    showAlert(res) {
        alert = this.$mdDialog.alert({
            title: 'vehicle has created successfully',
            textContent: '',
            ok: 'Close'
        });

        this.$mdDialog
            .show(alert)
            .finally(function () {
                alert = undefined;
            });
        this.$state.go('dealer');

    }

}
<commit_msg>vehicle creation successfull<commit_after>'use strict';

export default class VehicleSetUpController {
    /*@ngInject*/
    constructor($rootScope, $scope, $state, vehicleService, vehicleDetailsService, vehicleModelService, dealerService, $mdDialog) {
        this.$state = $state;
        this.$rootScope = $rootScope;
        this.$scope = $scope;
        this.$mdDialog = $mdDialog;
        this.vehicleService = new vehicleService();
        this.vehicleDetailService = new vehicleDetailsService();

        this.vehicle = vehicleService.query();
        this.vehicleModels = vehicleModelService.query();
        this.vehicleDetail = vehicleDetailsService.query();

        this.dealers = dealerService.query();
    }

    createVehicle(form) {
        if (form.$valid) {
            this.vehicleService.data = {
                vehicle_master_chassis_no: this.$scope.vehicle.chassisNo,
                vehicle_master_engine_no: this.$scope.vehicle.engineNo,
                VehicleModelId: this.$scope.vehicle.selectedVehicleModel
            };
            this.vehicleDetailService.data = {
                vehicle_detail_name: this.$scope.vehicle.details,
                vehicle_detail_sales_date: this.$scope.vehicle.salesDate,
                vehicle_details_import_date: this.$scope.vehicle.importDate,
                vehicle_detail_allocated_service_date: this.$scope.vehicle.allocatedServiceDate,
                vehicle_detail_service_date: this.$scope.vehicle.servicingDate,
                vehicle_detail_last_grade: this.$scope.vehicle.grade,
                vehicle_details_total_free_service: this.$scope.vehicle.freeService,
                vehicle_detail_last_milage: this.$scope.vehicle.mileage,
                DealerId: this.$scope.vehicle.selectedDealer
            };

            this.vehicleService.$save()
                .then(res => {
                    if (res.$resolved) {
                        this.vehicleDetailService.data.VehicleMasterId = res._id;
                        this.vehicleDetailService.$save()
                            .then(res => {
                                if (res.$resolved) {
                                    console.log("res saving vehicle details obj");
                                    console.log(res);
                                    this.showAlert(res);
                                }
                            })
                            .catch(function (req) {
                                console.log("error saving obj");
                            })
                            .finally(function () {
                                console.log("always called")
                            });
                    }
                })
                .catch(function (req) {
                    console.log("error saving obj");
                })
                .finally(function () {
                    console.log("always called")
                });

        }
    }

    showAlert(res) {
        alert = this.$mdDialog.alert({
            title: 'vehicle has created successfully',
            textContent: '',
            ok: 'Close'
        });

        this.$mdDialog
            .show(alert)
            .finally(function () {
                alert = undefined;
            });
        this.$state.go('vehicle');

    }

}
<|endoftext|>


<commit_before>'use strict';

angular.module('gowApp')
  .controller('NavbarCtrl', function ($scope, $location, Auth) {
    $scope.menu = [
      {'title': 'Home', 'link': '/'},
      {'title': 'Pages', 'link': '/pages'}
    ];

    $scope.isCollapsed = true;
    $scope.isLoggedIn = Auth.isLoggedIn;
    $scope.isAdmin = Auth.isAdmin;
    $scope.getCurrentUser = Auth.getCurrentUser;

    $scope.logout = function() {
      Auth.logout();
      $location.path('/login');
    };

    $scope.isActive = function(route) {
      return route === $location.path();
    };
  });
<commit_msg>showing page routes in menu<commit_after>'use strict';

angular.module('gowApp')
  .controller('NavbarCtrl', function ($scope, $location, Auth, Pages) {
    $scope.menu = [
      {'title': 'Home', 'link': '/'},
      {'title': 'Pages', 'link': '/pages'}
    ];

    // adding pages routes only if menu enabled
    var pages = Pages.query(function () {
      _.forEach(pages, function (page) {
        if (page.menu) {
          $scope.menu.push({title: page.name, link: page.route});
        }
      });
    });

    $scope.isCollapsed = true;
    $scope.isLoggedIn = Auth.isLoggedIn;
    $scope.isAdmin = Auth.isAdmin;
    $scope.getCurrentUser = Auth.getCurrentUser;

    $scope.logout = function () {
      Auth.logout();
      $location.path('/login');
    };

    $scope.isActive = function (route) {
      return route === $location.path();
    };
  });
<|endoftext|>


<commit_before>"use strict";

const debug = require("debug")("controller1");
//const moment = require("moment");

class Controller1 extends require("../lib/controller.js") {
  constructor(param) {
    super(param);
    this.errprob = 0.0001;
    this.collector=[];
        this.started = [0, 0];

    setInterval(() => {
  //    const erg = this.checkRunning(0,2E8);
  const erg = this.checkRunning(1);

      debug("longest %j %d",this.started, erg.length);
      this.parallel += erg.length;

    }, 1000).unref();

  }
  errHandler(pos, err) {
    debug("error", err, pos);

    if (pos.diff[0] > 0) {
        Object.assign(pos, {
            group: 1
        });
    } else {
        Object.assign(pos, {
            group: 0
        });
    }

    if (this.errcollector.size > 30) {
      return true;
    } else {
      return false;
    }
  }
  objHandler(pos, obj) { //add timing
    //debug("hier da",pos,obj);

    if (pos.diff[0] > 0) {
        Object.assign(pos, {
            group: 1
        });

    } else {
        Object.assign(pos, {
            group: 0
        });
    }

    this.collector[pos.input.id]=obj;

  }
  endHandler() {
    if (this.errcollector.size > 30) { //throw with error
      debug("finished with error %d", this.errcollector.size);
      this.emit("ende", [...this.errcollector]);
    } else { // return the array of results
      debug("finished with gen");
      this.emit("ende", null, this.collector);
    }

  }

  *
  dataGenerator(res) {

    const iter1 = this.makeIterator(res);

    const first = yield* this.startAll([],()=>iter1.next());

/*
    const iter2 = this.makeIteratorInp(first);
    const next= yield* this.startAll(first,()=>iter2.next(),10000);

    debug("am ende",next.length);

    const r = yield* this.waiterFinished(500000);

    debug("ganz am ende",r.length);
*/

let zahl0 = 0,
    zahl1 = 0;
for (let i = 0; i < first.length; i++) {
    if (first[i] && first[i].group === 0) {
        zahl0++;
    } else if (first[i] && first[i].group === 1) {
        zahl1++;
    }
}
debug("start wiederhol mit %d %d %d", first.length, zahl0, zahl1);

let iter = [this.makeIteratorInpG(first, 0), this.makeIteratorInpG(first, 1)];

const next = yield* this.startAll(first,(la)=>{
let next;
if ( !la){
la = {};
}
for (let i = 0; i < 2; i++) {
next = iter[la.group || 0].next();
             if (!next.done){
               this.started[la.group || 0]++;
               return next;
             } else {
               if (la.group) {
                   la = {
                       group: 0
                   };
               } else {
                   la = {
                       group: 1
                   };
               }

             }
}

  return next;
});

}

}
module.exports = Controller1;
<commit_msg>improve tests<commit_after>"use strict";

const debug = require("debug")("controller1");
//const moment = require("moment");

const co=(a)=>a?a.diff[0]*1e9+a.diff[1]:0;

class Controller1 extends require("../lib/controller.js") {
  constructor(param) {
    super(param);
    this.errprob = 0.0001;
    this.collector=[];
        this.started = [0, 0];

    setInterval(() => {
  //    const erg = this.checkRunning(0,2E8);
  const erg = this.checkRunning(1);

      debug("longest %j %d",this.started, erg.length);
      this.parallel += erg.length;

    }, 1000).unref();

  }
  errHandler(pos, err) {
    debug("error", err, pos);

    if (co(pos) > 1.63e9) {
        Object.assign(pos, {
            group: 1
        });
    } else {
        Object.assign(pos, {
            group: 0
        });
    }

    if (this.errcollector.size > 30) {
      return true;
    } else {
      return false;
    }
  }
  objHandler(pos, obj) { //add timing
    //debug("hier da",pos,obj);

    if (co(pos) > 1.63e9) {
        Object.assign(pos, {
            group: 1
        });
    } else {
        Object.assign(pos, {
            group: 0
        });
    }

    this.collector[pos.input.id]=obj;

  }
  endHandler() {
    if (this.errcollector.size > 30) { //throw with error
      debug("finished with error %d", this.errcollector.size);
      this.emit("ende", [...this.errcollector]);
    } else { // return the array of results
      debug("finished with gen");
      this.emit("ende", null, this.collector);
    }

  }

  *
  dataGenerator(res) {

    const iter1 = this.makeIterator(res);

    let first = yield* this.startAll([],()=>iter1.next());

/*
    const iter2 = this.makeIteratorInp(first);
    const next= yield* this.startAll(first,()=>iter2.next(),10000);

    debug("am ende",next.length);

    const r = yield* this.waiterFinished(500000);

    debug("ganz am ende",r.length);
*/
  const r= yield *this.waiter(3000);

  first.push(...r);

const x = Math.floor(first.length/2);

debug("vor sort %d",first.length );

    first.sort((a,b)=>co(a)-co(b));
    debug("median %d %j min %j max %j",x,first[x],first[0],first[first.length-2]);

let zahl0 = 0,
    zahl1 = 0;
for (let i = 0; i < first.length; i++) {
    if (first[i] && i<= x ) {
      first[i].group = 0;
        zahl0++;
    } else if (first[i] && i >x ) {
       first[i].group = 1;
        zahl1++;
    }
}
debug("start wiederhol mit %d %d %d", first.length, zahl0, zahl1);

let iter = [this.makeIteratorInpG(first, 0), this.makeIteratorInpG(first, 1)];

const next = yield* this.startAll(first,(la)=>{
let next;
if ( !la){
la = {};
}
for (let i = 0; i < 2; i++) {
next = iter[la.group || 0].next();
             if (!next.done){
               this.started[la.group || 0]++;
               return next;
             } else {
               if (la.group) {
                   la = {
                       group: 0
                   };
               } else {
                   la = {
                       group: 1
                   };
               }

             }
}

  return next;
});

}

}
module.exports = Controller1;
<|endoftext|>


<commit_before>// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var path = require('path');
var assert = require('assert');

exports.testDir = path.dirname(__filename);
exports.fixturesDir = path.join(exports.testDir, 'fixtures');
exports.libDir = path.join(exports.testDir, '../lib');
exports.tmpDir = path.join(exports.testDir, 'tmp');
exports.PORT = 12346;
exports.PROXY_PORT = 1234567;

if (process.platform == 'win32') {
  exports.PIPE = '\\\\.\\pipe\\libuv-test';
} else {
  exports.PIPE = exports.tmpDir + '/test.sock';
}

var util = require('util');
for (var i in util) exports[i] = util[i];
//for (var i in exports) global[i] = exports[i];

function protoCtrChain(o) {
  var result = [];
  for (; o; o = o.__proto__) { result.push(o.constructor); }
  return result.join();
}

exports.indirectInstanceOf = function(obj, cls) {
  if (obj instanceof cls) { return true; }
  var clsChain = protoCtrChain(cls.prototype);
  var objChain = protoCtrChain(obj);
  return objChain.slice(-clsChain.length) === clsChain;
};

exports.ddCommand = function(filename, kilobytes) {
  if (process.platform == 'win32') {
    return '"' + process.argv[0] + '" "' + path.resolve(exports.fixturesDir,
      'create-file.js') + '" "' + filename + '" ' + (kilobytes * 1024);
  } else {
    return 'dd if=/dev/zero of="' + filename + '" bs=1024 count=' + kilobytes;
  }
};

exports.spawnPwd = function(options) {
  var spawn = require('child_process').spawn;

  if (process.platform == 'win32') {
    return spawn('cmd.exe', ['/c', 'cd'], options);
  } else {
    return spawn('pwd', [], options);
  }
};

// Turn this off if the test should not check for global leaks.
exports.globalCheck = true;

process.on('exit', function() {
  if (!exports.globalCheck) return;
  var knownGlobals = [setTimeout,
                      setInterval,
                      clearTimeout,
                      clearInterval,
                      console,
                      Buffer,
                      process,
                      global];

  if (global.errno) {
    knownGlobals.push(errno);
  }

  if (global.gc) {
    knownGlobals.push(gc);
  }

  if (global.DTRACE_HTTP_SERVER_RESPONSE) {
    knownGlobals.push(DTRACE_HTTP_SERVER_RESPONSE);
    knownGlobals.push(DTRACE_HTTP_SERVER_REQUEST);
    knownGlobals.push(DTRACE_HTTP_CLIENT_RESPONSE);
    knownGlobals.push(DTRACE_HTTP_CLIENT_REQUEST);
    knownGlobals.push(DTRACE_NET_STREAM_END);
    knownGlobals.push(DTRACE_NET_SERVER_CONNECTION);
    knownGlobals.push(DTRACE_NET_SOCKET_READ);
    knownGlobals.push(DTRACE_NET_SOCKET_WRITE);
  }

  if (global.ArrayBuffer) {
    knownGlobals.push(ArrayBuffer);
    knownGlobals.push(Int8Array);
    knownGlobals.push(Uint8Array);
    knownGlobals.push(Int16Array);
    knownGlobals.push(Uint16Array);
    knownGlobals.push(Int32Array);
    knownGlobals.push(Uint32Array);
    knownGlobals.push(Float32Array);
    knownGlobals.push(Float64Array);
    knownGlobals.push(DataView);
  }

  for (var x in global) {
    var found = false;

    for (var y in knownGlobals) {
      if (global[x] === knownGlobals[y]) {
        found = true;
        break;
      }
    }

    if (!found) {
      console.error('Unknown global: %s', x);
      assert.ok(false, 'Unknown global found');
    }
  }
});

// This function allows one two run an HTTP test agaist both HTTPS and
// normal HTTP modules. This ensures they fit the same API.
exports.httpTest = function httpTest(cb) {
};

<commit_msg>[test] Upgrade `common.js` from node core<commit_after>// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var path = require('path');
var assert = require('assert');

exports.testDir = path.dirname(__filename);
exports.fixturesDir = path.join(exports.testDir, 'fixtures');
exports.libDir = path.join(exports.testDir, '../lib');
exports.tmpDir = path.join(exports.testDir, 'tmp');
exports.PORT = 12346;
exports.PROXY_PORT = 1234567;

if (process.platform === 'win32') {
  exports.PIPE = '\\\\.\\pipe\\libuv-test';
} else {
  exports.PIPE = exports.tmpDir + '/test.sock';
}

var util = require('util');
for (var i in util) exports[i] = util[i];
//for (var i in exports) global[i] = exports[i];

function protoCtrChain(o) {
  var result = [];
  for (; o; o = o.__proto__) { result.push(o.constructor); }
  return result.join();
}

exports.indirectInstanceOf = function(obj, cls) {
  if (obj instanceof cls) { return true; }
  var clsChain = protoCtrChain(cls.prototype);
  var objChain = protoCtrChain(obj);
  return objChain.slice(-clsChain.length) === clsChain;
};

exports.ddCommand = function(filename, kilobytes) {
  if (process.platform === 'win32') {
    var p = path.resolve(exports.fixturesDir, 'create-file.js');
    return '"' + process.argv[0] + '" "' + p + '" "' +
           filename + '" ' + (kilobytes * 1024);
  } else {
    return 'dd if=/dev/zero of="' + filename + '" bs=1024 count=' + kilobytes;
  }
};

exports.spawnPwd = function(options) {
  var spawn = require('child_process').spawn;

  if (process.platform === 'win32') {
    return spawn('cmd.exe', ['/c', 'cd'], options);
  } else {
    return spawn('pwd', [], options);
  }
};

// Turn this off if the test should not check for global leaks.
exports.globalCheck = true;

process.on('exit', function() {
  if (!exports.globalCheck) return;
  var knownGlobals = [setTimeout,
                      setInterval,
                      setImmediate,
                      clearTimeout,
                      clearInterval,
                      clearImmediate,
                      console,
                      Buffer,
                      process,
                      global];

  if (global.errno) {
    knownGlobals.push(errno);
  }

  if (global.gc) {
    knownGlobals.push(gc);
  }

  if (global.DTRACE_HTTP_SERVER_RESPONSE) {
    knownGlobals.push(DTRACE_HTTP_SERVER_RESPONSE);
    knownGlobals.push(DTRACE_HTTP_SERVER_REQUEST);
    knownGlobals.push(DTRACE_HTTP_CLIENT_RESPONSE);
    knownGlobals.push(DTRACE_HTTP_CLIENT_REQUEST);
    knownGlobals.push(DTRACE_NET_STREAM_END);
    knownGlobals.push(DTRACE_NET_SERVER_CONNECTION);
    knownGlobals.push(DTRACE_NET_SOCKET_READ);
    knownGlobals.push(DTRACE_NET_SOCKET_WRITE);
  }

  if (global.ArrayBuffer) {
    knownGlobals.push(ArrayBuffer);
    knownGlobals.push(Int8Array);
    knownGlobals.push(Uint8Array);
    knownGlobals.push(Uint8ClampedArray);
    knownGlobals.push(Int16Array);
    knownGlobals.push(Uint16Array);
    knownGlobals.push(Int32Array);
    knownGlobals.push(Uint32Array);
    knownGlobals.push(Float32Array);
    knownGlobals.push(Float64Array);
    knownGlobals.push(DataView);
  }

  for (var x in global) {
    var found = false;

    for (var y in knownGlobals) {
      if (global[x] === knownGlobals[y]) {
        found = true;
        break;
      }
    }

    if (!found) {
      console.error('Unknown global: %s', x);
      assert.ok(false, 'Unknown global found');
    }
  }
});

var mustCallChecks = [];

function runCallChecks() {
  var failed = mustCallChecks.filter(function(context) {
    return context.actual !== context.expected;
  });

  failed.forEach(function(context) {
    console.log('Mismatched %s function calls. Expected %d, actual %d.',
                context.name,
                context.expected,
                context.actual);
    console.log(context.stack.split('\n').slice(2).join('\n'));
  });

  if (failed.length) process.exit(1);
}

exports.mustCall = function(fn, expected) {
  if (typeof expected !== 'number') expected = 1;

  var context = {
    expected: expected,
    actual: 0,
    stack: (new Error).stack,
    name: fn.name || '<anonymous>'
  };

  // add the exit listener only once to avoid listener leak warnings
  if (mustCallChecks.length === 0) process.on('exit', runCallChecks);

  mustCallChecks.push(context);

  return function() {
    context.actual++;
    return fn.apply(this, arguments);
  };
};
<|endoftext|>


<commit_before>/***** BEGIN LICENSE BLOCK ***** {{{
Version: MPL 1.1/GPL 2.0/LGPL 2.1

The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.

(c) 2006-2007: Martin Stubenschrott <stubenschrott@gmx.net>

Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/

vimperator.modes = (function()
{
    var main = 1;     // NORMAL
    var extended = 0; // NONE

    var passNextKey = false;
    var passAllKeys = false;

    function getModeMessage()
    {
        if (passNextKey && !passAllKeys)
            return "PASS THROUGH (next)";
        else if (passAllKeys && !passNextKey)
            return "PASS THROUGH";

        var ext = "";
        switch (extended)
        {
            case vimperator.modes.QUICK_HINT:
                ext = " (quick)"; break;
            case vimperator.modes.EXTENDED_HINT:
                ext = " (extended)"; break;
            case vimperator.modes.ALWAYS_HINT:
                ext = " (always)"; break;
            case vimperator.modes.MENU: // TODO: desirable?
                ext = " (menu)"; break;
        }

        switch (main)
        {
            case vimperator.modes.INSERT:
                return "INSERT" + ext;
            case vimperator.modes.VISUAL:
                return (extended & vimperator.modes.LINE) ? "VISUAL LINE" + ext : "VISUAL" + ext;
            case vimperator.modes.HINTS:
                return "HINTS" + ext;
            case vimperator.modes.CARET:
                return "CARET" + ext;
            case vimperator.modes.TEXTAREA:
                return "TEXTAREA" + ext;
            default:
                return null;
        }
    }

    function handleModeChange(oldmode, newmode)
    {
        vimperator.log("switching from mode " + oldmode + " to mode " + newmode, 7);

        switch (oldmode)
        {
            case vimperator.modes.TEXTAREA:
            case vimperator.modes.INSERT:
                vimperator.editor.unselectText();
                break;

            case vimperator.modes.VISUAL:
                if (newmode == vimperator.modes.CARET)
                {
                    // clear any selection made
                    var selection = window.content.getSelection();
                    try { // a simple if (selection) does not work
                        selection.collapseToStart();
                    } catch (e) { }
                }
                else
                    vimperator.editor.unselectText();
                break;

            case vimperator.modes.HINTS:
                // XXX: for now this does not work, but later it should be here
                // vimperator.hints.disableHahMode();
                break;
        }

        if (newmode == vimperator.modes.NORMAL)
        {
            var value = Options.getFirefoxPref("accessibility.browsewithcaret", false);
            if (value)
                Options.setFirefoxPref("accessibility.browsewithcaret", false);

            vimperator.statusline.updateUrl();
            vimperator.focusContent();
        }
    }

    return {
        // main modes, only one should ever be active
        NONE:             0,
        NORMAL:           1 << 0,
        INSERT:           1 << 1,
        VISUAL:           1 << 2,
        HINTS:            1 << 3,
        COMMAND_LINE:     1 << 4,
        CARET:            1 << 5, // text cursor is visible
        TEXTAREA:         1 << 6, // text cursor is in a HTMLTextAreaElement
        // extended modes, can include multiple modes, and even main modes
        EX:               1 << 10,
        INPUT_MULTILINE:  1 << 11,
        OUTPUT_MULTILINE: 1 << 12,
        SEARCH_FORWARD:   1 << 13,
        SEARCH_BACKWARD:  1 << 14,
        QUICK_HINT:       1 << 15,
        EXTENDED_HINT:    1 << 16,
        ALWAYS_HINT:      1 << 17,
        MENU:             1 << 18, // a popupmenu is active
        LINE:             1 << 19, // linewise visual mode

        reset: function(silent)
        {
            this.set(vimperator.modes.NORMAL, vimperator.modes.NONE, silent);
        },

        show: function()
        {
            if (!vimperator.options["showmode"])
                return;

            // never show mode messages if we are in command line mode
            if (main == vimperator.modes.COMMAND_LINE)
                return;

            var msg = getModeMessage();
            if (msg)
                vimperator.commandline.echo("-- " + getModeMessage() + " --");
            else
                vimperator.commandline.echo("");
        },

        // helper function to set both modes in one go
        set: function(main_mode, extended_mode, silent)
        {
            // if a main mode is set, the extended is always cleared
            if (typeof main_mode === "number")
            {
                if (main_mode != main)
                    handleModeChange(main, main_mode);

                main = main_mode;
                if (!extended_mode)
                    extended = vimperator.modes.NONE;

            }
            if (typeof extended_mode === "number")
                extended = extended_mode;

            if (!silent)
                this.show();
        },

        // add/remove always work on the extended mode only
        add: function(mode)
        {
            extended |= mode;
            this.show();
        },
        remove: function(mode)
        {
            extended = (extended | mode) ^ mode;
            this.show();
        },

        get passNextKey() { return passNextKey; },
        set passNextKey(value) { passNextKey = value; this.show(); },

        get passAllKeys() { return passAllKeys; },
        set passAllKeys(value) { passAllKeys = value; this.show(); },

        get main()      { return main; },
        set main(value) {
            if (value != main)
                handleModeChange(main, value);

            main = value;
            // setting the main mode always resets any extended mode
            extended = vimperator.modes.NONE;
            this.show();
        },

        get extended()      { return extended; },
        set extended(value) {
            extended = value; this.show();
        }
    }
})();

// vim: set fdm=marker sw=4 ts=4 et:
<commit_msg>use hl-ModeMsg for highlighting mode messages<commit_after>/***** BEGIN LICENSE BLOCK ***** {{{
Version: MPL 1.1/GPL 2.0/LGPL 2.1

The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.

(c) 2006-2007: Martin Stubenschrott <stubenschrott@gmx.net>

Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/

vimperator.modes = (function()
{
    var main = 1;     // NORMAL
    var extended = 0; // NONE

    var passNextKey = false;
    var passAllKeys = false;

    function getModeMessage()
    {
        if (passNextKey && !passAllKeys)
            return "PASS THROUGH (next)";
        else if (passAllKeys && !passNextKey)
            return "PASS THROUGH";

        var ext = "";
        switch (extended)
        {
            case vimperator.modes.QUICK_HINT:
                ext = " (quick)"; break;
            case vimperator.modes.EXTENDED_HINT:
                ext = " (extended)"; break;
            case vimperator.modes.ALWAYS_HINT:
                ext = " (always)"; break;
            case vimperator.modes.MENU: // TODO: desirable?
                ext = " (menu)"; break;
        }

        switch (main)
        {
            case vimperator.modes.INSERT:
                return "INSERT" + ext;
            case vimperator.modes.VISUAL:
                return (extended & vimperator.modes.LINE) ? "VISUAL LINE" + ext : "VISUAL" + ext;
            case vimperator.modes.HINTS:
                return "HINTS" + ext;
            case vimperator.modes.CARET:
                return "CARET" + ext;
            case vimperator.modes.TEXTAREA:
                return "TEXTAREA" + ext;
            default:
                return null;
        }
    }

    function handleModeChange(oldmode, newmode)
    {
        vimperator.log("switching from mode " + oldmode + " to mode " + newmode, 7);

        switch (oldmode)
        {
            case vimperator.modes.TEXTAREA:
            case vimperator.modes.INSERT:
                vimperator.editor.unselectText();
                break;

            case vimperator.modes.VISUAL:
                if (newmode == vimperator.modes.CARET)
                {
                    // clear any selection made
                    var selection = window.content.getSelection();
                    try { // a simple if (selection) does not work
                        selection.collapseToStart();
                    } catch (e) { }
                }
                else
                    vimperator.editor.unselectText();
                break;

            case vimperator.modes.HINTS:
                // XXX: for now this does not work, but later it should be here
                // vimperator.hints.disableHahMode();
                break;
        }

        if (newmode == vimperator.modes.NORMAL)
        {
            var value = Options.getFirefoxPref("accessibility.browsewithcaret", false);
            if (value)
                Options.setFirefoxPref("accessibility.browsewithcaret", false);

            vimperator.statusline.updateUrl();
            vimperator.focusContent();
        }
    }

    return {
        // main modes, only one should ever be active
        NONE:             0,
        NORMAL:           1 << 0,
        INSERT:           1 << 1,
        VISUAL:           1 << 2,
        HINTS:            1 << 3,
        COMMAND_LINE:     1 << 4,
        CARET:            1 << 5, // text cursor is visible
        TEXTAREA:         1 << 6, // text cursor is in a HTMLTextAreaElement
        // extended modes, can include multiple modes, and even main modes
        EX:               1 << 10,
        INPUT_MULTILINE:  1 << 11,
        OUTPUT_MULTILINE: 1 << 12,
        SEARCH_FORWARD:   1 << 13,
        SEARCH_BACKWARD:  1 << 14,
        QUICK_HINT:       1 << 15,
        EXTENDED_HINT:    1 << 16,
        ALWAYS_HINT:      1 << 17,
        MENU:             1 << 18, // a popupmenu is active
        LINE:             1 << 19, // linewise visual mode

        reset: function(silent)
        {
            this.set(vimperator.modes.NORMAL, vimperator.modes.NONE, silent);
        },

        show: function()
        {
            if (!vimperator.options["showmode"])
                return;

            // never show mode messages if we are in command line mode
            if (main == vimperator.modes.COMMAND_LINE)
                return;

            var msg = getModeMessage();
            if (msg)
                vimperator.commandline.echo("-- " + getModeMessage() + " --", vimperator.commandline.HL_MODEMSG);
            else
                vimperator.commandline.echo("");
        },

        // helper function to set both modes in one go
        set: function(main_mode, extended_mode, silent)
        {
            // if a main mode is set, the extended is always cleared
            if (typeof main_mode === "number")
            {
                if (main_mode != main)
                    handleModeChange(main, main_mode);

                main = main_mode;
                if (!extended_mode)
                    extended = vimperator.modes.NONE;

            }
            if (typeof extended_mode === "number")
                extended = extended_mode;

            if (!silent)
                this.show();
        },

        // add/remove always work on the extended mode only
        add: function(mode)
        {
            extended |= mode;
            this.show();
        },
        remove: function(mode)
        {
            extended = (extended | mode) ^ mode;
            this.show();
        },

        get passNextKey() { return passNextKey; },
        set passNextKey(value) { passNextKey = value; this.show(); },

        get passAllKeys() { return passAllKeys; },
        set passAllKeys(value) { passAllKeys = value; this.show(); },

        get main()      { return main; },
        set main(value) {
            if (value != main)
                handleModeChange(main, value);

            main = value;
            // setting the main mode always resets any extended mode
            extended = vimperator.modes.NONE;
            this.show();
        },

        get extended()      { return extended; },
        set extended(value) {
            extended = value; this.show();
        }
    }
})();

// vim: set fdm=marker sw=4 ts=4 et:
<|endoftext|>


<commit_before>var path = require('path'),
    sys = require('sys'),
    assert = require('assert'),
    events = require('events'),
    http = require('http');

require.paths.unshift(path.join(__dirname, '..', 'lib'),
                      path.join(__dirname, 'vendor', 'vows', 'lib'));

var vows = require('vows'),
    cradle = require('cradle');

vows.options.Emitter = cradle.Promise;

function status(code) {
    return function (res) {
        assert.equal(res._headers.status, code);
    };
}

var client = http.createClient(5984, '127.0.0.1');

function r(method, url, doc) {
    var promise = new(events.Promise);
    var request = client.request(method, url, {});

    if (doc) { request.sendBody(JSON.stringify(doc)) }

    request.finish(function (res) {
        var body = '';

        res.setBodyEncoding('utf8');
        res.addListener('body', function (chunk) {
            body += (chunk || '');
        }).addListener('complete', function () {
            var obj, response;

            try { obj = JSON.parse(body) }
            catch (e) { return promise.emitError(e) }

            promise.emitSuccess(obj);
        });
    });
    return promise;
}

vows.tell("Cradle", {
    setup: function () {
        r('GET', '/_all_dbs').wait().forEach(function (db) {
            r('DELETE', '/' + db).wait();
        });
        r('PUT', '/rabbits');
        r('PUT', '/pigs').wait();
        r('PUT', '/pigs/_design/pigs', {
            _id: '_design/pigs', views: {
                all: { map: "function (doc) { if (doc.color) emit(null, doc) }" }
            }
        });
        r('PUT', '/pigs/mike', {color: 'pink'});
        r('PUT', '/pigs/bill', {color: 'blue'}).wait();
    },
    "Default connection settings": {
        setup: function () {
            cradle.setup({
                host: "http://cloudhead.io",
                port: 4242,
                milk: 'white'
            });
            return new(cradle.Connection);
        },
        "should be carried on to new Connections": function (c) {
            assert.equal(c.host, "http://cloudhead.io");
            assert.equal(c.port, 4242);
            assert.equal(c.options.milk, 'white');
            assert.equal(c.options.cache, true);
        },
        "with just a {} passed to a new Connection object": {
            setup: function () { return new(cradle.Connection)({milk: 'green'}) },
            "should override the defaults": function (c) {
                assert.equal(c.options.milk, 'green');
                assert.equal(c.port, 4242);
            }
        },
        "with a host and port passed to Connection": {
            setup: function () { return new(cradle.Connection)("255.255.0.0", 9696) },
            "should override the defaults": function (c) {
                assert.equal(c.host, '255.255.0.0');
                assert.equal(c.port, 9696);
            }
        },
        "with a host and port passed as a string to Connection": {
            setup: function () { return new(cradle.Connection)("8.8.8.8:4141") },
            "should override the defaults": function (c) {
                assert.equal(c.host, '8.8.8.8');
                assert.equal(c.port, 4141);
            }
        },
        "with a host, port and options passed to Connection": {
            setup: function () { return new(cradle.Connection)("4.4.4.4", 911, {raw: true}) },
            "should override the defaults": function (c) {
                assert.equal(c.host, '4.4.4.4');
                assert.equal(c.port, 911);
                assert.equal(c.options.raw, true);
            }
        }
    },
    "A Cradle connection": {
        setup: function () {
            return new(cradle.Connection)('127.0.0.1', 5984, {cache: false});
        },
        "queried for information": {
            setup: function (c) { return c.info() },

            "returns a 200": status(200),
            "returns the version number": function (info) {
                //sys.debug(sys.inspect(info))
                assert.ok(info);
                assert.match(info.version, /\d+\.\d+\.\d+/);
            }
        },
        "getting the list of databases": {
            setup: function (c) { return c.databases() },
            "returns an empty list": function (dbs) {
                assert.equal(dbs.length, 2);
                assert.ok(dbs instanceof Array);
            }
        },
        "create()": {
            setup: function (c) { return c.database('badgers').create() },
            "returns a 201": status(201),
            "creates a database": {
                setup: function (res, c) { return c.database('badgers').exists() },
                "it exists": function (res) { assert.ok(res) }
            }
        },
        "destroy()": {
            setup: function (c) { return c.database('rabbits').destroy() },
            "returns a 200": status(200),
            "destroys a database": {
                setup: function (res, c) { return c.database('rabbits').exists() },
                "it doesn't exist anymore": function (res) { assert.ok(! res) }
            }
        },
        "a database": {
            setup: function (c) { return c.database('pigs') },

            "info()": {
                setup: function (db) { return db.info() },
                "returns a 200": status(200),
                "returns database info": function (info) {
                    assert.equal(info['db_name'], 'pigs');
                }
            },
            "fetching a document by id (GET)": {
                setup: function (db) { return db.get('mike') },
                "returns a 200": status(200),
                "returns the document": function (res) {
                    assert.equal(res.id, 'mike');
                }
            },
            "inserting a document": {
                "with an id (PUT)": {
                    setup: function (db) {
                        return db.save('joe', {gender: 'male'});
                    },
                    "returns a 201": status(201),
                    "returns the revision": function (res) {
                        assert.ok(res.rev);
                    }
                },
                "without an id (POST)": {}
            },
            "bulk inserting documents": {
            },
            "getting all documents": {
                setup: function (db) {
                    return db.all();
                },
                "returns a 200": status(200),
                "returns a list of all docs": function (res) {
                    assert.ok(res.rows);
                }
            },
            "updating a document (PUT)": {
                setup: function (db) {
                    var promise = new(events.Promise);
                    db.get('mike').addCallback(function (doc) {
                        db.save('mike', doc.rev,
                            {color: doc.color, age: 13}).addCallback(function (res) {
                            promise.emitSuccess(res);
                        });
                    });
                    return promise;
                },
                "returns a 201": status(201),
                "returns the revision": function (res) {
                    assert.ok(res.rev);
                    assert.match(res.rev, /^2/);
                },

                "returns the updated document": function (res) {
                    //assert.equal(res.age, 13);
                }
            },
            "deleting a document (DELETE)": {
                setup: function (db) {
                    var promise = new(events.Promise);
                    db.get('bill').addCallback(function (res) {
                        db.remove('bill', res.rev).addCallback(function (res) {
                            promise.emitSuccess(res);
                        });
                    });
                    return promise;
                },
                "returns a 200": status(200)
            },
            "querying a view": {
                setup: function (db) {
                    return db.view('pigs/all');
                },
                "returns a 200": status(200),
                "returns view results": function (res) {
                    assert.ok(res.rows);
                    assert.equal(res.rows.length, 2);
                },
                "with options": {

                },
                "with a start & end key": {

                }
            }
        }
    }
});
<commit_msg>tests for _bulk_docs insert<commit_after>var path = require('path'),
    sys = require('sys'),
    assert = require('assert'),
    events = require('events'),
    http = require('http');

require.paths.unshift(path.join(__dirname, '..', 'lib'),
                      path.join(__dirname, 'vendor', 'vows', 'lib'));

var vows = require('vows'),
    cradle = require('cradle');

vows.options.Emitter = cradle.Promise;

function status(code) {
    return function (res) {
        assert.equal(res._headers.status, code);
    };
}

var client = http.createClient(5984, '127.0.0.1');

function r(method, url, doc) {
    var promise = new(events.Promise);
    var request = client.request(method, url, {});

    if (doc) { request.sendBody(JSON.stringify(doc)) }

    request.finish(function (res) {
        var body = '';

        res.setBodyEncoding('utf8');
        res.addListener('body', function (chunk) {
            body += (chunk || '');
        }).addListener('complete', function () {
            var obj, response;

            try { obj = JSON.parse(body) }
            catch (e) { return promise.emitError(e) }

            promise.emitSuccess(obj);
        });
    });
    return promise;
}

vows.tell("Cradle", {
    setup: function () {
        r('GET', '/_all_dbs').wait().forEach(function (db) {
            r('DELETE', '/' + db).wait();
        });
        r('PUT', '/rabbits');
        r('PUT', '/pigs').wait();
        r('PUT', '/pigs/_design/pigs', {
            _id: '_design/pigs', views: {
                all: { map: "function (doc) { if (doc.color) emit(null, doc) }" }
            }
        });
        r('PUT', '/pigs/mike', {color: 'pink'});
        r('PUT', '/pigs/bill', {color: 'blue'}).wait();
    },
    "Default connection settings": {
        setup: function () {
            cradle.setup({
                host: "http://cloudhead.io",
                port: 4242,
                milk: 'white'
            });
            return new(cradle.Connection);
        },
        "should be carried on to new Connections": function (c) {
            assert.equal(c.host, "http://cloudhead.io");
            assert.equal(c.port, 4242);
            assert.equal(c.options.milk, 'white');
            assert.equal(c.options.cache, true);
        },
        "with just a {} passed to a new Connection object": {
            setup: function () { return new(cradle.Connection)({milk: 'green'}) },
            "should override the defaults": function (c) {
                assert.equal(c.options.milk, 'green');
                assert.equal(c.port, 4242);
            }
        },
        "with a host and port passed to Connection": {
            setup: function () { return new(cradle.Connection)("255.255.0.0", 9696) },
            "should override the defaults": function (c) {
                assert.equal(c.host, '255.255.0.0');
                assert.equal(c.port, 9696);
            }
        },
        "with a host and port passed as a string to Connection": {
            setup: function () { return new(cradle.Connection)("8.8.8.8:4141") },
            "should override the defaults": function (c) {
                assert.equal(c.host, '8.8.8.8');
                assert.equal(c.port, 4141);
            }
        },
        "with a host, port and options passed to Connection": {
            setup: function () { return new(cradle.Connection)("4.4.4.4", 911, {raw: true}) },
            "should override the defaults": function (c) {
                assert.equal(c.host, '4.4.4.4');
                assert.equal(c.port, 911);
                assert.equal(c.options.raw, true);
            }
        }
    },
    "A Cradle connection": {
        setup: function () {
            return new(cradle.Connection)('127.0.0.1', 5984, {cache: false});
        },
        "queried for information": {
            setup: function (c) { return c.info() },

            "returns a 200": status(200),
            "returns the version number": function (info) {
                //sys.debug(sys.inspect(info))
                assert.ok(info);
                assert.match(info.version, /\d+\.\d+\.\d+/);
            }
        },
        "getting the list of databases": {
            setup: function (c) { return c.databases() },
            "returns an empty list": function (dbs) {
                assert.equal(dbs.length, 2);
                assert.ok(dbs instanceof Array);
            }
        },
        "create()": {
            setup: function (c) { return c.database('badgers').create() },
            "returns a 201": status(201),
            "creates a database": {
                setup: function (res, c) { return c.database('badgers').exists() },
                "it exists": function (res) { assert.ok(res) }
            }
        },
        "destroy()": {
            setup: function (c) { return c.database('rabbits').destroy() },
            "returns a 200": status(200),
            "destroys a database": {
                setup: function (res, c) { return c.database('rabbits').exists() },
                "it doesn't exist anymore": function (res) { assert.ok(! res) }
            }
        },
        "a database": {
            setup: function (c) { return c.database('pigs') },

            "info()": {
                setup: function (db) { return db.info() },
                "returns a 200": status(200),
                "returns database info": function (info) {
                    assert.equal(info['db_name'], 'pigs');
                }
            },
            "fetching a document by id (GET)": {
                setup: function (db) { return db.get('mike') },
                "returns a 200": status(200),
                "returns the document": function (res) {
                    assert.equal(res.id, 'mike');
                }
            },
            "inserting a document": {
                "with an id (PUT)": {
                    setup: function (db) {
                        return db.save('joe', {gender: 'male'});
                    },
                    "returns a 201": status(201),
                    "returns the revision": function (res) {
                        assert.ok(res.rev);
                    }
                },
                "without an id (POST)": {}
            },
            "calling save() with an array": {
                setup: function (db) {
                    return db.save([{_id: 'tom'}, {_id: 'flint'}]);
                },
                "returns an array of document ids and revs": function (res) {
                    assert.equal(res[0].id, 'tom');
                    assert.equal(res[1].id, 'flint');
                },
                "should bulk insert the documents": {
                    setup: function (res, db) {
                        var promise = new(events.Promise);
                        db.get('tom')(function (tom) {
                            db.get('flint')(function (flint) {
                                promise.emitSuccess(tom, flint);
                            });
                        });
                        return promise;
                    },
                    "which can then be retrieved": function (tom, flint) {
                        assert.ok(tom._id);
                        assert.ok(flint._id);
                    }
                }
            },
            "getting all documents": {
                setup: function (db) {
                    return db.all();
                },
                "returns a 200": status(200),
                "returns a list of all docs": function (res) {
                    assert.ok(res.rows);
                }
            },
            "updating a document (PUT)": {
                setup: function (db) {
                    var promise = new(events.Promise);
                    db.get('mike').addCallback(function (doc) {
                        db.save('mike', doc.rev,
                            {color: doc.color, age: 13}).addCallback(function (res) {
                            promise.emitSuccess(res);
                        });
                    });
                    return promise;
                },
                "returns a 201": status(201),
                "returns the revision": function (res) {
                    assert.ok(res.rev);
                    assert.match(res.rev, /^2/);
                },

                "returns the updated document": function (res) {
                    //assert.equal(res.age, 13);
                }
            },
            "deleting a document (DELETE)": {
                setup: function (db) {
                    var promise = new(events.Promise);
                    db.get('bill').addCallback(function (res) {
                        db.remove('bill', res.rev).addCallback(function (res) {
                            promise.emitSuccess(res);
                        });
                    });
                    return promise;
                },
                "returns a 200": status(200)
            },
            "querying a view": {
                setup: function (db) {
                    return db.view('pigs/all');
                },
                "returns a 200": status(200),
                "returns view results": function (res) {
                    assert.ok(res.rows);
                    assert.equal(res.rows.length, 2);
                },
                "with options": {

                },
                "with a start & end key": {

                }
            }
        }
    }
});
<|endoftext|>


<commit_before>import { importHtml, importOnCall, ajax, createMsaBox, initMsaBox, exportMsaBox, editMsaBox, forEachDeepMsaBox } from "/utils/msa-utils.js"

const popupSrc = "/utils/msa-utils-popup.js"
const addPopup = importOnCall(popupSrc, "addPopup")

importHtml(`<style>
	msa-page {
        margin: .5em;
        display: flex;
        flex-direction: column;
		flex: 1;
    }
    msa-page .msa-page-box:hover,
    msa-page .msa-page-box.msa-page-editing {
        box-shadow: 2px 2px 10px grey;
    }
</style>`)

export class HTMLMsaPageElement extends HTMLElement {

    getBaseUrl() {
        return "/page"
    }
    getId() {
        return this.getAttribute("page-id")
    }
    isEditable() {
        return (this.getAttribute("editable") == "true")
    }
    toFetch() {
        return (this.getAttribute("fetch") !== "false")
    }

    async connectedCallback() {
        this.editing = false
        if (this.toFetch())
            await this.getPage()
        // dynamically import msa-page-menu
        //if (this.isEditable())
        //    importHtml({ wel: '/page/msa-page-menu.js' }, this)
        this.initAddButtons()
    }

    initAddButtons() {
        const addBut = this.createAddButton()
        this.appendChild(addBut)
    }

    createAddButton() {
        const addBut = document.createElement("button")
        addBut.classList.add("msa-page-editor")
        addBut.textContent = "Add"
        addBut.onclick = async () => {
            await import("/utils/msa-utils-boxes-menu.js")
            const popup = await addPopup(this, document.createElement("msa-utils-boxes-menu"))
            popup.content.onSelect = async tag => {
                popup.remove()
                const box = await createMsaBox(tag, {
                    parent: this,
                    boxesRoute: `${this.getBaseUrl()}/${this.getId()}/_box`
                })
                await this.initMsaBox(box)
                this.insertBefore(box, addBut)
                this.postPage()
            }
        }
        return addBut
    }

    async initMsaBox(el) {
        await initMsaBox(el, { boxesRoute: `${this.getBaseUrl()}/${this.getId()}/_box` })
        await forEachDeepMsaBox(el, box => {
            box.classList.add("msa-page-box")
            box.addEventListener("click", () => this.editMsaBox(box))
            box.addEventListener("blur", () => this.stopEditMsaBox(box))
        })
    }

    async editMsaBox(box) {
        if (box === this.editingBox) return
        if (this.editingBox) this.stopEditMsaBox(this.editingBox)
        this.editingBox = box
        box.msaPageContentBeforeEdition = (await exportMsaBox(box)).outerHTML
        box.classList.add("msa-page-editing")
        editMsaBox(box, true)
    }

    async stopEditMsaBox(box) {
        if (box !== this.editingBox) return
        delete this.editingBox
        box.classList.remove("msa-page-editing")
        await editMsaBox(box, false)
        const content = (await exportMsaBox(box)).outerHTML
        if (content != box.msaPageContentBeforeEdition)
            this.postPage()
        delete box.msaPageContentBeforeEdition
    }

    async getPage() {
        const page = await ajax("GET", `${this.getBaseUrl()}/${this.getId()}/_page`)
        const template = document.createElement("template")
        template.innerHTML = page.content || ""
        await this.initMsaBox(template.content)
        this.appendChild(template.content)
        this.setAttribute("editable", page.editable || false)
    }

    async postPage() {
        const tmpl = await exportMsaBox(this.children)
        for (let ed of tmpl.content.querySelectorAll(".msa-page-editor"))
            ed.remove()
        for (let box of tmpl.content.querySelectorAll(".msa-page-box"))
            box.classList.remove("msa-page-box")
        await ajax("POST", `${this.getBaseUrl()}/${this.getId()}/_page`, {
            body: { content: tmpl.innerHTML }
        })
    }
}

// register elem
customElements.define("msa-page", HTMLMsaPageElement)

// register editable element
export class HTMLMsaPageTextElement extends HTMLElement {
    initContent() {
        for (let c of this.children)
            if (c.classList.contains("content"))
                return c
        const res = document.createElement("div")
        res.classList.add("content")
        res.style.flex = 1
        this.appendChild(res)
        return res
    }
}
customElements.define("msa-page-text", HTMLMsaPageTextElement)

export class HTMLMsaPageBoxesElement extends HTMLElement { }
customElements.define("msa-page-boxes", HTMLMsaPageBoxesElement)<commit_msg>Add box with lines<commit_after>import { importHtml, importOnCall, ajax, createMsaBox, initMsaBox, exportMsaBox, editMsaBox, forEachDeepMsaBox } from "/utils/msa-utils.js"

const addPopup = importOnCall("/utils/msa-utils-popup.js", "addPopup")
const setPositionRelativeTo = importOnCall("/utils/msa-utils-position.js", "setPositionRelativeTo")

importHtml(`<style>
	msa-page {
        margin: .5em;
        display: flex;
        flex-direction: column;
		flex: 1;
    }

    msa-page .msa-page-line {
        display: flex;
        flex-direction: row;
    }

    msa-page .msa-page-box:hover,
    msa-page .msa-page-box.msa-page-editing {
        box-shadow: 2px 2px 10px grey;
    }

    msa-page .msa-page-first-add-btn {
        display: block;
        height: 3em;
        background: white;
        background-image: url('/utils/img/add');
        background-size: 1.5em;
        background-repeat: no-repeat;
        background-position: center;
        border: 2px dashed black;
        border-radius: .5em;
        cursor: pointer;
    }

    msa-page .msa-page-box-add-btn {
        display: block;
        position: absolute;
        width: 3em;
        height: 3em;
        background: white;
        background-image: url('/utils/img/add');
        background-size: 80%;
        background-repeat: no-repeat;
        background-position: center;
        box-shadow: 1px 1px 5px grey;
        border-radius: 1em;
        cursor: pointer;
    }
    msa-page .msa-page-box-add-btn:hover {
        box-shadow: 1px 1px 5px black;
    }
</style>`)

export class HTMLMsaPageElement extends HTMLElement {

    getBaseUrl() {
        return "/page"
    }
    getId() {
        return this.getAttribute("page-id")
    }
    isEditable() {
        return (this.getAttribute("editable") == "true")
    }
    toFetch() {
        return (this.getAttribute("fetch") !== "false")
    }

    async connectedCallback() {
        this.editing = false
        if (this.toFetch())
            await this.getPage()
        // dynamically import msa-page-menu
        //if (this.isEditable())
        //    importHtml({ wel: '/page/msa-page-menu.js' }, this)
        this.initFirstAddButtons()
    }

    initFirstAddButtons() {
        if(this.querySelectorAll(".msa-page-line").length === 0) {
            const btnEl = document.createElement("div")
            btnEl.classList.add("msa-page-first-add-btn", "msa-page-editor")
            this.initAddButton(btnEl, newBoxEl => {
                insertBefore(this.createLine(newBoxEl), btnEl)
                btnEl.remove()
            })
            this.appendChild(btnEl)
        }
    }

    initAddButton(addBtn, insertBoxFn) {
        addBtn.onclick = async () => {
            await import("/utils/msa-utils-boxes-menu.js")
            const popup = await addPopup(this, document.createElement("msa-utils-boxes-menu"))
            popup.content.onSelect = async tag => {
                popup.remove()
                const box = await createMsaBox(tag, {
                    parent: this,
                    boxesRoute: `${this.getBaseUrl()}/${this.getId()}/_box`
                })
                await this.initMsaBox(box)
                insertBoxFn(box)
                this.postPage()
            }
        }
    }

    async initMsaBox(el) {
        await initMsaBox(el, { boxesRoute: `${this.getBaseUrl()}/${this.getId()}/_box` })
        await forEachDeepMsaBox(el, box => {
            box.classList.add("msa-page-box")
            box.addEventListener("click", () => this.editMsaBox(box))
            box.addEventListener("blur", () => this.stopEditMsaBox(box))
            box.addEventListener("mouseenter", () => this.addBoxAddButtons(box))
            box.addEventListener("mouseleave", () => this.rmBoxAddButtons(box))
        })
    }

    addBoxAddButtons(boxEl) {
        const lineEl = boxEl.parentNode
        const addBtn = (posX, posY, onNewBox) => {
            const btnEl = document.createElement("button")
            btnEl.classList.add("msa-page-box-add-btn", "msa-page-editor")
            setPositionRelativeTo(btnEl, boxEl, posX, posY)
            boxEl.appendChild(btnEl)
            this.initAddButton(btnEl, onNewBox)
        }
        addBtn("left", "center", newBoxEl => insertBefore(newBoxEl, boxEl))
        addBtn("right", "center", newBoxEl => insertAfter(newBoxEl, boxEl))
        addBtn("center", "top", newBoxEl => insertBefore(this.createLine(newBoxEl), lineEl))
        addBtn("center", "bottom", newBoxEl => insertAfter(this.createLine(newBoxEl), lineEl))
    }

    rmBoxAddButtons(box) {
        box.querySelectorAll(".msa-page-box-add-btn").forEach(b => b.remove())
    }

    createLine(box) {
        const lineEl = document.createElement("div")
        lineEl.classList.add("msa-page-line")
        lineEl.appendChild(box)
        return lineEl
    }

    async editMsaBox(box) {
        if (box === this.editingBox) return
        if (this.editingBox) this.stopEditMsaBox(this.editingBox)
        this.editingBox = box
        box.msaPageContentBeforeEdition = (await exportMsaBox(box)).outerHTML
        box.classList.add("msa-page-editing")
        editMsaBox(box, true)
    }

    async stopEditMsaBox(box) {
        if (box !== this.editingBox) return
        delete this.editingBox
        box.classList.remove("msa-page-editing")
        await editMsaBox(box, false)
        const content = (await exportMsaBox(box)).outerHTML
        if (content != box.msaPageContentBeforeEdition)
            this.postPage()
        delete box.msaPageContentBeforeEdition
    }

    async getPage() {
        const page = await ajax("GET", `${this.getBaseUrl()}/${this.getId()}/_page`)
        const template = document.createElement("template")
        template.innerHTML = page.content || ""
        await this.initMsaBox(template.content)
        this.appendChild(template.content)
        this.setAttribute("editable", page.editable || false)
    }

    async postPage() {
        const tmpl = await exportMsaBox(this.children)
        for (let ed of tmpl.content.querySelectorAll(".msa-page-editor"))
            ed.remove()
        for (let box of tmpl.content.querySelectorAll(".msa-page-box"))
            box.classList.remove("msa-page-box")
        await ajax("POST", `${this.getBaseUrl()}/${this.getId()}/_page`, {
            body: { content: tmpl.innerHTML }
        })
    }
}

// register elem
customElements.define("msa-page", HTMLMsaPageElement)

// register editable element
export class HTMLMsaPageTextElement extends HTMLElement {
    initContent() {
        for (let c of this.children)
            if (c.classList.contains("content"))
                return c
        const res = document.createElement("div")
        res.classList.add("content")
        res.style.flex = 1
        this.appendChild(res)
        return res
    }
}
customElements.define("msa-page-text", HTMLMsaPageTextElement)

export class HTMLMsaPageBoxesElement extends HTMLElement { }
customElements.define("msa-page-boxes", HTMLMsaPageBoxesElement)

// utils

function insertBefore(newNode, refNode) {
    refNode.parentNode.insertBefore(newNode, refNode)
}

function insertAfter(newNode, refNode) {
    refNode.parentNode.insertBefore(newNode, refNode.nextSibling)
}<|endoftext|>


<commit_before>var tape = require("tape");
var jsdom = require("./jsdom");
var d3_graphviz = require("../");
var d3_selection = require("d3-selection");

tape("engine() selects which graphviz layout engine to use.", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    graphviz
        .zoom(false)
        .engine('dot')
        .renderDot('digraph {a -> b;}');

    test.ok(d3_selection.select('svg').attr('width', '62pt'), 'The "dot" engine generates an SVG with width 62pt');
    test.ok(d3_selection.select('svg').attr('height', '116pt'), 'The "dot" engine generates an SVG with height 116pt');

    test.end();
});

tape("engine() selects which graphviz layout engine to use.", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    graphviz
        .zoom(false)
        .engine('circo')
        .renderDot('digraph {a -> b;}');

    test.ok(d3_selection.select('svg').attr('width', '188pt'), 'The "dot" engine generates an SVG with width 188pt');
    test.ok(d3_selection.select('svg').attr('height', '44pt'), 'The "dot" engine generates an SVG with height 44pt');

    test.end();
});
<commit_msg>Port test/engine-test.js to hpcc-js-wasm<commit_after>var tape = require("tape");
var jsdom = require("./jsdom");
var d3_graphviz = require("../");
var d3_selection = require("d3-selection");

tape("engine() selects which graphviz layout engine to use.", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph")
        .on("initEnd", startTest);

    function startTest() {

        graphviz
            .zoom(false)
            .engine('dot')
            .renderDot('digraph {a -> b;}');

        test.ok(d3_selection.select('svg').attr('width', '62pt'), 'The "dot" engine generates an SVG with width 62pt');
        test.ok(d3_selection.select('svg').attr('height', '116pt'), 'The "dot" engine generates an SVG with height 116pt');

        test.end();
    }
});

tape("engine() selects which graphviz layout engine to use.", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph")
        .on("initEnd", startTest);

    function startTest() {

        graphviz
            .zoom(false)
            .engine('circo')
            .renderDot('digraph {a -> b;}');

        test.ok(d3_selection.select('svg').attr('width', '188pt'), 'The "dot" engine generates an SVG with width 188pt');
        test.ok(d3_selection.select('svg').attr('height', '44pt'), 'The "dot" engine generates an SVG with height 44pt');

        test.end();
    }
});
<|endoftext|>


<commit_before>// Copyright 2017-2018, University of Colorado Boulder

'use strict';

const constants = require( './constants' );
const fs = require( 'graceful-fs' ); //eslint-disable-line
const winston = require( 'winston' );
const writeFile = require( '../common/writeFile' );
const parseScreenNames = require( './parseScreenNames' );

/**
 * Create a [sim name].xml file in the live sim directory in htdocs. This file tells the website which
 * translations exist for a given sim. It is used by the "synchronize" method in Project.java in the website code.
 * @param simName
 * @param version
 */
module.exports = async function( simName, version ) {
  const rootdir = `../babel/${simName}`;
  const englishStringsFile = `${simName}-strings_en.json`;
  const stringFiles = [ { name: englishStringsFile, locale: constants.ENGLISH_LOCALE } ];

  // pull all the string filenames and locales from babel and store in stringFiles array
  try {
    const files = fs.readdirSync( rootdir );
    for ( let i = 0; i < files.length; i++ ) {
      const filename = files[ i ];
      const firstUnderscoreIndex = filename.indexOf( '_' );
      const periodIndex = filename.indexOf( '.' );
      const locale = filename.substring( firstUnderscoreIndex + 1, periodIndex );
      stringFiles.push( { name: filename, locale: locale } );
    }
  }
  catch( e ) {
    winston.log( 'warn', 'no directory for the given sim exists in babel' );
  }

  // try opening the english strings file so we can read the english strings
  let englishStrings;
  try {
    englishStrings = JSON.parse( fs.readFileSync( `../${simName}/${englishStringsFile}`, { encoding: 'utf-8' } ) );
  }
  catch( e ) {
    return Promise.reject( new Error( 'English strings file not found' ) );
  }

  const simTitleKey = `${simName}.title`; // all sims must have a key of this form
  let simTitle;
  if ( englishStrings[ simTitleKey ] ) {
    simTitle = englishStrings[ simTitleKey ].value;
  }
  else {
    return Promise.reject( new Error( 'No key for sim title' ) );
  }

  // create xml, making a simulation tag for each language
  let finalXML = `<?xml version="1.0" encoding="utf-8" ?>\n<project name="${simName}">\n<simulations>`;

  const screenNames = await parseScreenNames( simName );

  for ( let j = 0; j < stringFiles.length; j++ ) {
    const stringFile = stringFiles[ j ];
    const languageJSON = ( stringFile.locale === constants.ENGLISH_LOCALE ) ? englishStrings :
                         JSON.parse( fs.readFileSync( `../babel/${simName}/${stringFile.name}`, { encoding: 'utf-8' } ) );

    const simHTML = `${constants.HTML_SIMS_DIRECTORY + simName}/${version}/${simName}_${stringFile.locale}.html`;

    if ( fs.existsSync( simHTML ) ) {
      const localizedSimTitle = ( languageJSON[ simTitleKey ] ) ? languageJSON[ simTitleKey ].value : englishStrings[ simTitleKey ].value;
      finalXML = finalXML.concat( `<simulation name="${simName}" locale="${stringFile.locale}">\n` +
                                  `<title><![CDATA[${localizedSimTitle}]]></title>\n` );
      if ( screenNames && screenNames[ simName ] && screenNames[ simName ][ stringFile.locale ] ) {
        finalXML = finalXML.concat( '<screens>\n' );
        screenNames[ simName ][ stringFile.locale ].forEach( ( screenName, index ) => {
          finalXML = finalXML.concat( `<screenName position="${index + 1}"><![CDATA[${screenName}]]></screenName>\n` );
        } );
        finalXML = finalXML.concat( '</screens>\n' );
      }
      finalXML = finalXML.concat( '</simulation>\n' );
    }
  }

  finalXML = finalXML.concat( '</simulations>\n</project>' );

  const xmlFilepath = `${constants.HTML_SIMS_DIRECTORY + simName}/${version}/${simName}.xml`;
  try {
    await writeFile( xmlFilepath, finalXML );
  }
  catch( err ) {
    return Promise.reject( err );
  }
  winston.log( 'info', 'wrote XML file' );
  return Promise.resolve( simTitle );
};<commit_msg>blocked duplicate english entries in translations xml<commit_after>// Copyright 2017-2018, University of Colorado Boulder

'use strict';

const constants = require( './constants' );
const fs = require( 'graceful-fs' ); //eslint-disable-line
const winston = require( 'winston' );
const writeFile = require( '../common/writeFile' );
const parseScreenNames = require( './parseScreenNames' );

/**
 * Create a [sim name].xml file in the live sim directory in htdocs. This file tells the website which
 * translations exist for a given sim. It is used by the "synchronize" method in Project.java in the website code.
 * @param simName
 * @param version
 */
module.exports = async function( simName, version ) {
  const rootdir = `../babel/${simName}`;
  const englishStringsFile = `${simName}-strings_en.json`;
  const stringFiles = [ { name: englishStringsFile, locale: constants.ENGLISH_LOCALE } ];

  // pull all the string filenames and locales from babel and store in stringFiles array
  try {
    const files = fs.readdirSync( rootdir );
    for ( let i = 0; i < files.length; i++ ) {
      const filename = files[ i ];
      const firstUnderscoreIndex = filename.indexOf( '_' );
      const periodIndex = filename.indexOf( '.' );
      const locale = filename.substring( firstUnderscoreIndex + 1, periodIndex );
      // Don't process English twice!
      if ( locale !== constants.ENGLISH_LOCALE ) {
        stringFiles.push( { name: filename, locale: locale } );
      }
    }
  }
  catch( e ) {
    winston.log( 'warn', 'no directory for the given sim exists in babel' );
  }

  // try opening the english strings file so we can read the english strings
  let englishStrings;
  try {
    englishStrings = JSON.parse( fs.readFileSync( `../${simName}/${englishStringsFile}`, { encoding: 'utf-8' } ) );
  }
  catch( e ) {
    return Promise.reject( new Error( 'English strings file not found' ) );
  }

  const simTitleKey = `${simName}.title`; // all sims must have a key of this form
  let simTitle;
  if ( englishStrings[ simTitleKey ] ) {
    simTitle = englishStrings[ simTitleKey ].value;
  }
  else {
    return Promise.reject( new Error( 'No key for sim title' ) );
  }

  // create xml, making a simulation tag for each language
  let finalXML = `<?xml version="1.0" encoding="utf-8" ?>\n<project name="${simName}">\n<simulations>`;

  const screenNames = await parseScreenNames( simName );

  for ( let j = 0; j < stringFiles.length; j++ ) {
    const stringFile = stringFiles[ j ];
    const languageJSON = ( stringFile.locale === constants.ENGLISH_LOCALE ) ? englishStrings :
                         JSON.parse( fs.readFileSync( `../babel/${simName}/${stringFile.name}`, { encoding: 'utf-8' } ) );

    const simHTML = `${constants.HTML_SIMS_DIRECTORY + simName}/${version}/${simName}_${stringFile.locale}.html`;

    if ( fs.existsSync( simHTML ) ) {
      const localizedSimTitle = ( languageJSON[ simTitleKey ] ) ? languageJSON[ simTitleKey ].value : englishStrings[ simTitleKey ].value;
      finalXML = finalXML.concat( `<simulation name="${simName}" locale="${stringFile.locale}">\n` +
                                  `<title><![CDATA[${localizedSimTitle}]]></title>\n` );
      if ( screenNames && screenNames[ simName ] && screenNames[ simName ][ stringFile.locale ] ) {
        finalXML = finalXML.concat( '<screens>\n' );
        screenNames[ simName ][ stringFile.locale ].forEach( ( screenName, index ) => {
          finalXML = finalXML.concat( `<screenName position="${index + 1}"><![CDATA[${screenName}]]></screenName>\n` );
        } );
        finalXML = finalXML.concat( '</screens>\n' );
      }
      finalXML = finalXML.concat( '</simulation>\n' );
    }
  }

  finalXML = finalXML.concat( '</simulations>\n</project>' );

  const xmlFilepath = `${constants.HTML_SIMS_DIRECTORY + simName}/${version}/${simName}.xml`;
  try {
    await writeFile( xmlFilepath, finalXML );
  }
  catch( err ) {
    return Promise.reject( err );
  }
  winston.log( 'info', 'wrote XML file' );
  return Promise.resolve( simTitle );
};<|endoftext|>


<commit_before>/*
 * PassagePage
 */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import Combokeys from 'combokeys'

import { asyncNavigateNext, asyncNavigatePrevious, asyncChangeMode, asyncChangeRecall } from '../../actions/AppActions';
import { VERSE_MODE, SEGMENT_MODE, CHAPTER_MODE, RECALL_STAGES } from '../../constants/AppConstants';

import AudioPlayer from '../AudioPlayer.react';
import PassageSelect from '../PassageSelect.react';
import KeyboardShortcutHUD from '../KeyboardShortcutHUD.react';
import Swipeable from 'react-swipeable';

// use named export for unconnected component (unit tests)
export class PassagePage extends Component {
  componentDidMount() {
    let combokeys = new Combokeys(document.documentElement);
    combokeys.bind('right', () => { this.props.dispatch(asyncNavigateNext()) });
    combokeys.bind('left', () => { this.props.dispatch(asyncNavigatePrevious()) });
    combokeys.bind('v', () => { this.props.dispatch(asyncChangeMode(VERSE_MODE)) });
    combokeys.bind('s', () => { this.props.dispatch(asyncChangeMode(SEGMENT_MODE)) });
    combokeys.bind('c', () => { this.props.dispatch(asyncChangeMode(CHAPTER_MODE)) });
    combokeys.bind('1', () => { this.props.dispatch(asyncChangeRecall(RECALL_STAGES.FULL)) });
    combokeys.bind('2', () => { this.props.dispatch(asyncChangeRecall(RECALL_STAGES.FIRST)) });
    combokeys.bind('3', () => { this.props.dispatch(asyncChangeRecall(RECALL_STAGES.NONE)) });
  }

  componentWillUnmount() {
    let combokeys = new Combokeys(document.documentElement);
    combokeys.unbind('right');
    combokeys.unbind('left');
    combokeys.unbind('v');
    combokeys.unbind('s');
    combokeys.unbind('c');
    combokeys.unbind('1');
    combokeys.unbind('2');
    combokeys.unbind('3');
  }

  renderPassageText(recallStage, activePassage) {
    if (recallStage !== RECALL_STAGES.NONE) {
      return (

      );
    }
  }

  render() {
    const dispatch = this.props.dispatch;
    const { active, verses, segments, chapters, mode, recallStage, isAudioPlaying } = this.props.data;

    /**
     * Take into account the current mode, and determine if we can navigation backward.
     *
     * @TODO make this better than a simple index check (which is only good for verse mode)
     *
     * @return boolean Whether or not we can navigate backward
     */
    function canNavigatePrevious() {
      return true;
    }

    /**
     * Take into account the current mode, and determine if we can navigation backward.
     *
     * @TODO make this work.
     *
     * @return boolean Whether or not we can navigate forward
     */
    function canNavigateNext() {
      return true;
    }

    let activePassage = {};
    let activeCollection = [];
    let activeIndex = 0;

    if (mode === VERSE_MODE) {
      activeCollection = verses;
      activeIndex = active[VERSE_MODE];
    } else if (mode === SEGMENT_MODE) {
      activeCollection = segments;
      activeIndex = active[SEGMENT_MODE];
    } else {
      activeCollection = chapters;
      activeIndex = active[CHAPTER_MODE];
    }
    activePassage = activeCollection[activeIndex];

    return (

        <KeyboardShortcutHUD />

            <button className={ mode == VERSE_MODE ? "active" : ""}
                    onClick={() => { dispatch(asyncChangeMode(VERSE_MODE)) }}>
              {verses[active[VERSE_MODE]].shortMetadata()}
            </button>

            <button className={ mode == SEGMENT_MODE ? "active" : ""}
                    onClick={() => { dispatch(asyncChangeMode(SEGMENT_MODE)) }}>
              {segments[active[SEGMENT_MODE]].shortMetadata()}
            </button>

            <button className={ mode == CHAPTER_MODE ? "active" : ""}
                    onClick={() => { dispatch(asyncChangeMode(CHAPTER_MODE)) }}>
              {chapters[active[CHAPTER_MODE]].bookAndChapter()}
            </button>

            <PassageSelect
              dispatch={dispatch}
              collection={activeCollection}
              selectedIndex={activeIndex}
            ></PassageSelect>

          <button className="previous"
                  title="Previous"
                  disabled={ !canNavigatePrevious() }
                  onClick={() => { dispatch(asyncNavigatePrevious()) }}>
            <
          </button>

          <button className="next"
                  title="Next"
                  disabled={ !canNavigateNext() }
                  onClick={() => { dispatch(asyncNavigateNext()) }}>
            >
          </button>

          <Swipeable
            className={ "verse-wrapper " + recallStage }
            onSwipedLeft={() => { dispatch(asyncNavigateNext()) }}
            onSwipedRight={() => { dispatch(asyncNavigatePrevious()) }}
          >

            { this.renderPassageText(recallStage, activePassage) }

ESV

          </Swipeable>

          <button
            className={ recallStage == RECALL_STAGES.FULL ? "active" : ""}
            onClick={() => { dispatch(asyncChangeRecall(RECALL_STAGES.FULL)) }}
          >KNOW</button>

          <button
            className={ recallStage == RECALL_STAGES.FIRST ? "active" : ""}
            onClick={() => { dispatch(asyncChangeRecall(RECALL_STAGES.FIRST)) }}
          >K___</button>

          <button
            className={ recallStage == RECALL_STAGES.NONE ? "active" : ""}
            onClick={() => { dispatch(asyncChangeRecall(RECALL_STAGES.NONE)) }}
          >____</button>

          <AudioPlayer className="audio-controls"
                       src={ activePassage.audioUrl() }
                       dispatch={ dispatch }
                       isAudioPlaying={ isAudioPlaying } />

    );
  }
}

function select(state) {
  return {
    data: state
  };
}

// Wrap the component to inject dispatch and state into it
export default connect(select)(PassagePage);
<commit_msg>Use font awesome for nav arrows<commit_after>/*
 * PassagePage
 */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import Combokeys from 'combokeys'

import { asyncNavigateNext, asyncNavigatePrevious, asyncChangeMode, asyncChangeRecall } from '../../actions/AppActions';
import { VERSE_MODE, SEGMENT_MODE, CHAPTER_MODE, RECALL_STAGES } from '../../constants/AppConstants';

import AudioPlayer from '../AudioPlayer.react';
import PassageSelect from '../PassageSelect.react';
import KeyboardShortcutHUD from '../KeyboardShortcutHUD.react';
import Swipeable from 'react-swipeable';

// use named export for unconnected component (unit tests)
export class PassagePage extends Component {
  componentDidMount() {
    let combokeys = new Combokeys(document.documentElement);
    combokeys.bind('right', () => { this.props.dispatch(asyncNavigateNext()) });
    combokeys.bind('left', () => { this.props.dispatch(asyncNavigatePrevious()) });
    combokeys.bind('v', () => { this.props.dispatch(asyncChangeMode(VERSE_MODE)) });
    combokeys.bind('s', () => { this.props.dispatch(asyncChangeMode(SEGMENT_MODE)) });
    combokeys.bind('c', () => { this.props.dispatch(asyncChangeMode(CHAPTER_MODE)) });
    combokeys.bind('1', () => { this.props.dispatch(asyncChangeRecall(RECALL_STAGES.FULL)) });
    combokeys.bind('2', () => { this.props.dispatch(asyncChangeRecall(RECALL_STAGES.FIRST)) });
    combokeys.bind('3', () => { this.props.dispatch(asyncChangeRecall(RECALL_STAGES.NONE)) });
  }

  componentWillUnmount() {
    let combokeys = new Combokeys(document.documentElement);
    combokeys.unbind('right');
    combokeys.unbind('left');
    combokeys.unbind('v');
    combokeys.unbind('s');
    combokeys.unbind('c');
    combokeys.unbind('1');
    combokeys.unbind('2');
    combokeys.unbind('3');
  }

  renderPassageText(recallStage, activePassage) {
    if (recallStage !== RECALL_STAGES.NONE) {
      return (

      );
    }
  }

  render() {
    const dispatch = this.props.dispatch;
    const { active, verses, segments, chapters, mode, recallStage, isAudioPlaying } = this.props.data;

    /**
     * Take into account the current mode, and determine if we can navigation backward.
     *
     * @TODO make this better than a simple index check (which is only good for verse mode)
     *
     * @return boolean Whether or not we can navigate backward
     */
    function canNavigatePrevious() {
      return true;
    }

    /**
     * Take into account the current mode, and determine if we can navigation backward.
     *
     * @TODO make this work.
     *
     * @return boolean Whether or not we can navigate forward
     */
    function canNavigateNext() {
      return true;
    }

    let activePassage = {};
    let activeCollection = [];
    let activeIndex = 0;

    if (mode === VERSE_MODE) {
      activeCollection = verses;
      activeIndex = active[VERSE_MODE];
    } else if (mode === SEGMENT_MODE) {
      activeCollection = segments;
      activeIndex = active[SEGMENT_MODE];
    } else {
      activeCollection = chapters;
      activeIndex = active[CHAPTER_MODE];
    }
    activePassage = activeCollection[activeIndex];

    return (

        <KeyboardShortcutHUD />

            <button className={ mode == VERSE_MODE ? "active" : ""}
                    onClick={() => { dispatch(asyncChangeMode(VERSE_MODE)) }}>
              {verses[active[VERSE_MODE]].shortMetadata()}
            </button>

            <button className={ mode == SEGMENT_MODE ? "active" : ""}
                    onClick={() => { dispatch(asyncChangeMode(SEGMENT_MODE)) }}>
              {segments[active[SEGMENT_MODE]].shortMetadata()}
            </button>

            <button className={ mode == CHAPTER_MODE ? "active" : ""}
                    onClick={() => { dispatch(asyncChangeMode(CHAPTER_MODE)) }}>
              {chapters[active[CHAPTER_MODE]].bookAndChapter()}
            </button>

            <PassageSelect
              dispatch={dispatch}
              collection={activeCollection}
              selectedIndex={activeIndex}
            ></PassageSelect>

          <button className="previous"
                  title="Previous"
                  disabled={ !canNavigatePrevious() }
                  onClick={() => { dispatch(asyncNavigatePrevious()) }}>

          </button>

          <button className="next"
                  title="Next"
                  disabled={ !canNavigateNext() }
                  onClick={() => { dispatch(asyncNavigateNext()) }}>

          </button>

          <Swipeable
            className={ "verse-wrapper " + recallStage }
            onSwipedLeft={() => { dispatch(asyncNavigateNext()) }}
            onSwipedRight={() => { dispatch(asyncNavigatePrevious()) }}
          >

            { this.renderPassageText(recallStage, activePassage) }

ESV

          </Swipeable>

          <button
            className={ recallStage == RECALL_STAGES.FULL ? "active" : ""}
            onClick={() => { dispatch(asyncChangeRecall(RECALL_STAGES.FULL)) }}
          >KNOW</button>

          <button
            className={ recallStage == RECALL_STAGES.FIRST ? "active" : ""}
            onClick={() => { dispatch(asyncChangeRecall(RECALL_STAGES.FIRST)) }}
          >K___</button>

          <button
            className={ recallStage == RECALL_STAGES.NONE ? "active" : ""}
            onClick={() => { dispatch(asyncChangeRecall(RECALL_STAGES.NONE)) }}
          >____</button>

          <AudioPlayer className="audio-controls"
                       src={ activePassage.audioUrl() }
                       dispatch={ dispatch }
                       isAudioPlaying={ isAudioPlaying } />

    );
  }
}

function select(state) {
  return {
    data: state
  };
}

// Wrap the component to inject dispatch and state into it
export default connect(select)(PassagePage);
<|endoftext|>