<commit_before>// Copyright (c) 2015, EMC Corporation

'use strict';

module.exports = ChildProcessFactory;

ChildProcessFactory.$provide = 'ChildProcess';
ChildProcessFactory.$inject = [
    'child_process',
    'Errors',
    'Logger',
    'Assert',
    'Util',
    'Promise',
    '_',
    'fs',
    'path'
];

/**
 * childProcessFactory returns a ChildProcess constructor
 * @param {Q} Q Promise Library
 * @param {Logger} Logger module
 * @param {Object} assert assertion module
 * @param {Object} _ lodash module
 * @private
 */
function ChildProcessFactory (
    nodeChildProcess,
    Errors,
    Logger,
    assert,
    util,
    Promise,
    _,
    fs,
    path
) {
    var logger = Logger.initialize(ChildProcessFactory);

    /**
     * ChildProcess provides a promise based mechanism to run shell commands
     * in a fairly secure manner.
     * @constructor
     */
    function ChildProcess (command, args, env, code) {
        var self = this;

        assert.string(command);

        self.command = command;
        self.file = self._parseCommandPath(self.command);
        self.args = args;
        self.environment = env || {};
        self.exitCode = code || 0;

        if (!self.file) {
            throw new Error('Unable to locate command file (' + self.command +').');
        }
        if (!_.isEmpty(self.args)) {
            try {
                assert.arrayOfString(self.args, 'ChildProcess command arguments');
            } catch (e) {
                throw new Error('args must be an array of strings');
            }
        }

        self.hasBeenKilled = false;
        self.hasBeenCancelled = false;
        self.spawnInstance = undefined;
    }

    ChildProcess.prototype.createOwnDeferred = function() {
        var self = this;
        self._deferred = new Promise(function(resolve, reject) {
            self._resolve = resolve;
            self._reject = reject;
        });
    };

    ChildProcess.prototype.resolve = function(result) {
        if (!this._deferred.isPending()) {
            logger.warning("ChildProcess promise has already been resolved");
            return;
        } else {
            this._resolve(result);
        }
    };

    ChildProcess.prototype.reject = function(error) {
        if (!this._deferred.isPending()) {
            logger.warning("ChildProcess promise has already been rejected");
            return;
        } else {
            this._reject(error);
        }
    };

    ChildProcess.prototype.killSafe = function (signal) {
        if (!this.hasBeenKilled && this.spawnInstance && _.isFunction(this.spawnInstance.kill)) {
            this.spawnInstance.kill(signal);
        }
        this.hasBeenCancelled = true;
    };

    /**
     * Runs the given command.
     * @param  {String} command File to run, with path or without.
     * @param  {String[]} args    Arguments to the file.
     * @param  {Object} env     Optional environment variables to provide.
     * @param  {Integer} code   Desired exit code, defaults to 0.
     * @return {Promise}        A promise fulfilled with the stdout, stderr of
     * a successful command.
     */
    ChildProcess.prototype._run = function () {
        var self = this;

        if (self.hasBeenCancelled) {
            self.reject(new Errors.JobKilledError("ChildProcess job has been cancelled", {
                command: self.command,
                argv: self.args
            }));
            return;
        }

        self.hasBeenKilled = false;

        self.spawnInstance = nodeChildProcess.execFile(
                self.file, self.args, self.environment, function (error, stdout, stderr) {

            if (error && error.code !== self.exitCode) {
                self.hasBeenKilled = true;
                logger.error('Error Running ChildProcess.', {
                    file: self.file,
                    argv: self.args,
                    stdout: stdout,
                    stderr: stderr,
                    error: error
                });

                self.reject(error);
            } else {
                self.hasBeenKilled = true;
                self.resolve({
                    stdout: stdout,
                    stderr: stderr
                });
            }
        })
        .on('close', function(code, signal) {
            if (signal) {
                logger.warning("Child process received closing signal:", {
                    signal: signal,
                    argv: self.args
                });
            }
            self.hasBeenKilled = true;
        })
        .on('error', function(code, signal) {
            logger.error("Child process received closing signal but has " +
                "already been closed!!!", {
                signal: signal,
                argv: self.args
            });
        });
    };

    ChildProcess.prototype._runWithRetries = function(retryCount, delay, retries) {
        var self = this;

        // Max out exponential backoff to 60 seconds.
        delay = delay > 60000 ? 60000 : delay;

        if (!self._deferred) {
            self.createOwnDeferred();
        }

        self._run();

        return self._deferred.catch(function(e) {
            if (e instanceof Errors.JobKilledError) {
                throw e;
            } else if (retryCount < retries) {
                logger.debug("Retrying ChildProcess command.", {
                    file: self.file,
                    args: self.args
                });
                // Create new deferred promise in here instead of above, in case we receive an
                // external cancellation during the below delay, so we don't
                // try to reject using the previous deferred object.
                self.createOwnDeferred();
                return Promise.delay(delay)
                .then(function() {
                    return self._runWithRetries(retryCount + 1, delay * 2, retries);
                });
            } else {
                throw e;
            }
        });
    };

    ChildProcess.prototype.run = function(options) {
        options = options || {};
        options.retries = options.retries || 0;
        if (options.delay !== 0) {
            options.delay = options.delay || 500;
        }

        return this._runWithRetries(0, options.delay, options.retries);
    };

    /**
     * Internal method to identify the path to the command file.  It's essentially
     * unix which in JavaScript.
     * @private
     */
    ChildProcess.prototype._parseCommandPath = function _parseCommandPath (command) {
        var self = this;

        if (self._fileExists(command)) {
            return command;
        } else {
            var found = _.some(self._getPaths(), function (current) {
                var target = path.resolve(current + '/' + command);

                if (self._fileExists(target)) {
                    command = target;

                    return true;
                }
            });

            return found ? command : null;
        }
    };

    /**
     * Internal method to verify a file exists and is not a directory.
     * @private
     */
    ChildProcess.prototype._fileExists = function _fileExists (file) {
        return fs.existsSync(file) && !fs.statSync(file).isDirectory();
    };

    /**
     * Internal method to get an array of directories in the users path.
     * @private
     */
    ChildProcess.prototype._getPaths = function _getPaths () {
        var path = process.env.path || process.env.Path || process.env.PATH;
        return path.split(':');
    };

    return ChildProcess;
}
<commit_msg>Add maxBuffer support to ChildProcess<commit_after>// Copyright (c) 2015, EMC Corporation

'use strict';

module.exports = ChildProcessFactory;

ChildProcessFactory.$provide = 'ChildProcess';
ChildProcessFactory.$inject = [
    'child_process',
    'Errors',
    'Logger',
    'Assert',
    'Util',
    'Promise',
    '_',
    'fs',
    'path'
];

/**
 * childProcessFactory returns a ChildProcess constructor
 * @param {Q} Q Promise Library
 * @param {Logger} Logger module
 * @param {Object} assert assertion module
 * @param {Object} _ lodash module
 * @private
 */
function ChildProcessFactory (
    nodeChildProcess,
    Errors,
    Logger,
    assert,
    util,
    Promise,
    _,
    fs,
    path
) {
    var logger = Logger.initialize(ChildProcessFactory);

    /**
     * ChildProcess provides a promise based mechanism to run shell commands
     * in a fairly secure manner.
     * @constructor
     */
    function ChildProcess (command, args, env, code) {
        var self = this;

        assert.string(command);

        self.command = command;
        self.file = self._parseCommandPath(self.command);
        self.args = args;
        self.environment = env || {};
        self.exitCode = code || 0;

        if (!self.file) {
            throw new Error('Unable to locate command file (' + self.command +').');
        }
        if (!_.isEmpty(self.args)) {
            try {
                assert.arrayOfString(self.args, 'ChildProcess command arguments');
            } catch (e) {
                throw new Error('args must be an array of strings');
            }
        }

        self.hasBeenKilled = false;
        self.hasBeenCancelled = false;
        self.spawnInstance = undefined;
    }

    ChildProcess.prototype.createOwnDeferred = function() {
        var self = this;
        self._deferred = new Promise(function(resolve, reject) {
            self._resolve = resolve;
            self._reject = reject;
        });
    };

    ChildProcess.prototype.resolve = function(result) {
        if (!this._deferred.isPending()) {
            logger.warning("ChildProcess promise has already been resolved");
            return;
        } else {
            this._resolve(result);
        }
    };

    ChildProcess.prototype.reject = function(error) {
        if (!this._deferred.isPending()) {
            logger.warning("ChildProcess promise has already been rejected");
            return;
        } else {
            this._reject(error);
        }
    };

    ChildProcess.prototype.killSafe = function (signal) {
        if (!this.hasBeenKilled && this.spawnInstance && _.isFunction(this.spawnInstance.kill)) {
            this.spawnInstance.kill(signal);
        }
        this.hasBeenCancelled = true;
    };

    /**
     * Runs the given command.
     * @param  {String} command File to run, with path or without.
     * @param  {String[]} args    Arguments to the file.
     * @param  {Object} env     Optional environment variables to provide.
     * @param  {Integer} code   Desired exit code, defaults to 0.
     * @return {Promise}        A promise fulfilled with the stdout, stderr of
     * a successful command.
     */
    ChildProcess.prototype._run = function (maxBuffer) {
        var self = this;

        if (self.hasBeenCancelled) {
            self.reject(new Errors.JobKilledError("ChildProcess job has been cancelled", {
                command: self.command,
                argv: self.args
            }));
            return;
        }

        self.hasBeenKilled = false;

        var options = {
            env: self.environment,
            maxBuffer: maxBuffer || (200*1024)  // nodejs default
        };

        self.spawnInstance = nodeChildProcess.execFile(
                self.file, self.args, options, function (error, stdout, stderr) {

            if (error && error.code !== self.exitCode) {
                self.hasBeenKilled = true;
                logger.error('Error Running ChildProcess.', {
                    file: self.file,
                    argv: self.args,
                    stdout: stdout,
                    stderr: stderr,
                    error: error
                });

                self.reject(error);
            } else {
                self.hasBeenKilled = true;
                self.resolve({
                    stdout: stdout,
                    stderr: stderr
                });
            }
        })
        .on('close', function(code, signal) {
            if (signal) {
                logger.warning("Child process received closing signal:", {
                    signal: signal,
                    argv: self.args
                });
            }
            self.hasBeenKilled = true;
        })
        .on('error', function(code, signal) {
            logger.error("Child process received closing signal but has " +
                "already been closed!!!", {
                signal: signal,
                argv: self.args
            });
        });
    };

    ChildProcess.prototype._runWithRetries = function(retryCount, delay, retries, maxBuffer) {
        var self = this;

        // Max out exponential backoff to 60 seconds.
        delay = delay > 60000 ? 60000 : delay;

        if (!self._deferred) {
            self.createOwnDeferred();
        }

        self._run();

        return self._deferred.catch(function(e) {
            if (e instanceof Errors.JobKilledError) {
                throw e;
            } else if (retryCount < retries) {
                logger.debug("Retrying ChildProcess command.", {
                    file: self.file,
                    args: self.args
                });
                // Create new deferred promise in here instead of above, in case we receive an
                // external cancellation during the below delay, so we don't
                // try to reject using the previous deferred object.
                self.createOwnDeferred();
                return Promise.delay(delay)
                .then(function() {
                    return self._runWithRetries(retryCount + 1, delay * 2, retries, maxBuffer);
                });
            } else {
                throw e;
            }
        });
    };

    ChildProcess.prototype.run = function(options) {
        options = options || {};
        options.retries = options.retries || 0;
        if (options.delay !== 0) {
            options.delay = options.delay || 500;
        }
        if (options.maxBuffer) {
            assert.number(options.maxBuffer);
        }

        return this._runWithRetries(0, options.delay, options.retries, options.maxBuffer);
    };

    /**
     * Internal method to identify the path to the command file.  It's essentially
     * unix which in JavaScript.
     * @private
     */
    ChildProcess.prototype._parseCommandPath = function _parseCommandPath (command) {
        var self = this;

        if (self._fileExists(command)) {
            return command;
        } else {
            var found = _.some(self._getPaths(), function (current) {
                var target = path.resolve(current + '/' + command);

                if (self._fileExists(target)) {
                    command = target;

                    return true;
                }
            });

            return found ? command : null;
        }
    };

    /**
     * Internal method to verify a file exists and is not a directory.
     * @private
     */
    ChildProcess.prototype._fileExists = function _fileExists (file) {
        return fs.existsSync(file) && !fs.statSync(file).isDirectory();
    };

    /**
     * Internal method to get an array of directories in the users path.
     * @private
     */
    ChildProcess.prototype._getPaths = function _getPaths () {
        var path = process.env.path || process.env.Path || process.env.PATH;
        return path.split(':');
    };

    return ChildProcess;
}
<|endoftext|>


<commit_before>/**
 * Description - Verifies that package.json does not contain a fatal error.
 * @param {string} packagePath - directory of the project to verify
 * @param {function} done - callback to be invoked with error
 **/

var fs           = require('fs');
var findFileSync = require('find-file-sync');
var util         = require('util');

module.exports = function (packagePath, done) {
  if (!packagePath) return done();

  var metaPath = findFileSync(packagePath, 'package.json', ['.git', 'node_modules']);
  var meta;
  try {
    meta = JSON.parse(fs.readFileSync(metaPath), 'utf8');
  } catch (e) {
    return done();
  }

  var matches = [];
  if (!meta.scripts || !meta.scripts.start) return done(null, matches);
  fatalBlackList.forEach(function(elem) {
    if(meta.scripts.start.match(new RegExp(elem, 'g'))) {
      matches.push(createFatalMessage(elem));
    }
  });

  return done(null, matches);
}

var fatalBlackList = ['forever', 'pm2', 'nodemon'];

function createFatalMessage (command) {
  return util.format(['FATAL: Your application is currently configured to run using %s,',
      'which is not supported on Modulus. Please change your start',
      'script to simply start the application and we\'ll handle the rest.'
    ].join(' '), command);
}
<commit_msg>make consistent callbacks<commit_after>/**
 * Description - Verifies that package.json does not contain a fatal error.
 * @param {string} packagePath - directory of the project to verify
 * @param {function} done - callback to be invoked with error
 **/

var fs           = require('fs');
var findFileSync = require('find-file-sync');
var util         = require('util');

module.exports = function (packagePath, done) {
  var matches = [];
  var metaPath;
  var meta;

  if (!packagePath) return done(null, matches);
  metaPath = findFileSync(packagePath, 'package.json', ['.git', 'node_modules']);

  try {
    meta = JSON.parse(fs.readFileSync(metaPath), 'utf8');
  } catch (e) {
    return done(null, matches);
  }

  if (!meta.scripts || !meta.scripts.start) return done(null, matches);

  fatalBlackList.forEach(function (elem) {
    if(meta.scripts.start.match(new RegExp(elem, 'g'))) {
      matches.push(createFatalMessage(elem));
    }
  });

  return done(null, matches);
}

var fatalBlackList = ['forever', 'pm2', 'nodemon'];

function createFatalMessage (command) {
  return util.format(['FATAL: Your application is currently configured to run using %s,',
      'which is not supported on Modulus. Please change your start',
      'script to simply start the application and we\'ll handle the rest.'
    ].join(' '), command);
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import $ from 'jquery';
import './Main.css';
import Header from '../Header/Header';
import Welcome from '../Welcome/Welcome';
import WeatherFull from '../WeatherFull/WeatherFull';

export default class Main extends Component {
  componentDidMount() {
    const location = localStorage.getItem('location');
    if (!location) {
      console.log('no location in storage');
    } else {
      // this.callAPI(location);
      this.callAPI(80203);
    }
  }

  changeLocation() {
    const location = document.querySelectorAll('.search-bar')[1].value;
    // might break once we hide the search in the header...easy to fix though
    // setState in WeatherFull? Or update local storage?
    this.callAPI(location);
  }

  callAPI(location) {
    $.get(`http://api.wunderground.com/api/b0004c055cb382e4/hourly/forecast10day/conditions/q/${location}.json`)
      .then(data => {
        console.log('API results', data);
        // update state in Weather Full?
      })
      .catch(error => console.log('catch', error))
  }

  render() {
    return (
      <main>
        <Header />
        <Welcome changeLocation={this.changeLocation.bind(this)}/>
        <WeatherFull />
      </main>
    );
  }
}<commit_msg>WIP: Console logs API Call w/ zip code and city, state pairs<commit_after>import React, { Component } from 'react';
import $ from 'jquery';
import './Main.css';
import Header from '../Header/Header';
import Welcome from '../Welcome/Welcome';
import WeatherFull from '../WeatherFull/WeatherFull';

export default class Main extends Component {
  componentDidMount() {
    const location = localStorage.getItem('location');
    if (!location) {
      console.log('no location in storage');
    } else {
      // this.callAPI(location);
      this.callAPI(48118);
    }
  }

  changeLocation() {
    const location = document.querySelectorAll('.search-bar')[1].value;
    // might break once we hide the search in the header...easy to fix though
    // setState in WeatherFull? Or update local storage?
    this.callAPI(location);
  }

  callAPI(location) {
    if (parseInt(location, 10)) {
      $.get(`http://api.wunderground.com/api/b0004c055cb382e4/hourly/forecast10day/conditions/q/${location}.json`)
      .then(data => {
        console.log('API results by Zip Code', data);
      })
      .catch(error => console.log('catch', error))
    } else {
      const cityStateArr = location.split(', ');
      $.get(`http://api.wunderground.com/api/b0004c055cb382e4/hourly/forecast10day/conditions/q/${cityStateArr[1]}/${cityStateArr[0]}.json`)
      .then(data => {
        console.log('API results by City, ST', data);
      })
      .catch(error => console.log('catch', error))
    }
    // update state in Weather Full?
  }

  render() {
    return (
      <main>
        <Header />
        <Welcome changeLocation={this.changeLocation.bind(this)}/>
        <WeatherFull />
      </main>
    );
  }
}<|endoftext|>


<commit_before>/*
TODO: funktion schreiben, die eine spalte hinzufügen kann zur tabelle!
und diese dann am besten über ein callback oder Promise?
so befüllt

  id - id des divs im menü, bei on Click wird die Spalte hinzugefügt und
    für jede zeile das callback mit der dnr aufgerufen
  name - array von dict mit Maschinenname (wird für css klassen etc. verwendet)
          und Menschennamen (wird angezeigt in der ui) der spalten:
            [{calcname : "sandienststunden", uiname: "Dienststunden d. l. 6 Monate"}, ]

  callback - callback, das (dnr, name, td)
        dnr - Dienstnummer
        name - Das DictObject mit classname und Name der Spalte, aus dem names array
        td - die Tabellenzelle als jquery Object
    der Spalte die berechnet werden soll übergeben bekommt,
    der return des callback wird in die tabellenzelle geschrieben

*/
var clicked = {};
function addCalculationHandler(id, names, callback) {

  $(id).click(function() {
    if (id in clicked) { //verhindern, das eine Spalte mehrmals hinzugefügt wird
      return;
    }
    clicked[id] = true;

    var exportTable = $(".export");
    names.forEach( function(name) {
        console.log("addCalculationHandler --> names " + name.calcname + " mit ui "+ name.uiname);

        columns.push({
          data: name.calcname,
          title: name.uiname,
          defaultContent: ""
        });

        //TODO: solange das läuft kleines fenster anzeigen bzw. user informieren!
        var ready = Promise.resolve();
        for (index in dataSet) {
          var row = dataSet[index];
          //dataSet[index][name.calcname] = "eins";
          console.log("addCalculationHandler --> lade für dnr: " + row.DNR);
          ready = ready.then(function() {
            return callback(row.DNR, name).then(function(value) {
              dataSet[index][name.calcname] = value;
              console.log("addCalculationHandler --> füge value " + value + " für spalte " + name.calcname + " hinzu");
            } ).catch(function(error) {
              console.log("addCalculationHandler -> promise then mit error: " + error);
            });
          });
        }
        ready.then(function() { //warte auf die promises...
          console.log("addCalculationHandler --> promises should be resolved....refresh DataTable data");

          // columns.push({
          //   data: "testdata",
          //   title: "Leere Daten",
          //   defaultContent: "leer"
          // });

          initDataTable();  //erzeuge DataTable erneut!
        });

        //exportTable.find("tr:gt(0)").append("Berechnen...	");
        //exportTable.find("tr:first").append("" + names[n].uiname + "	");

        // exportTable.find("tr:gt(0)").each(function(index, element) {
        //   var dnr = $(element).find("td:first").text();
        //   var td = $(element).find("td." + names[n].calcname);
        //   callback(dnr, n).then(
        //     function (value) {
        //       console.log("addCalculationHandler --> promise then value:" + value);
        //         td.text(value);
        //     },
        //     function (error) {
        //         console.log("addCalculationHandler -> promise then mit error: " + error);
        //         td.text(error);
        //     });
        //     //hier darauf warten, dass callback fertig! um niu von zu vielen Requests zu entlasten
        //     //und diese hier seriell abzuarbeiten!
        //
        // });
    });

  });

}

//TODO: die gesamte Tabelle irgendwie sortierbar machen
/*
  eventuell mit plugin wie
  dynatable https://www.dynatable.com/#event-hooks
  tablesorter http://tablesorter.com/docs/

*/

var dataSet = new Array;
var columns = new Array;
// var dataTableColumns = new Array;
var datatable = undefined;
function initDataTable() {
  console.log("initDataTable --> dataSet lenght: " + dataSet.length );
  console.log("initDataTable --> columns: " + columns.length);

  if (!(datatable === undefined)) {
      datatable.destroy();
      console.log("initDataTable --> after destroy: dataSet lenght: " + dataSet.length + " columns: " + columns.length);
      datatable = undefined;
  }
  // var exportTable = $(".export");
  // columns = new Array;
  // //var headers = [];
  // //parse first column also die headers...
  // exportTable.find("tr:first th").each( function(index) {
  //   console.log("index " + index + " mit th " + $(this).text());
  //     //headers.push($(this).text());
  //     columns.push( {
  //       data: $(this).text(),
  //       title: $(this).text()
  //     });
  // });
  // for (index in columns) {
  //     dataTableColumns.push($.extend({}, columns[index]));
  // }

  console.log("initDataTable --> dataSet:" + JSON.stringify(dataSet));
  console.log("initDataTable --> dataTableColumns:" + JSON.stringify(columns));

  $('#datatablediv').empty();

  datatable = $('

')
  $('#datatablediv').append(datatable);

  datatable = datatable.DataTable({
    destroy: true,
    data: dataSet,
    columns: columns
  });

  //verändere css, damit die sorting images angezeigt werden!
  $("#datatable").find(".sorting").css("background-image", 'url("' + chrome.extension.getURL("/img/sort_both.png") + '")');
  $("#datatable").find(".sorting_asc").css("background-image", 'url("' + chrome.extension.getURL("/img/sort_asc.png")  + '")');
  $("#datatable").find(".sorting_desc").css("background-image", 'url("' + chrome.extension.getURL("/img/sort_desc.png")  + '")');

}

$(document).ready(function() {

  var exportTable = $(".export");

  var headers = [];
  //parse first column also die headers...
  exportTable.find("tr:first th").each( function(index) {
    console.log("index " + index + " mit th " + $(this).text());
      headers.push($(this).text());
      columns.push( {
        data: $(this).text(),
        title: $(this).text()
      });
  });

  //parse data
  exportTable.find("tr:gt(0)").each( function(index) {
      var row = {};
      $(this).find("td").each(function(index) {
        row[headers[index]] = $(this).text();
      });
      dataSet.push(row);
  });

  //exportTable.after("
Hallo Welt
");
  exportTable.after("

");
  exportTable.hide();
  initDataTable();

  var header = $("#ctl00_m_Header");

  /*
    lade das Menü, mit den möglichen Berechnungen
    es wäre unklug gleich alle Berechnungen zu machen -> zu viele
    Requests und nicht jeder MA braucht alle Berechnungen
    TODO:
  */
  var path = chrome.extension.getURL("src/webcontent/employee_dump_menu.html");
  console.log("path: " + path);
  $.get(path, function(data) {

    header.after(data);
    //data.menu();
    $("#menu").menu();

    //$("#rddienste").trigger("click");

    $("#grundkurse").click(function() {
      console.log("grundkurse gecklickt!");
      if ("grundkurse" in clicked) {
        return;
      }
      clicked["grundkurse"] = true;

      var grundkurse = {
                        kurs1 : { "Name" : "BAS - Ausbildung - Das Rote Kreuz - Auch du bist ein Teil davon! (QM)", "altName1" : "BAS - Ausbildung - Das Rote Kreuz - auch du bist ein Teil davon!", "altName2" : "", "absolved" : "?" },
                        kurs2 : { "Name" : "SAN - Ausbildung - RS Ambulanzseminar", "altName1" : "", "altName2" : "", "absolved" : "?" },
                        kurs3 : { "Name" : "BAS - Ausbildung - KHD-SD-Praxis", "altName1" : "BAS - Ausbildung - KHD-Praxistag", "altName2" : "", "absolved" : "?" }
                      };

      exportTable.find("tr:gt(0)").append("Berechnen...	");
      exportTable.find("tr:first").append("Grundkurse	");

      exportTable.find("tr:gt(0)").each(function(index, element) {
          var dnr = $(element).find("td:first").text();

            dnrToIdentifier(dnr).then(
            function(result) {
            console.log("dnrToIdentifier result: ENID = " + result.ENID + " / EID = " + result.EID);

            checkCourseAttendance(result.EID, grundkurse).then(
            function(resultDict) {
            $(element).find(".grundkurse").html("Das RK: " + resultDict.kurs1.absolved + "
AmbSem: " + resultDict.kurs2.absolved + "
KHD-SD: " + resultDict.kurs3.absolved);
            },
            function() {
            console.log("grundkurse --> error checkCourseAttendance");
            $(element).find(".grundkurse").text("error checkCourseAttendance");
            });
            },
            function() {
            console.log("grundkurse --> error dnrToIdentifier");
            $(element).find(".grundkurse").text("error dnrToIdentifier");
            });

      });

    });

    addCalculationHandler("#sandienststunden", [{calcname : "dienststunden", uiname : "Dienststunden d. l. 6 Monate"}], function(dnr, name) {
       //verkettete Promises...
       return dnrToIdentifier(dnr).then(
              function(result) {
                console.log("dnrToIdentifier result: ENID = " + result.ENID + " / EID = " + result.EID);
                return calculateDutyStatistic(result.ENID, "");
              }).then(
                function(statresult) {
                  return statresult["hourDutyAs"]["SAN_RD"];
                }
              );
      });

      addCalculationHandler("#rddienste", [{calcname : "rddienste", uiname : "Dienste d. l. 6 Monate"}], function(dnr, name){
        return dnrToIdentifier(dnr).then(
               function(result) {
                 console.log("dnrToIdentifier result: ENID = " + result.ENID + " / EID = " + result.EID);
                 return calculateDutyStatistic(result.ENID, "");
               }).then(
                 function(statresult) {
                   return statresult["countDutyAs"]["SAN_RD"];
                 }
               );
      });

  }); //close $.get(path, function(data) {

});
<commit_msg>DataTable fertig gestellt -> testing wird benötigt<commit_after>/*
TODO: funktion schreiben, die eine spalte hinzufügen kann zur tabelle!
und diese dann am besten über ein callback oder Promise?
so befüllt

  id - id des divs im menü, bei on Click wird die Spalte hinzugefügt und
    für jede zeile das callback mit der dnr aufgerufen
  name - array von dict mit Maschinenname (wird für css klassen etc. verwendet)
          und Menschennamen (wird angezeigt in der ui) der spalten:
            [{calcname : "sandienststunden", uiname: "Dienststunden d. l. 6 Monate"}, ]

  callback - callback, das (dnr, name, td)
        dnr - Dienstnummer
        name - Das DictObject mit classname und Name der Spalte, aus dem names array
        td - die Tabellenzelle als jquery Object
    der Spalte die berechnet werden soll übergeben bekommt,
    der return des callback wird in die tabellenzelle geschrieben

*/
var clicked = {};
function addCalculationHandler(id, names, callback) {

  $(id).click(function() {
    if (id in clicked) { //verhindern, das eine Spalte mehrmals hinzugefügt wird
      return;
    }
    clicked[id] = true;

    var exportTable = $(".export");
    names.forEach( function(name) {
        console.log("addCalculationHandler --> names " + name.calcname + " mit ui "+ name.uiname);

        columns.push({
          data: name.calcname,
          title: name.uiname,
          defaultContent: ""
        });

        initDataTable();

        //TODO: solange das läuft kleines fenster anzeigen bzw. user informieren!
        var ready = Promise.resolve();
        for (index in dataSet) {
          var row = dataSet[index];
          //dataSet[index][name.calcname] = "eins";
          console.log("addCalculationHandler --> lade für dnr: " + row.DNR);

          var p = new Promise(function(resolve, raise) {
               var i = index;
               var r = row;
               var c = columns.length - 1;
               resolve(callback(r.DNR, name)
                .then(function(value) {
                  r[name.calcname] = value;
                  //console.log("get cell: " + i + "#" + c);
                  datatable.cell(i, c).invalidate().draw();
                  console.log("addCalculationHandler --> füge value " + value + " für spalte " + name.calcname + " in dataSet zeile " + i + " dnr: "+ r.DNR + "hinzu");
                })
                .catch(function(error) {
                  console.log("addCalculationHandler -> promise then mit error: " + error);
                }));
          });
          ready = ready.then(function() {
           return p;
          });

        }
        ready.then(function() { //warte auf die promises...
          console.log("addCalculationHandler --> promises should be resolved....refresh DataTable data");

          // columns.push({
          //   data: "testdata",
          //   title: "Leere Daten",
          //   defaultContent: "leer"
          // });

          //initDataTable();  //erzeuge DataTable erneut!
        });

        //exportTable.find("tr:gt(0)").append("Berechnen...	");
        //exportTable.find("tr:first").append("" + names[n].uiname + "	");

        // exportTable.find("tr:gt(0)").each(function(index, element) {
        //   var dnr = $(element).find("td:first").text();
        //   var td = $(element).find("td." + names[n].calcname);
        //   callback(dnr, n).then(
        //     function (value) {
        //       console.log("addCalculationHandler --> promise then value:" + value);
        //         td.text(value);
        //     },
        //     function (error) {
        //         console.log("addCalculationHandler -> promise then mit error: " + error);
        //         td.text(error);
        //     });
        //     //hier darauf warten, dass callback fertig! um niu von zu vielen Requests zu entlasten
        //     //und diese hier seriell abzuarbeiten!
        //
        // });
    });

  });

}

//TODO: die gesamte Tabelle irgendwie sortierbar machen
/*
  eventuell mit plugin wie
  dynatable https://www.dynatable.com/#event-hooks
  tablesorter http://tablesorter.com/docs/

*/

var dataSet = new Array;
var columns = new Array;
// var dataTableColumns = new Array;
var datatable = undefined;
function initDataTable() {
  console.log("initDataTable --> dataSet lenght: " + dataSet.length );
  console.log("initDataTable --> columns: " + columns.length);

  if (!(datatable === undefined)) {
      datatable.destroy();
      console.log("initDataTable --> after destroy: dataSet lenght: " + dataSet.length + " columns: " + columns.length);
      datatable = undefined;
  }
  // var exportTable = $(".export");
  // columns = new Array;
  // //var headers = [];
  // //parse first column also die headers...
  // exportTable.find("tr:first th").each( function(index) {
  //   console.log("index " + index + " mit th " + $(this).text());
  //     //headers.push($(this).text());
  //     columns.push( {
  //       data: $(this).text(),
  //       title: $(this).text()
  //     });
  // });
  // for (index in columns) {
  //     dataTableColumns.push($.extend({}, columns[index]));
  // }

  console.log("initDataTable --> dataSet:" + JSON.stringify(dataSet));
  console.log("initDataTable --> dataTableColumns:" + JSON.stringify(columns));

  $('#datatablediv').empty();

  datatable = $('

')
  $('#datatablediv').append(datatable);

  datatable = datatable.DataTable({
    destroy: true,
    data: dataSet,
    columns: columns
  });

  //verändere css, damit die sorting images angezeigt werden!
  $("#datatable").find(".sorting").css("background-image", 'url("' + chrome.extension.getURL("/img/sort_both.png") + '")');
  $("#datatable").find(".sorting_asc").css("background-image", 'url("' + chrome.extension.getURL("/img/sort_asc.png")  + '")');
  $("#datatable").find(".sorting_desc").css("background-image", 'url("' + chrome.extension.getURL("/img/sort_desc.png")  + '")');

}

$(document).ready(function() {

  var exportTable = $(".export");

  var headers = [];
  //parse first column also die headers...
  exportTable.find("tr:first th").each( function(index) {
    console.log("index " + index + " mit th " + $(this).text());
      headers.push($(this).text());
      columns.push( {
        data: $(this).text(),
        title: $(this).text()
      });
  });

  //parse data
  exportTable.find("tr:gt(0)").each( function(index) {
      var row = {};
      $(this).find("td").each(function(index) {
        row[headers[index]] = $(this).text();
      });
      dataSet.push(row);
  });

  //exportTable.after("
Hallo Welt
");
  exportTable.after("

");
  exportTable.hide();
  initDataTable();

  var header = $("#ctl00_m_Header");

  /*
    lade das Menü, mit den möglichen Berechnungen
    es wäre unklug gleich alle Berechnungen zu machen -> zu viele
    Requests und nicht jeder MA braucht alle Berechnungen
    TODO:
  */
  var path = chrome.extension.getURL("src/webcontent/employee_dump_menu.html");
  console.log("path: " + path);
  $.get(path, function(data) {

    header.after(data);
    //data.menu();
    $("#menu").menu();

    //$("#rddienste").trigger("click");

    addCalculationHandler("#grundkurse", [{calcname : "grundkurse", uiname : "Grundkurse"}], function(dnr, name) {
       //verkettete Promises...

       var grundkurse = {
                           kurs1 : { "Name" : "BAS - Ausbildung - Das Rote Kreuz - Auch du bist ein Teil davon! (QM)", "altName1" : "BAS - Ausbildung - Das Rote Kreuz - auch du bist ein Teil davon!", "altName2" : "", "absolved" : "?" },
                           kurs2 : { "Name" : "SAN - Ausbildung - RS Ambulanzseminar", "altName1" : "", "altName2" : "", "absolved" : "?" },
                           kurs3 : { "Name" : "BAS - Ausbildung - KHD-SD-Praxis", "altName1" : "BAS - Ausbildung - KHD-Praxistag", "altName2" : "", "absolved" : "?" }
                         };

        return dnrToIdentifier(dnr)
        .then(function(result) {
          console.log("dnrToIdentifier result: ENID = " + result.ENID + " / EID = " + result.EID);
          return checkCourseAttendance(result.EID, grundkurse)
        }).then( function(resultDict) {
          return ("Das RK: " + resultDict.kurs1.absolved + "
AmbSem: " + resultDict.kurs2.absolved + "
KHD-SD: " + resultDict.kurs3.absolved);
        });

     });

    // $("#grundkurse").click(function() {
    //   console.log("grundkurse gecklickt!");
    //   if ("grundkurse" in clicked) {
    //     return;
    //   }
    //   clicked["grundkurse"] = true;
    //
    //
    //   var grundkurse = {
    //                     kurs1 : { "Name" : "BAS - Ausbildung - Das Rote Kreuz - Auch du bist ein Teil davon! (QM)", "altName1" : "BAS - Ausbildung - Das Rote Kreuz - auch du bist ein Teil davon!", "altName2" : "", "absolved" : "?" },
    //                     kurs2 : { "Name" : "SAN - Ausbildung - RS Ambulanzseminar", "altName1" : "", "altName2" : "", "absolved" : "?" },
    //                     kurs3 : { "Name" : "BAS - Ausbildung - KHD-SD-Praxis", "altName1" : "BAS - Ausbildung - KHD-Praxistag", "altName2" : "", "absolved" : "?" }
    //                   };
    //
    //   exportTable.find("tr:gt(0)").append("Berechnen...	");
    //   exportTable.find("tr:first").append("Grundkurse	");
    //
    //   exportTable.find("tr:gt(0)").each(function(index, element) {
    //       var dnr = $(element).find("td:first").text();
    //
    //         dnrToIdentifier(dnr).then(
    //         function(result) {
    //         console.log("dnrToIdentifier result: ENID = " + result.ENID + " / EID = " + result.EID);
    //
    //         checkCourseAttendance(result.EID, grundkurse).then(
    //         function(resultDict) {
    //         $(element).find(".grundkurse").html("Das RK: " + resultDict.kurs1.absolved + "
AmbSem: " + resultDict.kurs2.absolved + "
KHD-SD: " + resultDict.kurs3.absolved);
    //         },
    //         function() {
    //         console.log("grundkurse --> error checkCourseAttendance");
    //         $(element).find(".grundkurse").text("error checkCourseAttendance");
    //         });
    //         },
    //         function() {
    //         console.log("grundkurse --> error dnrToIdentifier");
    //         $(element).find(".grundkurse").text("error dnrToIdentifier");
    //         });
    //
    //
    //   });
    //
    // });

    addCalculationHandler("#sandienststunden", [{calcname : "dienststunden", uiname : "Dienststunden d. l. 6 Monate"}], function(dnr, name) {
       //verkettete Promises...
       return dnrToIdentifier(dnr).then(
              function(result) {
                console.log("dnrToIdentifier result: ENID = " + result.ENID + " / EID = " + result.EID);
                return calculateDutyStatistic(result.ENID, "");
              }).then(
                function(statresult) {
                  return statresult["hourDutyAs"]["SAN_RD"];
                }
              );
      });

      addCalculationHandler("#rddienste", [{calcname : "rddienste", uiname : "Dienste d. l. 6 Monate"}], function(dnr, name){
        return dnrToIdentifier(dnr).then(
               function(result) {
                 console.log("dnrToIdentifier result: ENID = " + result.ENID + " / EID = " + result.EID);
                 return calculateDutyStatistic(result.ENID, "");
               }).then(
                 function(statresult) {
                   return statresult["countDutyAs"]["SAN_RD"];
                 }
               );
      });

  }); //close $.get(path, function(data) {

});
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Modulus
 *
 * 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 librarian = require('../common/api').librarian,
    userConfig = require('../common/api').userConfig,
    fs = require('fs'),
    EventEmitter = require('events').EventEmitter,
    util = require('util'),
    request = require('request');

//-----------------------------------------------------------------------------
/**
 * Handles file uploading.
 * Events:
 * error
 * progress
 * end
 */
 //-----------------------------------------------------------------------------
var Uploader = function() {

};

util.inherits(Uploader, EventEmitter);

//-----------------------------------------------------------------------------
/**
 * Uploads a file.
 */
//-----------------------------------------------------------------------------
Uploader.prototype.upload = function(projectId, file, options) {

  var self = this;

  self.uploading = true;

  var endpoint = util.format('%s://%s:%s/project/deploy/%s?authToken=%s&forceNpmInstall=%s&registry=%s',
    librarian._http._ssl ? 'https' : 'http',
    librarian._http._host,
    librarian._http._port,
    projectId,
    userConfig.data.apiKey,
    options.forceNpmInstall,
    options.registry);

  fs.stat(file, function(err, stat) {

    if(err) {
      return self.emit('error', err);
    }

    // Read the file and pipe the contents directly.
    fs.createReadStream(file).pipe(
      request.put(
        {
          method: 'PUT',
          uri : endpoint,
          timeout: 60 * 60 * 1000, // 1 hour
          headers : {
            'content-length' : stat.size
          }
        },
        function(err, res, b) {

          self.uploading = false;

          if(err) {
            return self.emit('error', err);
          }

          //convert the response to an object
          if(typeof b === 'string') {
            try {
              var tmp = JSON.parse(b);
              b = tmp;
            } catch(e) {
              //console out the response body for debugging
              console.log('Unknown body type.');
              console.log(b);
            }
          }

          //check for errors
          if(typeof b === 'object') {
            if(b.error) {
              console.log(b.error);
              return (self.emit('error', 'There was an error uploading.'));
            } else if(b.errors) {
              return self.emit('error', b.errors[0].message);
            }
          }

          // Send a final progress emit so the user always sees 100%.
          self.emit('progress', 1);

          // Do next tick so the UI can actually update to 100% before
          // continuing.
          process.nextTick(function() {
            self.emit('end');
          });
        }
      )
    );
  });

  self.monitorProgress(projectId);
};

//-----------------------------------------------------------------------------
/**
 * Periodically requests upload progress information.
 * @param {string} projectId The project ID.
 */
//-----------------------------------------------------------------------------
Uploader.prototype.monitorProgress = function(projectId) {

  var self = this;

  var getStatus = function() {
    librarian.project.uploadProgress(projectId, userConfig.data.apiKey, function(err, result) {

      // If an error does occur, just ignore it and continue trying to get the progress.
      if(!err) {
        if(self.uploading) {
          self.emit('progress', result.progress);
        }
      }

      // Wait a second and get status again.
      if(self.uploading) {
        setTimeout(getStatus, 1000);
      }
    });
  };

  setTimeout(getStatus, 1000);
};

module.exports = Uploader;
<commit_msg>corrected an issue with running tests<commit_after>/*
 * Copyright (c) 2014 Modulus
 *
 * 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 librarian = require('../common/api').librarian,
    userConfig = require('../common/api').userConfig,
    fs = require('fs'),
    EventEmitter = require('events').EventEmitter,
    util = require('util'),
    request = require('request');

//-----------------------------------------------------------------------------
/**
 * Handles file uploading.
 * Events:
 * error
 * progress
 * end
 */
 //-----------------------------------------------------------------------------
var Uploader = function() {

};

util.inherits(Uploader, EventEmitter);

//-----------------------------------------------------------------------------
/**
 * Uploads a file.
 */
//-----------------------------------------------------------------------------
Uploader.prototype.upload = function(projectId, file, options) {

  var self = this;

  self.uploading = true;

  var endpoint = util.format(
    '%s://%s:%s/project/deploy/%s?authToken=%s&forceNpmInstall=%s&registry=%s&withTests=%s',
    librarian._http._ssl ? 'https' : 'http',
    librarian._http._host,
    librarian._http._port,
    projectId,
    userConfig.data.apiKey,
    options.forceNpmInstall,
    options.registry,
    options.withTests
  );

  fs.stat(file, function(err, stat) {

    if(err) {
      return self.emit('error', err);
    }

    // Read the file and pipe the contents directly.
    fs.createReadStream(file).pipe(
      request.put(
        {
          method: 'PUT',
          uri : endpoint,
          timeout: 60 * 60 * 1000, // 1 hour
          headers : {
            'content-length' : stat.size
          }
        },
        function(err, res, b) {

          self.uploading = false;

          if(err) {
            return self.emit('error', err);
          }

          //convert the response to an object
          if(typeof b === 'string') {
            try {
              var tmp = JSON.parse(b);
              b = tmp;
            } catch(e) {
              //console out the response body for debugging
              console.log('Unknown body type.');
              console.log(b);
            }
          }

          //check for errors
          if(typeof b === 'object') {
            if(b.error) {
              console.log(b.error);
              return (self.emit('error', 'There was an error uploading.'));
            } else if(b.errors) {
              return self.emit('error', b.errors[0].message);
            }
          }

          // Send a final progress emit so the user always sees 100%.
          self.emit('progress', 1);

          // Do next tick so the UI can actually update to 100% before
          // continuing.
          process.nextTick(function() {
            self.emit('end');
          });
        }
      )
    );
  });

  self.monitorProgress(projectId);
};

//-----------------------------------------------------------------------------
/**
 * Periodically requests upload progress information.
 * @param {string} projectId The project ID.
 */
//-----------------------------------------------------------------------------
Uploader.prototype.monitorProgress = function(projectId) {

  var self = this;

  var getStatus = function() {
    librarian.project.uploadProgress(projectId, userConfig.data.apiKey, function(err, result) {

      // If an error does occur, just ignore it and continue trying to get the progress.
      if(!err) {
        if(self.uploading) {
          self.emit('progress', result.progress);
        }
      }

      // Wait a second and get status again.
      if(self.uploading) {
        setTimeout(getStatus, 1000);
      }
    });
  };

  setTimeout(getStatus, 1000);
};

module.exports = Uploader;
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import update from 'react/lib/update';
import { DropTarget } from 'react-dnd';
import shouldPureComponentUpdate from './utils/shouldPureComponentUpdate';
import ItemTypes from './utils/ItemTypes';
import DraggableElement from './DraggableElement';
import NonDraggableElement from './NonDraggableElement';
import snapToGrid from './utils/snapToGrid';
import { connect } from 'react-redux';
import { setElementXY, deleteElement, setSize } from '../reducers/elements'

// const styles = {
//   width: '795',
//   height: 500,
//   border: '1px solid #607D8B',
//   position: 'relative',
// };

function getStyles (props) {
  let border = props.editable ? '1px solid #607D8B' : "none"

  return {
    width: '795',
    height: 500,
    border: border,
    position: 'border',
  }
}

const elementTarget = {
  drop(props, monitor, component) {
    const delta = monitor.getDifferenceFromInitialOffset()
    const item = monitor.getItem()

    let left = Math.round(item.left + delta.x)
    let top = Math.round(item.top + delta.y)
    if (props.snapToGrid) {
      [left, top] = snapToGrid(left, top)
    }
    component.moveElement(item.type, item.id, left, top, item.zIndex)
  },
};

class Page extends Component {
  static propTypes = {
    connectDropTarget: PropTypes.func.isRequired,
    snapToGrid: PropTypes.bool.isRequired,
  }

  shouldComponentUpdate = shouldPureComponentUpdate;

  moveElement(type, id, left, top, zIndex) {
    const selected = this.props.selected
    if(this.props.deleteMode) {
      let elementToDelete = {
        type: type,
        id: id,
      }

      this.props.clearSelectedIfDeleted(type, id)
      this.props.deleteElement(elementToDelete)
    } else {
      this.props.selectElement(type, id, zIndex)

      let elementUpdate = {
        type: type,
        id: id,
        left: left,
        top: top,
      }

      this.props.setElementXY(elementUpdate)
    }
  }

  renderElement(item, key, type) {
    if (this.props.editable) return <DraggableElement key={key} id={key} type={type} {...item} />
    else return <NonDraggableElement key={key} id={key} type={type} {...item} />
  }

  render() {
    const { connectDropTarget } = this.props
    const { elements } = this.props

    return connectDropTarget(

        {Object
          .keys(elements)
          .map(type => {
            return Object.keys(elements[type])
            .map((elementId) => {
              var currentEl = elements[type][elementId];
              return this.renderElement(currentEl, elementId, type)
            })
          })
        }

,
    );
  }
}

const mapStateToProps = state => state

// wraps Page component with DropTarget capabilities from react-dnd,
// similar to the redux connect function
Page = DropTarget(ItemTypes.ELEMENT, elementTarget, connect => ({
  connectDropTarget: connect.dropTarget(),
}))(Page)

Page = connect(mapStateToProps, { setElementXY, deleteElement, setSize })(Page)

export default Page
<commit_msg>Update Page.js<commit_after>import React, { Component, PropTypes } from 'react';
import update from 'react/lib/update';
import { DropTarget } from 'react-dnd';
import shouldPureComponentUpdate from './utils/shouldPureComponentUpdate';
import ItemTypes from './utils/ItemTypes';
import DraggableElement from './DraggableElement';
import NonDraggableElement from './NonDraggableElement';
import snapToGrid from './utils/snapToGrid';
import { connect } from 'react-redux';
import { setElementXY, deleteElement, setSize } from '../reducers/elements'

function getStyles (props) {
  let border = props.editable ? '1px solid #607D8B' : "none"

  return {
    width: '795',
    height: 500,
    border: border,
    position: 'relative',
  }
}

const elementTarget = {
  drop(props, monitor, component) {
    const delta = monitor.getDifferenceFromInitialOffset()
    const item = monitor.getItem()

    let left = Math.round(item.left + delta.x)
    let top = Math.round(item.top + delta.y)
    if (props.snapToGrid) {
      [left, top] = snapToGrid(left, top)
    }
    component.moveElement(item.type, item.id, left, top, item.zIndex)
  },
};

class Page extends Component {
  static propTypes = {
    connectDropTarget: PropTypes.func.isRequired,
    snapToGrid: PropTypes.bool.isRequired,
  }

  shouldComponentUpdate = shouldPureComponentUpdate;

  moveElement(type, id, left, top, zIndex) {
    const selected = this.props.selected
    if(this.props.deleteMode) {
      let elementToDelete = {
        type: type,
        id: id,
      }

      this.props.clearSelectedIfDeleted(type, id)
      this.props.deleteElement(elementToDelete)
    } else {
      this.props.selectElement(type, id, zIndex)

      let elementUpdate = {
        type: type,
        id: id,
        left: left,
        top: top,
      }

      this.props.setElementXY(elementUpdate)
    }
  }

  renderElement(item, key, type) {
    if (this.props.editable) return <DraggableElement key={key} id={key} type={type} {...item} />
    else return <NonDraggableElement key={key} id={key} type={type} {...item} />
  }

  render() {
    const { connectDropTarget } = this.props
    const { elements } = this.props

    return connectDropTarget(

        {Object
          .keys(elements)
          .map(type => {
            return Object.keys(elements[type])
            .map((elementId) => {
              var currentEl = elements[type][elementId];
              return this.renderElement(currentEl, elementId, type)
            })
          })
        }

,
    );
  }
}

const mapStateToProps = state => state

// wraps Page component with DropTarget capabilities from react-dnd,
// similar to the redux connect function
Page = DropTarget(ItemTypes.ELEMENT, elementTarget, connect => ({
  connectDropTarget: connect.dropTarget(),
}))(Page)

Page = connect(mapStateToProps, { setElementXY, deleteElement, setSize })(Page)

export default Page
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc directive
 * @name ngClick
 *
 * @description
 * The ngClick directive allows you to specify custom behavior when
 * an element is clicked.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngClick {@link guide/expression Expression} to evaluate upon
 * click. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-click="count = count + 1" ng-init="count=0">
        Increment
      </button>
      count: {{count}}
     </file>
     <file name="protractor.js" type="protractor">
       it('should check ng-click', function() {
         expect(element(by.binding('count')).getText()).toMatch('0');
         element(by.css('button')).click();
         expect(element(by.binding('count')).getText()).toMatch('1');
       });
     </file>
   </example>
 */
/*
 * A directive that allows creation of custom onclick handlers that are defined as angular
 * expressions and are compiled and executed within the current scope.
 *
 * Events that are handled via these handler are always configured not to propagate further.
 */
var ngEventDirectives = {};
forEach(
  'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
  function(name) {
    var directiveName = directiveNormalize('ng-' + name);
    ngEventDirectives[directiveName] = ['$parse', function($parse) {
      return {
        restrict: 'A',
        compile: function($element, attr) {
          var fn = $parse(attr[directiveName]);
          return function ngEventHandler(scope, element) {
            element.on(lowercase(name), function(event) {
              scope.$apply(function() {
                fn(scope, {$event:event});
              });
            });
          };
        }
      };
    }];
  }
);

/**
 * @ngdoc directive
 * @name ngDblclick
 *
 * @description
 * The `ngDblclick` directive allows you to specify custom behavior on a dblclick event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon
 * a dblclick. (The Event object is available as `$event`)
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-dblclick="count = count + 1" ng-init="count=0">
        Increment (on double click)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMousedown
 *
 * @description
 * The ngMousedown directive allows you to specify custom behavior on mousedown event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon
 * mousedown. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mousedown="count = count + 1" ng-init="count=0">
        Increment (on mouse down)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMouseup
 *
 * @description
 * Specify custom behavior on mouseup event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon
 * mouseup. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseup="count = count + 1" ng-init="count=0">
        Increment (on mouse up)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMouseover
 *
 * @description
 * Specify custom behavior on mouseover event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon
 * mouseover. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseover="count = count + 1" ng-init="count=0">
        Increment (when mouse is over)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMouseenter
 *
 * @description
 * Specify custom behavior on mouseenter event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon
 * mouseenter. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseenter="count = count + 1" ng-init="count=0">
        Increment (when mouse enters)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMouseleave
 *
 * @description
 * Specify custom behavior on mouseleave event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon
 * mouseleave. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseleave="count = count + 1" ng-init="count=0">
        Increment (when mouse leaves)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMousemove
 *
 * @description
 * Specify custom behavior on mousemove event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon
 * mousemove. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mousemove="count = count + 1" ng-init="count=0">
        Increment (when mouse moves)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngKeydown
 *
 * @description
 * Specify custom behavior on keydown event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
 * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-keydown="count = count + 1" ng-init="count=0">
      key down count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngKeyup
 *
 * @description
 * Specify custom behavior on keyup event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
 * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
 *
 * @example
   <example>
     <file name="index.html">

Typing in the input box below updates the key count

       <input ng-keyup="count = count + 1" ng-init="count=0"> key up count: {{count}}

Typing in the input box below updates the keycode

       <input ng-keyup="event=$event">

event keyCode: {{ event.keyCode }}

event altKey: {{ event.altKey }}

     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngKeypress
 *
 * @description
 * Specify custom behavior on keypress event.
 *
 * @element ANY
 * @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon
 * keypress. ({@link guide/expression#-event- Event object is available as `$event`}
 * and can be interrogated for keyCode, altKey, etc.)
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-keypress="count = count + 1" ng-init="count=0">
      key press count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngSubmit
 *
 * @description
 * Enables binding angular expressions to onsubmit events.
 *
 * Additionally it prevents the default action (which for form means sending the request to the
 * server and reloading the current page), but only if the form does not contain `action`,
 * `data-action`, or `x-action` attributes.
 *
 * @element form
 * @priority 0
 * @param {expression} ngSubmit {@link guide/expression Expression} to eval.
 * ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example module="submitExample">
     <file name="index.html">

      <form ng-submit="submit()" ng-controller="ExampleController">
        Enter text and hit enter:
        <input type="text" ng-model="text" name="text" />
        <input type="submit" id="submit" value="Submit" />

list={{list}}

      </form>
     </file>
     <file name="protractor.js" type="protractor">
       it('should check ng-submit', function() {
         expect(element(by.binding('list')).getText()).toBe('list=[]');
         element(by.css('#submit')).click();
         expect(element(by.binding('list')).getText()).toContain('hello');
         expect(element(by.model('text')).getAttribute('value')).toBe('');
       });
       it('should ignore empty strings', function() {
         expect(element(by.binding('list')).getText()).toBe('list=[]');
         element(by.css('#submit')).click();
         element(by.css('#submit')).click();
         expect(element(by.binding('list')).getText()).toContain('hello');
        });
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngFocus
 *
 * @description
 * Specify custom behavior on focus event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon
 * focus. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
 * See {@link ng.directive:ngClick ngClick}
 */

/**
 * @ngdoc directive
 * @name ngBlur
 *
 * @description
 * Specify custom behavior on blur event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon
 * blur. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
 * See {@link ng.directive:ngClick ngClick}
 */

/**
 * @ngdoc directive
 * @name ngCopy
 *
 * @description
 * Specify custom behavior on copy event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngCopy {@link guide/expression Expression} to evaluate upon
 * copy. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-copy="copied=true" ng-init="copied=false; value='copy me'" ng-model="value">
      copied: {{copied}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngCut
 *
 * @description
 * Specify custom behavior on cut event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngCut {@link guide/expression Expression} to evaluate upon
 * cut. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-cut="cut=true" ng-init="cut=false; value='cut me'" ng-model="value">
      cut: {{cut}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngPaste
 *
 * @description
 * Specify custom behavior on paste event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngPaste {@link guide/expression Expression} to evaluate upon
 * paste. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-paste="paste=true" ng-init="paste=false" placeholder='paste here'>
      pasted: {{paste}}
     </file>
   </example>
 */
<commit_msg>docs(ngSubmit): add link to `form` docs to discourage double submission<commit_after>'use strict';

/**
 * @ngdoc directive
 * @name ngClick
 *
 * @description
 * The ngClick directive allows you to specify custom behavior when
 * an element is clicked.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngClick {@link guide/expression Expression} to evaluate upon
 * click. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-click="count = count + 1" ng-init="count=0">
        Increment
      </button>
      count: {{count}}
     </file>
     <file name="protractor.js" type="protractor">
       it('should check ng-click', function() {
         expect(element(by.binding('count')).getText()).toMatch('0');
         element(by.css('button')).click();
         expect(element(by.binding('count')).getText()).toMatch('1');
       });
     </file>
   </example>
 */
/*
 * A directive that allows creation of custom onclick handlers that are defined as angular
 * expressions and are compiled and executed within the current scope.
 *
 * Events that are handled via these handler are always configured not to propagate further.
 */
var ngEventDirectives = {};
forEach(
  'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
  function(name) {
    var directiveName = directiveNormalize('ng-' + name);
    ngEventDirectives[directiveName] = ['$parse', function($parse) {
      return {
        restrict: 'A',
        compile: function($element, attr) {
          var fn = $parse(attr[directiveName]);
          return function ngEventHandler(scope, element) {
            element.on(lowercase(name), function(event) {
              scope.$apply(function() {
                fn(scope, {$event:event});
              });
            });
          };
        }
      };
    }];
  }
);

/**
 * @ngdoc directive
 * @name ngDblclick
 *
 * @description
 * The `ngDblclick` directive allows you to specify custom behavior on a dblclick event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngDblclick {@link guide/expression Expression} to evaluate upon
 * a dblclick. (The Event object is available as `$event`)
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-dblclick="count = count + 1" ng-init="count=0">
        Increment (on double click)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMousedown
 *
 * @description
 * The ngMousedown directive allows you to specify custom behavior on mousedown event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMousedown {@link guide/expression Expression} to evaluate upon
 * mousedown. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mousedown="count = count + 1" ng-init="count=0">
        Increment (on mouse down)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMouseup
 *
 * @description
 * Specify custom behavior on mouseup event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseup {@link guide/expression Expression} to evaluate upon
 * mouseup. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseup="count = count + 1" ng-init="count=0">
        Increment (on mouse up)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMouseover
 *
 * @description
 * Specify custom behavior on mouseover event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseover {@link guide/expression Expression} to evaluate upon
 * mouseover. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseover="count = count + 1" ng-init="count=0">
        Increment (when mouse is over)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMouseenter
 *
 * @description
 * Specify custom behavior on mouseenter event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseenter {@link guide/expression Expression} to evaluate upon
 * mouseenter. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseenter="count = count + 1" ng-init="count=0">
        Increment (when mouse enters)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMouseleave
 *
 * @description
 * Specify custom behavior on mouseleave event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMouseleave {@link guide/expression Expression} to evaluate upon
 * mouseleave. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mouseleave="count = count + 1" ng-init="count=0">
        Increment (when mouse leaves)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngMousemove
 *
 * @description
 * Specify custom behavior on mousemove event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngMousemove {@link guide/expression Expression} to evaluate upon
 * mousemove. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <button ng-mousemove="count = count + 1" ng-init="count=0">
        Increment (when mouse moves)
      </button>
      count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngKeydown
 *
 * @description
 * Specify custom behavior on keydown event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
 * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-keydown="count = count + 1" ng-init="count=0">
      key down count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngKeyup
 *
 * @description
 * Specify custom behavior on keyup event.
 *
 * @element ANY
 * @priority 0
 * @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
 * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
 *
 * @example
   <example>
     <file name="index.html">

Typing in the input box below updates the key count

       <input ng-keyup="count = count + 1" ng-init="count=0"> key up count: {{count}}

Typing in the input box below updates the keycode

       <input ng-keyup="event=$event">

event keyCode: {{ event.keyCode }}

event altKey: {{ event.altKey }}

     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngKeypress
 *
 * @description
 * Specify custom behavior on keypress event.
 *
 * @element ANY
 * @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon
 * keypress. ({@link guide/expression#-event- Event object is available as `$event`}
 * and can be interrogated for keyCode, altKey, etc.)
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-keypress="count = count + 1" ng-init="count=0">
      key press count: {{count}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngSubmit
 *
 * @description
 * Enables binding angular expressions to onsubmit events.
 *
 * Additionally it prevents the default action (which for form means sending the request to the
 * server and reloading the current page), but only if the form does not contain `action`,
 * `data-action`, or `x-action` attributes.
 *
 *

 * **Warning:** Be careful not to cause "double-submission" by using both the `ngClick` and
 * `ngSubmit` handlers together. See the
 * {@link form#submitting-a-form-and-preventing-the-default-action `form` directive documentation}
 * for a detailed discussion of when `ngSubmit` may be triggered.
 *

 *
 * @element form
 * @priority 0
 * @param {expression} ngSubmit {@link guide/expression Expression} to eval.
 * ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example module="submitExample">
     <file name="index.html">

      <form ng-submit="submit()" ng-controller="ExampleController">
        Enter text and hit enter:
        <input type="text" ng-model="text" name="text" />
        <input type="submit" id="submit" value="Submit" />

list={{list}}

      </form>
     </file>
     <file name="protractor.js" type="protractor">
       it('should check ng-submit', function() {
         expect(element(by.binding('list')).getText()).toBe('list=[]');
         element(by.css('#submit')).click();
         expect(element(by.binding('list')).getText()).toContain('hello');
         expect(element(by.model('text')).getAttribute('value')).toBe('');
       });
       it('should ignore empty strings', function() {
         expect(element(by.binding('list')).getText()).toBe('list=[]');
         element(by.css('#submit')).click();
         element(by.css('#submit')).click();
         expect(element(by.binding('list')).getText()).toContain('hello');
        });
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngFocus
 *
 * @description
 * Specify custom behavior on focus event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon
 * focus. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
 * See {@link ng.directive:ngClick ngClick}
 */

/**
 * @ngdoc directive
 * @name ngBlur
 *
 * @description
 * Specify custom behavior on blur event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon
 * blur. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
 * See {@link ng.directive:ngClick ngClick}
 */

/**
 * @ngdoc directive
 * @name ngCopy
 *
 * @description
 * Specify custom behavior on copy event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngCopy {@link guide/expression Expression} to evaluate upon
 * copy. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-copy="copied=true" ng-init="copied=false; value='copy me'" ng-model="value">
      copied: {{copied}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngCut
 *
 * @description
 * Specify custom behavior on cut event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngCut {@link guide/expression Expression} to evaluate upon
 * cut. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-cut="cut=true" ng-init="cut=false; value='cut me'" ng-model="value">
      cut: {{cut}}
     </file>
   </example>
 */

/**
 * @ngdoc directive
 * @name ngPaste
 *
 * @description
 * Specify custom behavior on paste event.
 *
 * @element window, input, select, textarea, a
 * @priority 0
 * @param {expression} ngPaste {@link guide/expression Expression} to evaluate upon
 * paste. ({@link guide/expression#-event- Event object is available as `$event`})
 *
 * @example
   <example>
     <file name="index.html">
      <input ng-paste="paste=true" ng-init="paste=false" placeholder='paste here'>
      pasted: {{paste}}
     </file>
   </example>
 */
<|endoftext|>


<commit_before>import React from 'react';
import { getDb } from 'api/rxdb';

export default class Find extends React.Component {
  state = {
    data: null
  }
  async componentWillMount() {
    const { collection, query, reactive } = this.props;
    const db = getDb();
    const queryObj = db[collection].find(query);
    if (reactive === true) {
      this.subscription = queryObj.$.subscribe(data => {
        this.setState({ data });
      });
    } else {
      const data = await queryObj.exec();
      this.setState({ data });
    }
  }
  componentWillUnmount() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
  render() {
    return (
      <this.props.view {...this.state} />
    );
  }
}
<commit_msg>Rxdb class component renamed + errors exposed now too<commit_after>import React from 'react';
import { getDb } from 'api/rxdb';

class Rxdb extends React.Component {
  state = {
    data: null,
    error: null
  }
  async componentWillMount() {
    try {
      const { collection, query, reactive } = this.props;
      const db = getDb();
      const queryObj = db[collection].find(query);
      if (reactive === true) {
        this.subscription = queryObj.$.subscribe(data => {
          this.setState({ data });
        });
      } else {
        const data = await queryObj.exec();
        this.setState({ data });
      }
    } catch (error) {
      this.setState({ error });
    }
  }
  componentWillUnmount() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
  render() {
    return (
      <this.props.view {...this.state} />
    );
  }
}

export default Rxdb;<|endoftext|>


<commit_before>'use strict';

let Promise = require('bluebird'),
  webdriver = require('selenium-webdriver'),
  chrome = require('./chrome'),
  firefox = require('./firefox');

/**
 * Create a new WebDriver instance based on the specified options.
 * @param {Object} options the options for a web driver.
 * @returns {!Promise<webdriver.WebDriver>} a promise that resolves to the webdriver,
 * or rejects if the current configuration is invalid.
 */
module.exports.createWebDriver = function(options) {
  const browser = options.browser || 'chrome';
  const seleniumUrl = options.selenium ? options.selenium.url : undefined;
  const builder = new webdriver.Builder()
    .forBrowser(browser)
    .usingServer(seleniumUrl);

  switch (browser) {
    case 'chrome':
      chrome.configureBuilder(builder, options);
      break;

    case 'firefox':
      firefox.configureBuilder(builder, options);
      break;

    default:
      return Promise.reject(new Error('Unsupported browser: ' + browser));
  }

  return Promise.try(() => builder.build());
};
<commit_msg>Support setting custom capabilities (#325)<commit_after>'use strict';

let Promise = require('bluebird'),
  webdriver = require('selenium-webdriver'),
  isEmpty = require('lodash.isempty'),
  chrome = require('./chrome'),
  firefox = require('./firefox');

/**
 * Create a new WebDriver instance based on the specified options.
 * @param {Object} options the options for a web driver.
 * @returns {!Promise<webdriver.WebDriver>} a promise that resolves to the webdriver,
 * or rejects if the current configuration is invalid.
 */
module.exports.createWebDriver = function(options) {
  const browser = options.browser || 'chrome';
  const seleniumUrl = options.selenium ? options.selenium.url : undefined;
  const capabilities = options.selenium ? options.selenium.capabilities : undefined;
  const builder = new webdriver.Builder()
    .forBrowser(browser)
    .usingServer(seleniumUrl);

  if (capabilities && !isEmpty(capabilities)) {
    builder.withCapabilities(capabilities);
  }

  switch (browser) {
    case 'chrome':
      chrome.configureBuilder(builder, options);
      break;

    case 'firefox':
      firefox.configureBuilder(builder, options);
      break;

    default:
      return Promise.reject(new Error('Unsupported browser: ' + browser));
  }

  return Promise.try(() => builder.build());
};
<|endoftext|>


<commit_before>'use strict'
require('../sass/reset.scss')
require('../sass/normalize.scss')
require('../sass/normalize-opentype.scss')
require('../sass/base.scss')
require.context('../assets/images')

const React = require('react')

const imageCanvasStyle = `
  .image-canvas {
    background: url("canvas.jpg") no-repeat center center fixed;
    background-size: cover
  }
`

function Page ({ body, content, css, js }) {
  return (

        <title>Derek Lieu</title>
        {css.map((href, i) => <link rel="stylesheet" key={`css-${i}`} href={'/' + href}/>)}