<commit_before>/*
 * grunt-data-uri
 * http://github.com/ahomu/grunt-data-uri
 * http://aho.mu
 *
 * Copyright (c) 2012 ahomu
 * Licensed under the MIT license.
 */
module.exports = function(grunt) {

  'use strict';

  var fs       = require('fs'),
      path     = require('path'),
      datauri  = require('datauri');

  var RE_CSS_URLFUNC = /(?:url\(["']?)(.*?)(?:["']?\))/,
      util = grunt.util,
      gruntfileDir = path.resolve('./'),
      expandFiles;

  if (grunt.file.expandFiles) {
    expandFiles = grunt.file.expandFiles;
  } else {
    expandFiles = function(files) {
      return grunt.file.expand({filter: 'isFile'}, files);
    };
  }

  grunt.registerMultiTask('dataUri', 'Convert your css file image path!!', function() {

    var options  = this.options(),
        srcFiles = expandFiles(this.data.src),
        destDir  = path.resolve(this.data.dest),
        haystack = [];

    expandFiles(options.target).forEach(function(imgPath) {
      haystack.push(path.resolve(imgPath));
    });

    srcFiles.forEach(function(src) {
      var content  = grunt.file.read(src),
          matches  = content.match(new RegExp(RE_CSS_URLFUNC.source, 'g')),
          outputTo = destDir+'/'+path.basename(src),
          baseDir,
          uris;

      // Detect baseDir for using traversal image files
      baseDir = options.baseDir ? path.resolve(options.baseDir)    // specified base dir
                                : path.resolve(path.dirname(src)); // detected from src

      // Not found image path
      if (!matches) {
        grunt.log.subhead('SRC: file uri not found on '+src);
        grunt.file.write(outputTo, content);
        grunt.log.ok('Skipped');
        grunt.log.ok('=> ' + outputTo);
        return;
      }

      // Change base to src(css, html, js) existing dir
      grunt.file.setBase(baseDir);

      // List uniq image URIs
      uris = util._.uniq(matches.map(function(m) {
        return m.match(RE_CSS_URLFUNC)[1];
      }));

      // Exclude external http resource
      uris = uris.filter(function(u) {
        return !u.match('(data:|http)');
      });

      grunt.log.subhead('SRC: '+uris.length+' file uri found on '+src);

      // Process urls
      uris.forEach(function(uri) {
        var src, replacement, needle, fixedUri;

        // fixed current dir when specified uri is like root
        fixedUri = (uri.indexOf('/') === 0 ? '.' + uri : uri).split('?')[0].split('#')[0];

        // Resolve image realpath
        needle = path.resolve(fixedUri);

        // Assume file existing cause found from haystack
        if (haystack.indexOf(needle) !== -1) {

          // check if file exceeds the max bytes
          var fileSize = getFileSize(needle);
          if (options.maxBytes && fileSize > options.maxBytes) {
            // file is over the max size
            grunt.log.ok('Skipping (size ' + fileSize + ' > ' + options.maxBytes +'): ' + uri);
            return;
          } else {
            // Encoding to Data uri
            replacement = datauri(needle);

            grunt.log.ok('Encode: '+needle);
          }
        } else {
          if (options.fixDirLevel) {
            // Diff of directory level
            replacement = adjustDirectoryLevel(fixedUri, destDir, baseDir);
            grunt.log.ok('Adjust: '+ uri + ' -> ' + replacement);
          } else {
            replacement = uri;
            grunt.log.ok('Ignore: '+ uri);
          }
        }

        content = content.replace(new RegExp(uri, 'g'), replacement);
      });

      // Revert base to gruntjs executing current dir
      grunt.file.setBase(gruntfileDir);
      grunt.file.write(outputTo, content);
      grunt.log.ok('=> ' + outputTo);
    });
  });

  /**
   *
   * @param fullPath
   * @param options
   * @return {boolean} the file size, or undefined if not found
   */
  function getFileSize(fullPath) {

    if (!fs.existsSync(fullPath)) {
      return false;
    }

    var stats = fs.statSync(fullPath);
    if (!stats.isFile()) {
      return false;
    }
    return stats.size;
  }

  /**
   * @method adjustDirectoryLevel
   * @param {String} relativePath
   * @param {String} toDir
   * @param {String} fromDir
   * @return {String} resolvedPath
   */
  function adjustDirectoryLevel(relativePath, toDir, fromDir) {
    // fix ../path/to/img.jpg to path/to/img.jpg
    var resolvedPath = relativePath.replace(/^\.\//, '');

    if (toDir === fromDir) {
      // both toDir and fromDir are same base.
    }
    else if (fromDir.indexOf(toDir) === 0) {
      // fromDir is shallow than toDir
      path.relative(fromDir, toDir).split('/').forEach(function() {
        resolvedPath = resolvedPath.replace(/^\.\.\//, '');
      });
    }
    else if (toDir.indexOf(fromDir) === 0 ) {
      // toDir is deep than fromDir
      path.relative(fromDir, toDir).split('/').forEach(function() {
        resolvedPath = '../'+resolvedPath;
      });
    }
    return resolvedPath;
  }

};
<commit_msg>question marks in path caused not to replace (other characters may need to be escaped as well)<commit_after>/*
 * grunt-data-uri
 * http://github.com/ahomu/grunt-data-uri
 * http://aho.mu
 *
 * Copyright (c) 2012 ahomu
 * Licensed under the MIT license.
 */
module.exports = function(grunt) {

  'use strict';

  var fs       = require('fs'),
      path     = require('path'),
      datauri  = require('datauri');

  var RE_CSS_URLFUNC = /(?:url\(["']?)(.*?)(?:["']?\))/,
      util = grunt.util,
      gruntfileDir = path.resolve('./'),
      expandFiles;

  if (grunt.file.expandFiles) {
    expandFiles = grunt.file.expandFiles;
  } else {
    expandFiles = function(files) {
      return grunt.file.expand({filter: 'isFile'}, files);
    };
  }

  grunt.registerMultiTask('dataUri', 'Convert your css file image path!!', function() {

    var options  = this.options(),
        srcFiles = expandFiles(this.data.src),
        destDir  = path.resolve(this.data.dest),
        haystack = [];

    expandFiles(options.target).forEach(function(imgPath) {
      haystack.push(path.resolve(imgPath));
    });

    srcFiles.forEach(function(src) {
      var content  = grunt.file.read(src),
          matches  = content.match(new RegExp(RE_CSS_URLFUNC.source, 'g')),
          outputTo = destDir+'/'+path.basename(src),
          baseDir,
          uris;

      // Detect baseDir for using traversal image files
      baseDir = options.baseDir ? path.resolve(options.baseDir)    // specified base dir
                                : path.resolve(path.dirname(src)); // detected from src

      // Not found image path
      if (!matches) {
        grunt.log.subhead('SRC: file uri not found on '+src);
        grunt.file.write(outputTo, content);
        grunt.log.ok('Skipped');
        grunt.log.ok('=> ' + outputTo);
        return;
      }

      // Change base to src(css, html, js) existing dir
      grunt.file.setBase(baseDir);

      // List uniq image URIs
      uris = util._.uniq(matches.map(function(m) {
        return m.match(RE_CSS_URLFUNC)[1];
      }));

      // Exclude external http resource
      uris = uris.filter(function(u) {
        return !u.match('(data:|http)');
      });

      grunt.log.subhead('SRC: '+uris.length+' file uri found on '+src);

      // Process urls
      uris.forEach(function(uri) {
        var src, replacement, needle, fixedUri;

        // fixed current dir when specified uri is like root
        fixedUri = (uri.indexOf('/') === 0 ? '.' + uri : uri).split('?')[0].split('#')[0];

        // Resolve image realpath
        needle = path.resolve(fixedUri);

        // Assume file existing cause found from haystack
        if (haystack.indexOf(needle) !== -1) {

          // check if file exceeds the max bytes
          var fileSize = getFileSize(needle);
          if (options.maxBytes && fileSize > options.maxBytes) {
            // file is over the max size
            grunt.log.ok('Skipping (size ' + fileSize + ' > ' + options.maxBytes +'): ' + uri);
            return;
          } else {
            // Encoding to Data uri
            replacement = datauri(needle);

            grunt.log.ok('Encode: '+needle);
          }
        } else {
          if (options.fixDirLevel) {
            // Diff of directory level
            replacement = adjustDirectoryLevel(fixedUri, destDir, baseDir);
            grunt.log.ok('Adjust: '+ uri + ' -> ' + replacement);
          } else {
            replacement = uri;
            grunt.log.ok('Ignore: '+ uri);
          }
        }

        var escapedUri = uri.replace(/\?/g, '\\$&');
        content = content.replace(new RegExp(escapedUri, 'g'), replacement);
      });

      // Revert base to gruntjs executing current dir
      grunt.file.setBase(gruntfileDir);
      grunt.file.write(outputTo, content);
      grunt.log.ok('=> ' + outputTo);
    });
  });

  /**
   *
   * @param fullPath
   * @param options
   * @return {boolean} the file size, or undefined if not found
   */
  function getFileSize(fullPath) {

    if (!fs.existsSync(fullPath)) {
      return false;
    }

    var stats = fs.statSync(fullPath);
    if (!stats.isFile()) {
      return false;
    }
    return stats.size;
  }

  /**
   * @method adjustDirectoryLevel
   * @param {String} relativePath
   * @param {String} toDir
   * @param {String} fromDir
   * @return {String} resolvedPath
   */
  function adjustDirectoryLevel(relativePath, toDir, fromDir) {
    // fix ../path/to/img.jpg to path/to/img.jpg
    var resolvedPath = relativePath.replace(/^\.\//, '');

    if (toDir === fromDir) {
      // both toDir and fromDir are same base.
    }
    else if (fromDir.indexOf(toDir) === 0) {
      // fromDir is shallow than toDir
      path.relative(fromDir, toDir).split('/').forEach(function() {
        resolvedPath = resolvedPath.replace(/^\.\.\//, '');
      });
    }
    else if (toDir.indexOf(fromDir) === 0 ) {
      // toDir is deep than fromDir
      path.relative(fromDir, toDir).split('/').forEach(function() {
        resolvedPath = '../'+resolvedPath;
      });
    }
    return resolvedPath;
  }

};
<|endoftext|>


<commit_before>'use strict';

var path = require('path');

module.exports = function (grunt) {

  var _ = grunt.util._;

  var defaultOpts = {
    pckgs: ['.']
  };

  function spawned(done, cmd, args, opts) {
    function spawnFunc() {
      var spawn = require('child_process').spawn;
      opts.stdio = 'inherit';
      spawn(cmd, args || [], opts).on('exit', function (status) {
        done(status === 0);
      });
    }

    return spawnFunc;
  }

  // expecting 'go:<command>:<target>(:<profile>)'
  function validateArgs(args) {
    if (args.length === 0) {
      grunt.log.error('Unable to run task: no target specified');
      return false;
    } else if (args.length === 1) {
      grunt.log.error('Unable to run task: no action specified (e.g. build)');
      return false;
    } else if (args.length > 2) {
      grunt.log.error('Unable to run task: too many arguments (up to 3 allowed)');
      return false;
    }

    return true;
  }

  function validateOpts(opts) {
    for (var key in opts) {
      if (key.indexOf('_flags') !== -1 || key.indexOf('pckgs') !== -1 || key.indexOf('_files') !== -1  || key === 'GOPATH') {
        var value = opts[key];
        if (!(value instanceof Array)) {
          grunt.log.error('Unable to run task: option \'' + key + '\' must be an array');
          return false;
        }
      }
    }

    return true;
  }

  function createPath(opts) {
    var res = [];
    var root = opts['root'] || '.';
    var paths = opts['GOPATH'] || [];

    if (paths) {
      for (var i in paths) {
        res.push(path.resolve(path.join(root, paths[i])));
      }
    }

    return res;
  }

  // ==== INTERFACE

  var exports = {
    execute: function (dryRun) {
      var self = this;
      var name = self.name || 'go';

      // ==== read task parameters

      var taskArgs = this.args || [];
      grunt.log.debug('Task args: ' + taskArgs);
      if (validateArgs(taskArgs) === false) {
        return false;
      }
      var action = taskArgs[0];
      var target = taskArgs[1];
      var profile = taskArgs[2] || "";

      if (!target || !grunt.config([name, target])) {
        grunt.log.error('Unable to run task: target \'' + target + '\' not found');
        return false;
      }

      var gruntTaskTargetProfileOpts = grunt.config([name, target, profile]) || {};
      var gruntTaskTargetOpts = grunt.config([name, target]) || {};
      var gruntTaskOpts = grunt.config([name, 'options']) || {};
      var taskOpts = _.defaults(
        gruntTaskTargetProfileOpts,
        gruntTaskTargetOpts,
        gruntTaskOpts,
        defaultOpts
      );
      grunt.log.debug('Task opts: ' + JSON.stringify(taskOpts));
      if (validateOpts(taskOpts) === false) {
        return false;
      }
      var output = taskOpts['output'] || target;

      // ==== assemble command path

      var cmd = 'go';
      var goBin = taskOpts['bin'];
      if (goBin) {
        cmd = goBin + '/' + cmd;

        if (cmd.substr(0, 1) === '~') {
          cmd = process.env.HOME + cmd.substr(1);
        }

        cmd = path.resolve(cmd);
      }

      // ==== assemble command arguments

      var cmdArgs = [action];
      var cmdFlags = taskOpts[action + '_flags'] || [];
      var cmdBuildFlags = taskOpts['build_flags'] || [];
      var cmdPckgs = taskOpts[action + '_pckgs'] || taskOpts[action + '_files'] || taskOpts['pckgs'] || [];

      if (action === "test") {
        cmdArgs = cmdArgs.concat(taskOpts['test_build_flags'] || []);
        cmdArgs = cmdArgs.concat(cmdBuildFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
        cmdArgs = cmdArgs.concat(cmdFlags);
      } else if (action === "build") {
        if (!cmdFlags || _.indexOf(cmdFlags, '-o') === -1) {
          cmdArgs.push('-o', output);
        }
        cmdArgs = cmdArgs.concat(cmdFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
      } else if (action === "run") {
        cmdArgs = cmdArgs.concat(cmdBuildFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
        cmdArgs = cmdArgs.concat(cmdFlags);
      } else if (action === "get") {
        cmdArgs = cmdArgs.concat(cmdFlags);
        cmdArgs = cmdArgs.concat(cmdBuildFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
      } else if (action === "install") {
        cmdArgs = cmdArgs.concat(cmdBuildFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
      } else {
        cmdArgs = cmdArgs.concat(cmdFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
      }

      // ==== assemble command options

      var cmdOpts = {};
      cmdOpts['env'] = process.env || {};
      cmdOpts['cwd'] = path.resolve(taskOpts['root'] || '.');

      var envTaskOpts = taskOpts['env'] || {};
      for (var envName in envTaskOpts) {
        cmdOpts['env'][envName] = envTaskOpts[envName];
      }

      cmdOpts['env'].GOPATH =
        createPath(gruntTaskOpts)
          .concat(createPath(gruntTaskTargetOpts))
          .concat(createPath(gruntTaskTargetProfileOpts)).join(':');

      grunt.log.debug('CMD opts: ' + JSON.stringify(cmdOpts));

      // ==== execute and return

      var fullCmd = cmd + ' ' + cmdArgs.join(' ');
      grunt.log.writeln('executing: ' + fullCmd);

      if (dryRun !== true) {
        var done = this.async();
        spawned(done, cmd, cmdArgs, cmdOpts)();
      } else {
        grunt.log.write('(dry run: script not executed)');
      }

      grunt.log.writeln();
      return {
        cmd: fullCmd,
        opts: cmdOpts
      };
    }
  };

  // ==== TASK

  grunt.registerTask('go', 'Working with Go', exports.execute);

  return exports;
};
<commit_msg>removed unnecessary writeln()<commit_after>'use strict';

var path = require('path');

module.exports = function (grunt) {

  var _ = grunt.util._;

  var defaultOpts = {
    pckgs: ['.']
  };

  function spawned(done, cmd, args, opts) {
    function spawnFunc() {
      var spawn = require('child_process').spawn;
      opts.stdio = 'inherit';
      spawn(cmd, args || [], opts).on('exit', function (status) {
        done(status === 0);
      });
    }

    return spawnFunc;
  }

  // expecting 'go:<command>:<target>(:<profile>)'
  function validateArgs(args) {
    if (args.length === 0) {
      grunt.log.error('Unable to run task: no target specified');
      return false;
    } else if (args.length === 1) {
      grunt.log.error('Unable to run task: no action specified (e.g. build)');
      return false;
    } else if (args.length > 2) {
      grunt.log.error('Unable to run task: too many arguments (up to 3 allowed)');
      return false;
    }

    return true;
  }

  function validateOpts(opts) {
    for (var key in opts) {
      if (key.indexOf('_flags') !== -1 || key.indexOf('pckgs') !== -1 || key.indexOf('_files') !== -1  || key === 'GOPATH') {
        var value = opts[key];
        if (!(value instanceof Array)) {
          grunt.log.error('Unable to run task: option \'' + key + '\' must be an array');
          return false;
        }
      }
    }

    return true;
  }

  function createPath(opts) {
    var res = [];
    var root = opts['root'] || '.';
    var paths = opts['GOPATH'] || [];

    if (paths) {
      for (var i in paths) {
        res.push(path.resolve(path.join(root, paths[i])));
      }
    }

    return res;
  }

  // ==== INTERFACE

  var exports = {
    execute: function (dryRun) {
      var self = this;
      var name = self.name || 'go';

      // ==== read task parameters

      var taskArgs = this.args || [];
      grunt.log.debug('Task args: ' + taskArgs);
      if (validateArgs(taskArgs) === false) {
        return false;
      }
      var action = taskArgs[0];
      var target = taskArgs[1];
      var profile = taskArgs[2] || "";

      if (!target || !grunt.config([name, target])) {
        grunt.log.error('Unable to run task: target \'' + target + '\' not found');
        return false;
      }

      var gruntTaskTargetProfileOpts = grunt.config([name, target, profile]) || {};
      var gruntTaskTargetOpts = grunt.config([name, target]) || {};
      var gruntTaskOpts = grunt.config([name, 'options']) || {};
      var taskOpts = _.defaults(
        gruntTaskTargetProfileOpts,
        gruntTaskTargetOpts,
        gruntTaskOpts,
        defaultOpts
      );
      grunt.log.debug('Task opts: ' + JSON.stringify(taskOpts));
      if (validateOpts(taskOpts) === false) {
        return false;
      }
      var output = taskOpts['output'] || target;

      // ==== assemble command path

      var cmd = 'go';
      var goBin = taskOpts['bin'];
      if (goBin) {
        cmd = goBin + '/' + cmd;

        if (cmd.substr(0, 1) === '~') {
          cmd = process.env.HOME + cmd.substr(1);
        }

        cmd = path.resolve(cmd);
      }

      // ==== assemble command arguments

      var cmdArgs = [action];
      var cmdFlags = taskOpts[action + '_flags'] || [];
      var cmdBuildFlags = taskOpts['build_flags'] || [];
      var cmdPckgs = taskOpts[action + '_pckgs'] || taskOpts[action + '_files'] || taskOpts['pckgs'] || [];

      if (action === "test") {
        cmdArgs = cmdArgs.concat(taskOpts['test_build_flags'] || []);
        cmdArgs = cmdArgs.concat(cmdBuildFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
        cmdArgs = cmdArgs.concat(cmdFlags);
      } else if (action === "build") {
        if (!cmdFlags || _.indexOf(cmdFlags, '-o') === -1) {
          cmdArgs.push('-o', output);
        }
        cmdArgs = cmdArgs.concat(cmdFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
      } else if (action === "run") {
        cmdArgs = cmdArgs.concat(cmdBuildFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
        cmdArgs = cmdArgs.concat(cmdFlags);
      } else if (action === "get") {
        cmdArgs = cmdArgs.concat(cmdFlags);
        cmdArgs = cmdArgs.concat(cmdBuildFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
      } else if (action === "install") {
        cmdArgs = cmdArgs.concat(cmdBuildFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
      } else {
        cmdArgs = cmdArgs.concat(cmdFlags);
        cmdArgs = cmdArgs.concat(cmdPckgs);
      }

      // ==== assemble command options

      var cmdOpts = {};
      cmdOpts['env'] = process.env || {};
      cmdOpts['cwd'] = path.resolve(taskOpts['root'] || '.');

      var envTaskOpts = taskOpts['env'] || {};
      for (var envName in envTaskOpts) {
        cmdOpts['env'][envName] = envTaskOpts[envName];
      }

      cmdOpts['env'].GOPATH =
        createPath(gruntTaskOpts)
          .concat(createPath(gruntTaskTargetOpts))
          .concat(createPath(gruntTaskTargetProfileOpts)).join(':');

      grunt.log.debug('CMD opts: ' + JSON.stringify(cmdOpts));

      // ==== execute and return

      var fullCmd = cmd + ' ' + cmdArgs.join(' ');
      grunt.log.writeln('executing: ' + fullCmd);

      if (dryRun !== true) {
        var done = this.async();
        spawned(done, cmd, cmdArgs, cmdOpts)();
      } else {
        grunt.log.write('(dry run: script not executed)');
      }

      return {
        cmd: fullCmd,
        opts: cmdOpts
      };
    }
  };

  // ==== TASK

  grunt.registerTask('go', 'Working with Go', exports.execute);

  return exports;
};
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Francisco Salavert (SGL-CIPF)
 * Copyright (c) 2014 Alejandro Alemán (SGL-CIPF)
 * Copyright (c) 2014 Ignacio Medina (EBI-EMBL)
 * Copyright (c) 2014 Jag Kandasamy (EBI-EMBL)
 *
 * This file is part of EVA.
 *
 * EVA is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * EVA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with EVA. If not, see <http://www.gnu.org/licenses/>.
 */
function Eva(args) {
    _.extend(this, Backbone.Events);

    //set default args
    this.id = Utils.genId("Eva");
    this.target;
    this.targetMenu;
    this.autoRender = true;

    //set instantiation args, must be last
    _.extend(this, args);

    this.on(this.handlers);

    this.childDivMenuMap = {};
    this.rendered = false;
    if (this.autoRender) {
        this.render(this.targetId);
    }
}

Eva.prototype = {
    render: function () {
        var _this = this;
        console.log("Initializing");

        //HTML skel
        this.div = document.createElement('div');
        this.div.setAttribute('class', 'eva-app');
        this.div.setAttribute('id', this.id);

        this.targetMenuUl = (this.targetMenu instanceof HTMLElement ) ? this.targetMenu : document.querySelector('#' + this.targetMenu);
        this.evaMenu = this._createEvaMenu(this.targetMenuUl);

        /* Home */
        $(this.homeDiv).addClass('eva-child');
        this.childDivMenuMap['Home'] = this.homeDiv;

        /* Submit */
        $(this.submitDiv).addClass('eva-child');
        this.childDivMenuMap['Submit Data'] = this.submitDiv;

        /* About */
        $(this.aboutDiv).addClass('eva-child');
        this.childDivMenuMap['About'] = this.aboutDiv;

        /* Contact */
        $(this.contactDiv).addClass('eva-child');
        this.childDivMenuMap['Contact'] = this.contactDiv;

        /* api */
        $(this.apiDiv).addClass('eva-child');
        this.childDivMenuMap['API'] = this.apiDiv;

        /* Templates */
        $(this.templatesDiv).addClass('eva-child');
        this.childDivMenuMap['Templates'] = this.templatesDiv;

        /* VCF */
        $(this.vcfDiv).addClass('eva-child');
        this.childDivMenuMap['VCF'] = this.vcfDiv;

        /* studyView */
        $(this.studyView).addClass('eva-child');
        this.childDivMenuMap['eva-study'] = this.studyView;
        this.childDivMenuMap['dgva-study'] = this.studyView;

        /* variantView */
        $(this.variantView).addClass('eva-child');
        this.childDivMenuMap['variant'] = this.variantView;

        /* beacon */
        $(this.beacon).addClass('eva-child');
        this.childDivMenuMap['GA4GH'] = this.beacon;

        /* clinical */
        $(this.clinicalDiv).addClass('eva-child');
        this.childDivMenuMap['Clinical'] = this.clinicalDiv;

        /* submision-start */
        $(this.submissionForm).addClass('eva-child');
        this.childDivMenuMap['submission-start'] = this.submissionForm;
    },
    draw: function () {
        this.targetDiv = (this.target instanceof HTMLElement ) ? this.target : document.querySelector('#' + this.target);
        if (this.targetDiv === 'undefined') {
            console.log('target not found');
            return;
        }
        this.targetDiv.appendChild(this.div);
        this.evaMenu.draw();
        this.contentDiv = document.querySelector('#content');

//        this.select('Home');

    },
    select: function (option) {
        this.evaMenu.select(option);
        this._selectHandler(option);
    },
    _selectHandler: function (option) {
        var _this = this;
        if(this.studyBrowserPanel){
            this.studyBrowserPanel.hide();
        }
        if(this.variantWidgetPanel){
            this.variantWidgetPanel.hide();
        }
        if(this.genomeViewerPanel){
            this.genomeViewerPanel.hide();
        }

        if(this.beaconPanel){
            this.beaconPanel.hide();
        }

        if(this.clinicalWidgetPanel){
            this.clinicalWidgetPanel.hide();
        }

        $('body').find('.show-div').each(function (index, el) {
            $(el).removeClass('show-div');
            $(el).addClass('hide-div');
//           _this.div.removeChild(el)
        });
        if (this.childDivMenuMap[option]) {
            $(this.childDivMenuMap[option]).removeClass('hide-div');
            $(this.childDivMenuMap[option]).addClass('show-div');
//            this.div.appendChild(this.childDivMenuMap[option]);
        }

        var pageArray = ['eva-study','dgva-study', 'variant'];
        if(_.indexOf(pageArray, option) < 0 && !_.isEmpty(option)  ){
            var optionValue = option;
            if(option == 'Genome Browser'){
                var hash = document.URL.substring(document.URL.indexOf('?')+1);
                if  (!_.isUndefined(hash.split("&")[1])){
                    optionValue = hash;
                }else{
                    optionValue = option;
                }
            }
            var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?'+optionValue;
            window.history.pushState({path:newurl},'',newurl);
            $( "a:contains('"+option+"')").parent('li').addClass('active');
        }

        switch (option) {
            case 'Home':
                _this._drawStatisticsChart();
                _this._twitterWidgetUpdate();
                break;
            case 'Study Browser':
                if(this.studyBrowserPanel){
                    this.studyBrowserPanel.show();
                }else{
                    this.studyBrowserPanel  = this._createStudyBrowserPanel(this.contentDiv);
                }
                break;
            case 'VCF Browser':
                if(this.variantWidgetPanel){
                    this.variantWidgetPanel.show();
                }else{
                    this.variantWidgetPanel = this._createVariantWidgetPanel(this.contentDiv);
                    this.variantWidgetPanel.formPanelVariantFilter.trigger('submit', {values: this.variantWidgetPanel.formPanelVariantFilter.getValues(), sender: _this});
                }

                break;
            case 'Genome Browser':
                if(this.genomeViewerPanel){
                    this.genomeViewerPanel.show();
                }else{
                    this.genomeViewerPanel  = this._createGenomeViewerPanel(this.contentDiv);
                }
                break;
            case 'GA4GH':
                if(this.beaconPanel){
                    this.beaconPanel.show();
                }else{
                    this.beaconPanel  = this._createBeaconPanel(this.contentDiv);
                }
                break;

            case 'Clinical':
                if(this.clinicalWidgetPanel){
                    this.clinicalWidgetPanel.show();
                }else{
                    this.clinicalWidgetPanel = this._createClinicalWidgetPanel(this.contentDiv);
                    this.clinicalWidgetPanel.formPanelVariantFilter.trigger('submit', {values: this.clinicalWidgetPanel.formPanelVariantFilter.getValues(), sender: _this});
                }
                break;
        }
    },
    _createEvaMenu: function (target) {
        var _this = this;
        var evaMenu = new EvaMenu({
            target: target,
            handlers: {
                'menu:click': function (e) {
                    _this._selectHandler(e.option);
                }
            }
        });
        return evaMenu;
    },
    _createStudyBrowserPanel: function(target){
        var studyBrowser = new EvaStudyBrowserPanel({
            target: target
        });
        studyBrowser.draw();
        return studyBrowser;

    },
    _createVariantWidgetPanel: function(target){
        var variantWidget= new EvaVariantWidgetPanel({
            target: target
        });
        variantWidget.draw();
        return variantWidget;

    },
    _createGenomeViewerPanel: function(target){
        var genomeViewer = new EvaGenomeViewerPanel({
            target: target,
            position:$.urlParam('position')
        });
        genomeViewer.draw();
        return genomeViewer;

    },
    _createBeaconPanel: function(target){
        var evaBeacon = new EvaBeaconPanel({
            target: target
        });
        evaBeacon.draw();
        return evaBeacon;

    },
    _createClinicalWidgetPanel: function(target){
        var evaClinicalWidgetPanel = new EvaClinicalWidgetPanel({
            target: target
        });
        evaClinicalWidgetPanel.draw();
        return evaClinicalWidgetPanel;

    },
    _twitterWidgetUpdate : function (){

        var twitterWidgetEl = document.getElementById('twitter-widget');
        twitterWidgetEl.innerHTML = "";
        twitterWidgetEl.innerHTML = 'Tweets by @EBIvariation';
        $.getScript('//platform.twitter.com/widgets.js', function(){
            twttr.widgets.load();
        });
    },
    _drawStatisticsChart : function(){
        var evaStatistics = new EvaStatistics({
            targetId:'eva-statistics'
        });
        var dgvaStatistics = new DgvaStatistics({
            targetId:'dgva-statistics'
        });
    }
}
<commit_msg>code clean up<commit_after>/*
 * Copyright (c) 2014 Francisco Salavert (SGL-CIPF)
 * Copyright (c) 2014 Alejandro Alemán (SGL-CIPF)
 * Copyright (c) 2014 Ignacio Medina (EBI-EMBL)
 * Copyright (c) 2014 Jag Kandasamy (EBI-EMBL)
 *
 * This file is part of EVA.
 *
 * EVA is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * EVA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with EVA. If not, see <http://www.gnu.org/licenses/>.
 */
function Eva(args) {
    _.extend(this, Backbone.Events);

    //set default args
    this.id = Utils.genId("Eva");
    this.target;
    this.targetMenu;
    this.autoRender = true;

    //set instantiation args, must be last
    _.extend(this, args);

    this.on(this.handlers);

    this.childDivMenuMap = {};
    this.rendered = false;
    if (this.autoRender) {
        this.render(this.targetId);
    }
}

Eva.prototype = {
    render: function () {
        var _this = this;
        console.log("Initializing");

        //HTML skel
        this.div = document.createElement('div');
        this.div.setAttribute('class', 'eva-app');
        this.div.setAttribute('id', this.id);

        this.targetMenuUl = (this.targetMenu instanceof HTMLElement ) ? this.targetMenu : document.querySelector('#' + this.targetMenu);
        this.evaMenu = this._createEvaMenu(this.targetMenuUl);

        /* Home */
        $(this.homeDiv).addClass('eva-child');
        this.childDivMenuMap['Home'] = this.homeDiv;

        /* Submit */
        $(this.submitDiv).addClass('eva-child');
        this.childDivMenuMap['Submit Data'] = this.submitDiv;

        /* About */
        $(this.aboutDiv).addClass('eva-child');
        this.childDivMenuMap['About'] = this.aboutDiv;

        /* Contact */
        $(this.contactDiv).addClass('eva-child');
        this.childDivMenuMap['Contact'] = this.contactDiv;

        /* api */
        $(this.apiDiv).addClass('eva-child');
        this.childDivMenuMap['API'] = this.apiDiv;

        /* Templates */
        $(this.templatesDiv).addClass('eva-child');
        this.childDivMenuMap['Templates'] = this.templatesDiv;

        /* VCF */
        $(this.vcfDiv).addClass('eva-child');
        this.childDivMenuMap['VCF'] = this.vcfDiv;

        /* studyView */
        $(this.studyView).addClass('eva-child');
        this.childDivMenuMap['eva-study'] = this.studyView;
        this.childDivMenuMap['dgva-study'] = this.studyView;

        /* variantView */
        $(this.variantView).addClass('eva-child');
        this.childDivMenuMap['variant'] = this.variantView;

        /* beacon */
        $(this.beacon).addClass('eva-child');
        this.childDivMenuMap['GA4GH'] = this.beacon;

        /* clinical */
        $(this.clinicalDiv).addClass('eva-child');
        this.childDivMenuMap['Clinical'] = this.clinicalDiv;

        /* submision-start */
        $(this.submissionForm).addClass('eva-child');
        this.childDivMenuMap['submission-start'] = this.submissionForm;
    },
    draw: function () {
        this.targetDiv = (this.target instanceof HTMLElement ) ? this.target : document.querySelector('#' + this.target);
        if (this.targetDiv === 'undefined') {
            console.log('target not found');
            return;
        }
        this.targetDiv.appendChild(this.div);
        this.evaMenu.draw();
        this.contentDiv = document.querySelector('#content');

//        this.select('Home');

    },
    select: function (option) {
        this.evaMenu.select(option);
        this._selectHandler(option);
    },
    _selectHandler: function (option) {
        var _this = this;
        if(this.studyBrowserPanel){
            this.studyBrowserPanel.hide();
        }
        if(this.variantWidgetPanel){
            this.variantWidgetPanel.hide();
        }
        if(this.genomeViewerPanel){
            this.genomeViewerPanel.hide();
        }

        if(this.beaconPanel){
            this.beaconPanel.hide();
        }

        if(this.clinicalWidgetPanel){
            this.clinicalWidgetPanel.hide();
        }

        $('body').find('.show-div').each(function (index, el) {
            $(el).removeClass('show-div');
            $(el).addClass('hide-div');
//           _this.div.removeChild(el)
        });
        if (this.childDivMenuMap[option]) {
            $(this.childDivMenuMap[option]).removeClass('hide-div');
            $(this.childDivMenuMap[option]).addClass('show-div');
//            this.div.appendChild(this.childDivMenuMap[option]);
        }

        //
        var pageArray = ['eva-study','dgva-study', 'variant'];
        if(_.indexOf(pageArray, option) < 0 && !_.isEmpty(option)  ){
            var optionValue = option;
            var tabArray = ['Genome Browser'];
            if(_.indexOf(tabArray, option) >= 0){
                var hash = document.URL.substring(document.URL.indexOf('?')+1);
                if  (!_.isUndefined(hash.split("&")[1])){
                    optionValue = hash;
                }else{
                    optionValue = option;
                }
            }
            var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?'+optionValue;
            window.history.pushState({path:newurl},'',newurl);
            $( "a:contains('"+option+"')").parent('li').addClass('active');
        }

        switch (option) {
            case 'Home':
                _this._drawStatisticsChart();
                _this._twitterWidgetUpdate();
                break;
            case 'Study Browser':
                if(this.studyBrowserPanel){
                    this.studyBrowserPanel.show();
                }else{
                    this.studyBrowserPanel  = this._createStudyBrowserPanel(this.contentDiv);
                }
                break;
            case 'VCF Browser':
                if(this.variantWidgetPanel){
                    this.variantWidgetPanel.show();
                }else{
                    this.variantWidgetPanel = this._createVariantWidgetPanel(this.contentDiv);
                    this.variantWidgetPanel.formPanelVariantFilter.trigger('submit', {values: this.variantWidgetPanel.formPanelVariantFilter.getValues(), sender: _this});
                }

                break;
            case 'Genome Browser':
                if(this.genomeViewerPanel){
                    this.genomeViewerPanel.show();
                }else{
                    this.genomeViewerPanel  = this._createGenomeViewerPanel(this.contentDiv);
                }
                break;
            case 'GA4GH':
                if(this.beaconPanel){
                    this.beaconPanel.show();
                }else{
                    this.beaconPanel  = this._createBeaconPanel(this.contentDiv);
                }
                break;

            case 'Clinical':
                if(this.clinicalWidgetPanel){
                    this.clinicalWidgetPanel.show();
                }else{
                    this.clinicalWidgetPanel = this._createClinicalWidgetPanel(this.contentDiv);
                    this.clinicalWidgetPanel.formPanelVariantFilter.trigger('submit', {values: this.clinicalWidgetPanel.formPanelVariantFilter.getValues(), sender: _this});
                }
                break;
        }
    },
    _createEvaMenu: function (target) {
        var _this = this;
        var evaMenu = new EvaMenu({
            target: target,
            handlers: {
                'menu:click': function (e) {
                    _this._selectHandler(e.option);
                }
            }
        });
        return evaMenu;
    },
    _createStudyBrowserPanel: function(target){
        var studyBrowser = new EvaStudyBrowserPanel({
            target: target
        });
        studyBrowser.draw();
        return studyBrowser;

    },
    _createVariantWidgetPanel: function(target){
        var variantWidget= new EvaVariantWidgetPanel({
            target: target
        });
        variantWidget.draw();
        return variantWidget;

    },
    _createGenomeViewerPanel: function(target){
        var genomeViewer = new EvaGenomeViewerPanel({
            target: target,
            position:$.urlParam('position')
        });
        genomeViewer.draw();
        return genomeViewer;

    },
    _createBeaconPanel: function(target){
        var evaBeacon = new EvaBeaconPanel({
            target: target
        });
        evaBeacon.draw();
        return evaBeacon;

    },
    _createClinicalWidgetPanel: function(target){
        var evaClinicalWidgetPanel = new EvaClinicalWidgetPanel({
            target: target
        });
        evaClinicalWidgetPanel.draw();
        return evaClinicalWidgetPanel;

    },
    _twitterWidgetUpdate : function (){

        var twitterWidgetEl = document.getElementById('twitter-widget');
        twitterWidgetEl.innerHTML = "";
        twitterWidgetEl.innerHTML = 'Tweets by @EBIvariation';
        $.getScript('//platform.twitter.com/widgets.js', function(){
            twttr.widgets.load();
        });
    },
    _drawStatisticsChart : function(){
        var evaStatistics = new EvaStatistics({
            targetId:'eva-statistics'
        });
        var dgvaStatistics = new DgvaStatistics({
            targetId:'dgva-statistics'
        });
    }
}
<|endoftext|>


<commit_before>// ==UserScript==
// @name                Rabobank Internetbankieren auto-input
// @namespace           FelixAkk
// @description         Quickly select from multiple bank acccounts in the Rabobank login and payment pages
// @include             https://bankieren.rabobank.nl/klanten*
// @include             https://bankieren.rabobank.nl/rib/*
// @include             https://betalen.rabobank.nl/ide/qslo*
// @include             https://betalen.rabobank.nl/ideal-betaling/*
// @grant               GM_setValue
// @grant               GM_getValue
// @grant               GM_listValues
// @grant               GM_deleteValue
// @grant               GM_addStyle
// @grant               GM_registerMenuCommand
// @require             http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js
// @copyright           2014, Felix Akkermans
// @copyright           2014, Matthijs Kooijman (matthijs@stdin.nl)
// @license             The MIT license; http://opensource.org/licenses/MIT
// @homepageURL         https://github.com/matthijskooijman/greasemonkey-rabobank-autoinput
// @version             2.1.2
// ==/UserScript==

/*jslint undef: true, vars: true, newcap: true, maxerr: 50, maxlen: 200, indent: 4 */

/**
 * The `jslint` comment is an annotation with flags for JSLint.com and alike tools. Some explanation on the options:
 *
 * browser: true        Will make it accept use of document, window, JSON and such without declaration
 * vars: true           Tollerate many seperate variable declarations
 * maxlen: 200          Set the maximum line length to 200 characters
 * undef: true          Tollerate usage of undefined functions. To accept GM_* functions.
 * plusplus: true       Tollerate ++ and -- operators. Just shush already, I just them responsibly.
 */

/**
 * The global annotation is also for JSLint, which will tell it not to whine about the declaration
 */
/*global GM_setValue, GM_getValue, GM_listValues, GM_deleteValue, window, document */

// http://stackoverflow.com/questions/1335851/what-does-use-strict-do-in-javascript-and-what-is-the-reasoning-behind-it
(function () {
	"use strict";
	// --------------- General settings -------------------
	// tweak it to your own likings (script may malfunction on bad values)

	// Want me to fill in your default/primary account automatically as a page loads?
	var autoFillDefault = true,
		// Change to the account you want to select from the accountsArray (start counting from zero).
		defaultAccount = 0,
		// Time in miliseconds to wait for Rabobank's native JavaScript that's ran on DOM-ready to finish.
		// Increase this if you see your account selected but not filled in.
		autoFillDelay = 1000,
		// Optionally you can also choose your account through the GreaseMonkey command menu (off by default)
		GMMenu = false,
		// Want me to remove that puny original Rabobank 'remember my card' checkbox?
		// It's bugged, and I just made it obsolete... Yeah, that's what I though :)
		removeOriginalRemember = true;

	// ---------------- CSS/Stylesheet --------------------

	var stylesheet =
	'div#account_selection {'+
	'    margin-bottom: 20px;'+
	'}'+
	'div#account_selection table#accounts {'+
	'    background: none repeat scroll 0 0 White;'+
	'    padding: 5px;'+
	'    width: 96%;'+
	'}'+
	'table#accounts th {'+
	'    text-align: left;'+
	'}'+
	'table#accounts td:first-child {'+
	'    padding-left: 16px;'+
	'}'+
	'a.edit {'+
	'    background: no-repeat scroll 0 0 transparent;'+
	'    display: block;'+
	'    margin: 10px;'+
	'    padding-left: 25px;'+
	'}'+
	'a.edit.enter {'+
	'    background-image: url("http://www.famfamfam.com/lab/icons/silk/icons/page_white_edit.png");'+
	'}'+
	'a.edit.exit {'+
	'    background-image: url("http://www.famfamfam.com/lab/icons/silk/icons/page_white_put.png");'+
	'}'+
	'a.account.add, a.account.delete {'+
	'    background: no-repeat scroll 0 0 transparent;'+
	'    display: inline-block;'+
	'    height: 16px;'+
	'    opacity: 0.3;'+
	'    vertical-align: text-bottom;'+
	'    width: 16px;'+
	'}'+
	'a.account.add:hover, a.account.delete:hover {'+
	'    opacity: 1;'+
	'}'+
	'a.account.add {'+
	'    background-image: url("http://www.famfamfam.com/lab/icons/silk/icons/add.png");'+
	'}'+
	'a.account.delete {'+
	'    background-image: url("http://www.famfamfam.com/lab/icons/silk/icons/delete.png");'+
	'}';

	// Construct selection panel DOM
	var selectionPanel =
	// I'll employ the styles of the Rabobank CSS classes .imgstripe, .newpanel to make it look identical.
	'
'+
	'  <form>'+
	'
'+
	// Static table header
	'
'+
	'
'+
	'
Selecteer uw Rabobank rekening
	'+
	'
Rekeningnummer
	'+
	'
Kaartnummer
	'+
	'
'+
	'
'+
	'

'+
	'
'+
	'  <form>'+
	// The edit button
	'  Rekeningen instellen...'+
	'  Veranderingen opslaan'+
	'
'
	selectionPanel = $(selectionPanel);

	// Account object
	function Account(descr, acc, card) {
		this.description = descr;
		this.number = acc;
		this.cardNumber = card;
	}

	// Define whether the page is in the editing stage
	var editing = false;
	// Example accounts
	var examples = [
		new Account("Bijv. Privé coulante rekening", 123456789, 1234),
		new Account("Bijv. Spaar rekening", 123456789, 1234),
		new Account("Bijv. Zakelijke rekening", 123456789, 1234)
	];

	// Prefetch storage
	var accountsJSON = GM_getValue('accountsJSON');
	// Actual accounts
	var accountsArray;
	// If we have no values stored yet (first run), initialize the storage with example values
	if (accountsJSON === undefined) {
		GM_setValue('accountsJSON', JSON.stringify(examples));
		accountsArray = examples;
	} else {
		// Else load the bank accounts
		accountsArray = JSON.parse(accountsJSON);
	}

	// Utility function that takes a bank account number and returns it seperated by points like on the Rabobank cards
	function numberFormat(account) {
		var nr = String(account);
		return nr.substring(0, 4) + '.' + nr.substring(4, 6) + '.' + nr.substring(6);
	}

	// Build accounts table contents (the rows), depending on whether we're editing (true) or selecting (false)
	function constructTable() {
		var t = $('#accounts tbody');
		t.empty();
		for (var idx = 0; idx < accountsArray.length; idx++) {
			if (editing)
				t.append(constructEditableRow(accountsArray[idx]));
			else
				t.append(constructSelectableRow(idx, accountsArray[idx]));
		}
		if (editing)
			$('

').on('click', addAccount).appendTo(t);
	}

	function constructSelectableRow(idx, acc) {
		return $('
').append(
			$('').append(
				$('<input type="radio" name="account" />'),
				$('').text(acc.description)
			),
			$('').append($('').text(acc.number)),
			$('').append($('').text(acc.cardNumber))
		).on('click', function() { selectAccount(idx, true); });
	}

	function constructEditableRow(acc) {
		return $('
').append(
			$('').append($('<input type="text" />').attr('value', acc.description)),
			$('').append($('<input type="text" size="9" maxlength="9"/>').attr('value', acc.number)),
			$('').append($('<input type="text" size="4" maxlength="4"/>').attr('value', acc.cardNumber)),
			$('').append($('').on('click', deleteAccount))
		);
	}

	function accountFromRow(row) {
		var inputs = $('input', row);
		return new Account(inputs[0].value, inputs[1].value, inputs[2].value);
	}

	// Define event handling function for selecting an account; fills in the account details
	function selectAccount(idx, override) {
		// Figure out the currently selected values (removing
		// the spaces in the account number added for
		// readability).
		var number = $('#rass-data-reknr').prop('value').replace(/ /g, "");
		var card = $('#rass-data-pasnr').prop('value')

		if (number && card && !override) {
			// On page load, we shouldn't override any
			// current values if they are there, since when
			// using the Rabo Scanner, selecting an account
			// causes a page reload, after which we run
			// again. If we'd override the account number
			// then, we'd select the default account
			// after the user selected a different one
			//
			// Instead, find out which account was selected.
			idx = null;
			for (var i = 0; i < accountsArray.length; ++i) {
				if (accountsArray[i].number == number && accountsArray[i].cardNumber == card) {
					idx = i;
					break;
				}
			}
		} else {
			$('#rass-data-reknr').prop('value', accountsArray[idx].number);
			$('#rass-data-pasnr').prop('value', accountsArray[idx].cardNumber);

			// For the Rabo Scanner, the account and card
			// number need to be submitted, so the server
			// can generate a new challenge
			$('#loginform').submit();
		}

		// Login pages have AuthCdv4, sign pages have SignCdv4.
		// Focuse whatever one is available.
		$('#rass-data-inlogcode').focus();

		if (idx !== null)
			$('#accounts input[type="radio"]')[idx].checked = true;
	}

	// Define event handling function for deleting an account/row in the accounts table when editing accounts
	function deleteAccount() {
		$(this).closest('tr').remove();
	}

	// Define event handling function for inserting an account/row in the accounts table after a given index (when editing accounts)
	function addAccount(accountIdx) {
		var row = constructEditableRow(new Account());
		row.insertBefore($('#accounts tbody tr').last());
	}

	// Event handler for the save changes button
	function saveChanges() {
		accountsArray = []; // new array, clean slate
		// Fill array
		$('#accounts tbody tr').slice(0, -1).each(function(idx, row) {
			accountsArray.push(accountFromRow(row));
		});
		// Save it all
		GM_setValue('accountsJSON', JSON.stringify(accountsArray));
		setEditMode(false);
	}

	// Function to add an menu item to the GreaseMonkey command item to select your account.
	// This function is necessary to get 'idx' to be a seperate variable at runtime instead of the end value of the 'idx' variable of the insertPanel function.
	function addGMMenuItem(idx) {
		// Format caption like '1. Account description (12345689 : 1234)'
		var caption = (idx + 1) + '. ' + accountsArray[idx].description + '  (' + numberFormat(accountsArray[idx].number) + ' : ' + accountsArray[idx].cardNumber + ')';
		// Have to wrap the select account function in an anonymous function to create a closure with the index parameter bound
		var handler = function () { selectAccount(idx, true); };
		GM_registerMenuCommand(caption, handler);
	}

	function setEditMode(value) {
		// Update edit/save links
		$("a.edit.enter", selectionPanel).toggle(!value);
		$("a.edit.exit", selectionPanel).toggle(value);
		// Remember new edit mode
		editing = value;
		// Reconstruct table
		constructTable();
	}

	function initAccountsPanel() {
		$("a.edit.enter", selectionPanel).on("click", function() { setEditMode(true)});
		$("a.edit.exit", selectionPanel).on("click", function() { saveChanges()});
		setEditMode(false);
	}

	function initialize() {
		// Load the defined custom styles
		GM_addStyle(stylesheet);

		// Insert and fill the custom account selection panel
		var elem = $('#loginform');

		elem.before(selectionPanel);
		initAccountsPanel(editing);

		if (GMMenu) {
			for (var idx = 0; idx < accountsArray.length; idx++) {
				addGMMenuItem(idx);
			}
		}

		// Want me to remove that puny original Rabobank 'remember my card' checkbox? It's bugged, and I just made it obsolete... Yeah, that's what I though :)
		if (removeOriginalRemember) {
			$('#rass-data-onthouden').parent().hide();
		}

		// And for good measure, we may select the default/primary straight away.
		// This basically just fires the event listener function without setting the it's this.id attribute.
		if (autoFillDefault) {
			// We have to wait a little while to avoid conflict with Rabobank's native JavaScript ran on DOM-ready
			window.setTimeout(function() { selectAccount(defaultAccount, false); }, autoFillDelay);
		}
	}
	/**
	/* Run only when script is of use, i.e.;
	/* if we're on a Rabobank page where we have the kind of form we can input something usefull into.
	 */
	if(
		$('#loginform').length != 0 &&
		$('#rass-data-reknr').length != 0 &&
		$('#rass-data-pasnr').length != 0
	) {
		initialize();
	}

}());

<commit_msg>Update login url<commit_after>// ==UserScript==
// @name                Rabobank Internetbankieren auto-input
// @namespace           FelixAkk
// @description         Quickly select from multiple bank acccounts in the Rabobank login and payment pages
// @include             https://bankieren.rabobank.nl/omgevingskeuze/registratie
// @include             https://betalen.rabobank.nl/ide/qslo*
// @include             https://betalen.rabobank.nl/ideal-betaling/*
// @grant               GM_setValue
// @grant               GM_getValue
// @grant               GM_listValues
// @grant               GM_deleteValue
// @grant               GM_addStyle
// @grant               GM_registerMenuCommand
// @require             http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js
// @copyright           2014, Felix Akkermans
// @copyright           2014, Matthijs Kooijman (matthijs@stdin.nl)
// @license             The MIT license; http://opensource.org/licenses/MIT
// @homepageURL         https://github.com/matthijskooijman/greasemonkey-rabobank-autoinput
// @version             2.1.2
// ==/UserScript==

/*jslint undef: true, vars: true, newcap: true, maxerr: 50, maxlen: 200, indent: 4 */

/**
 * The `jslint` comment is an annotation with flags for JSLint.com and alike tools. Some explanation on the options:
 *
 * browser: true        Will make it accept use of document, window, JSON and such without declaration
 * vars: true           Tollerate many seperate variable declarations
 * maxlen: 200          Set the maximum line length to 200 characters
 * undef: true          Tollerate usage of undefined functions. To accept GM_* functions.
 * plusplus: true       Tollerate ++ and -- operators. Just shush already, I just them responsibly.
 */

/**
 * The global annotation is also for JSLint, which will tell it not to whine about the declaration
 */
/*global GM_setValue, GM_getValue, GM_listValues, GM_deleteValue, window, document */

// http://stackoverflow.com/questions/1335851/what-does-use-strict-do-in-javascript-and-what-is-the-reasoning-behind-it
(function () {
	"use strict";
	// --------------- General settings -------------------
	// tweak it to your own likings (script may malfunction on bad values)

	// Want me to fill in your default/primary account automatically as a page loads?
	var autoFillDefault = true,
		// Change to the account you want to select from the accountsArray (start counting from zero).
		defaultAccount = 0,
		// Time in miliseconds to wait for Rabobank's native JavaScript that's ran on DOM-ready to finish.
		// Increase this if you see your account selected but not filled in.
		autoFillDelay = 1000,
		// Optionally you can also choose your account through the GreaseMonkey command menu (off by default)
		GMMenu = false,
		// Want me to remove that puny original Rabobank 'remember my card' checkbox?
		// It's bugged, and I just made it obsolete... Yeah, that's what I though :)
		removeOriginalRemember = true;

	// ---------------- CSS/Stylesheet --------------------

	var stylesheet =
	'div#account_selection {'+
	'    margin-bottom: 20px;'+
	'}'+
	'div#account_selection table#accounts {'+
	'    background: none repeat scroll 0 0 White;'+
	'    padding: 5px;'+
	'    width: 96%;'+
	'}'+
	'table#accounts th {'+
	'    text-align: left;'+
	'}'+
	'table#accounts td:first-child {'+
	'    padding-left: 16px;'+
	'}'+
	'a.edit {'+
	'    background: no-repeat scroll 0 0 transparent;'+
	'    display: block;'+
	'    margin: 10px;'+
	'    padding-left: 25px;'+
	'}'+
	'a.edit.enter {'+
	'    background-image: url("http://www.famfamfam.com/lab/icons/silk/icons/page_white_edit.png");'+
	'}'+
	'a.edit.exit {'+
	'    background-image: url("http://www.famfamfam.com/lab/icons/silk/icons/page_white_put.png");'+
	'}'+
	'a.account.add, a.account.delete {'+
	'    background: no-repeat scroll 0 0 transparent;'+
	'    display: inline-block;'+
	'    height: 16px;'+
	'    opacity: 0.3;'+
	'    vertical-align: text-bottom;'+
	'    width: 16px;'+
	'}'+
	'a.account.add:hover, a.account.delete:hover {'+
	'    opacity: 1;'+
	'}'+
	'a.account.add {'+
	'    background-image: url("http://www.famfamfam.com/lab/icons/silk/icons/add.png");'+
	'}'+
	'a.account.delete {'+
	'    background-image: url("http://www.famfamfam.com/lab/icons/silk/icons/delete.png");'+
	'}';

	// Construct selection panel DOM
	var selectionPanel =
	// I'll employ the styles of the Rabobank CSS classes .imgstripe, .newpanel to make it look identical.
	'
'+
	'  <form>'+
	'
'+
	// Static table header
	'
'+
	'
'+
	'
Selecteer uw Rabobank rekening
	'+
	'
Rekeningnummer
	'+
	'
Kaartnummer
	'+
	'
'+
	'
'+
	'

'+
	'
'+
	'  <form>'+
	// The edit button
	'  Rekeningen instellen...'+
	'  Veranderingen opslaan'+
	'
'
	selectionPanel = $(selectionPanel);

	// Account object
	function Account(descr, acc, card) {
		this.description = descr;
		this.number = acc;
		this.cardNumber = card;
	}

	// Define whether the page is in the editing stage
	var editing = false;
	// Example accounts
	var examples = [
		new Account("Bijv. Privé coulante rekening", 123456789, 1234),
		new Account("Bijv. Spaar rekening", 123456789, 1234),
		new Account("Bijv. Zakelijke rekening", 123456789, 1234)
	];

	// Prefetch storage
	var accountsJSON = GM_getValue('accountsJSON');
	// Actual accounts
	var accountsArray;
	// If we have no values stored yet (first run), initialize the storage with example values
	if (accountsJSON === undefined) {
		GM_setValue('accountsJSON', JSON.stringify(examples));
		accountsArray = examples;
	} else {
		// Else load the bank accounts
		accountsArray = JSON.parse(accountsJSON);
	}

	// Utility function that takes a bank account number and returns it seperated by points like on the Rabobank cards
	function numberFormat(account) {
		var nr = String(account);
		return nr.substring(0, 4) + '.' + nr.substring(4, 6) + '.' + nr.substring(6);
	}

	// Build accounts table contents (the rows), depending on whether we're editing (true) or selecting (false)
	function constructTable() {
		var t = $('#accounts tbody');
		t.empty();
		for (var idx = 0; idx < accountsArray.length; idx++) {
			if (editing)
				t.append(constructEditableRow(accountsArray[idx]));
			else
				t.append(constructSelectableRow(idx, accountsArray[idx]));
		}
		if (editing)
			$('

').on('click', addAccount).appendTo(t);
	}

	function constructSelectableRow(idx, acc) {
		return $('
').append(
			$('').append(
				$('<input type="radio" name="account" />'),
				$('').text(acc.description)
			),
			$('').append($('').text(acc.number)),
			$('').append($('').text(acc.cardNumber))
		).on('click', function() { selectAccount(idx, true); });
	}

	function constructEditableRow(acc) {
		return $('
').append(
			$('').append($('<input type="text" />').attr('value', acc.description)),
			$('').append($('<input type="text" size="9" maxlength="9"/>').attr('value', acc.number)),
			$('').append($('<input type="text" size="4" maxlength="4"/>').attr('value', acc.cardNumber)),
			$('').append($('').on('click', deleteAccount))
		);
	}

	function accountFromRow(row) {
		var inputs = $('input', row);
		return new Account(inputs[0].value, inputs[1].value, inputs[2].value);
	}

	// Define event handling function for selecting an account; fills in the account details
	function selectAccount(idx, override) {
		// Figure out the currently selected values (removing
		// the spaces in the account number added for
		// readability).
		var number = $('#rass-data-reknr').prop('value').replace(/ /g, "");
		var card = $('#rass-data-pasnr').prop('value')

		if (number && card && !override) {
			// On page load, we shouldn't override any
			// current values if they are there, since when
			// using the Rabo Scanner, selecting an account
			// causes a page reload, after which we run
			// again. If we'd override the account number
			// then, we'd select the default account
			// after the user selected a different one
			//
			// Instead, find out which account was selected.
			idx = null;
			for (var i = 0; i < accountsArray.length; ++i) {
				if (accountsArray[i].number == number && accountsArray[i].cardNumber == card) {
					idx = i;
					break;
				}
			}
		} else {
			$('#rass-data-reknr').prop('value', accountsArray[idx].number);
			$('#rass-data-pasnr').prop('value', accountsArray[idx].cardNumber);

			// For the Rabo Scanner, the account and card
			// number need to be submitted, so the server
			// can generate a new challenge
			$('#loginform').submit();
		}

		// Login pages have AuthCdv4, sign pages have SignCdv4.
		// Focuse whatever one is available.
		$('#rass-data-inlogcode').focus();

		if (idx !== null)
			$('#accounts input[type="radio"]')[idx].checked = true;
	}

	// Define event handling function for deleting an account/row in the accounts table when editing accounts
	function deleteAccount() {
		$(this).closest('tr').remove();
	}

	// Define event handling function for inserting an account/row in the accounts table after a given index (when editing accounts)
	function addAccount(accountIdx) {
		var row = constructEditableRow(new Account());
		row.insertBefore($('#accounts tbody tr').last());
	}

	// Event handler for the save changes button
	function saveChanges() {
		accountsArray = []; // new array, clean slate
		// Fill array
		$('#accounts tbody tr').slice(0, -1).each(function(idx, row) {
			accountsArray.push(accountFromRow(row));
		});
		// Save it all
		GM_setValue('accountsJSON', JSON.stringify(accountsArray));
		setEditMode(false);
	}

	// Function to add an menu item to the GreaseMonkey command item to select your account.
	// This function is necessary to get 'idx' to be a seperate variable at runtime instead of the end value of the 'idx' variable of the insertPanel function.
	function addGMMenuItem(idx) {
		// Format caption like '1. Account description (12345689 : 1234)'
		var caption = (idx + 1) + '. ' + accountsArray[idx].description + '  (' + numberFormat(accountsArray[idx].number) + ' : ' + accountsArray[idx].cardNumber + ')';
		// Have to wrap the select account function in an anonymous function to create a closure with the index parameter bound
		var handler = function () { selectAccount(idx, true); };
		GM_registerMenuCommand(caption, handler);
	}

	function setEditMode(value) {
		// Update edit/save links
		$("a.edit.enter", selectionPanel).toggle(!value);
		$("a.edit.exit", selectionPanel).toggle(value);
		// Remember new edit mode
		editing = value;
		// Reconstruct table
		constructTable();
	}

	function initAccountsPanel() {
		$("a.edit.enter", selectionPanel).on("click", function() { setEditMode(true)});
		$("a.edit.exit", selectionPanel).on("click", function() { saveChanges()});
		setEditMode(false);
	}

	function initialize() {
		// Load the defined custom styles
		GM_addStyle(stylesheet);

		// Insert and fill the custom account selection panel
		var elem = $('#loginform');

		elem.before(selectionPanel);
		initAccountsPanel(editing);

		if (GMMenu) {
			for (var idx = 0; idx < accountsArray.length; idx++) {
				addGMMenuItem(idx);
			}
		}

		// Want me to remove that puny original Rabobank 'remember my card' checkbox? It's bugged, and I just made it obsolete... Yeah, that's what I though :)
		if (removeOriginalRemember) {
			$('#rass-data-onthouden').parent().hide();
		}

		// And for good measure, we may select the default/primary straight away.
		// This basically just fires the event listener function without setting the it's this.id attribute.
		if (autoFillDefault) {
			// We have to wait a little while to avoid conflict with Rabobank's native JavaScript ran on DOM-ready
			window.setTimeout(function() { selectAccount(defaultAccount, false); }, autoFillDelay);
		}
	}
	/**
	/* Run only when script is of use, i.e.;
	/* if we're on a Rabobank page where we have the kind of form we can input something usefull into.
	 */
	if(
		$('#loginform').length != 0 &&
		$('#rass-data-reknr').length != 0 &&
		$('#rass-data-pasnr').length != 0
	) {
		initialize();
	}

}());

<|endoftext|>


<commit_before>"use strict";

var Checker = require( "jscs" ),
    jscsConfig = require( "jscs/lib/cli-config" ),

    assign = require( "lodash" ).assign,
    hooker = require( "hooker" );

exports.init = function( grunt ) {

    // Task specific options
    var taskOptions = [ "config", "force", "reporter", "reporterOutput" ];

    /**
     * @see jQuery.isEmptyObject
     * @private
     */
    function isEmptyObject( obj ) {
        var name;

        for ( name in obj ) {
            return false;
        }

        return true;
    }

    /**
     * Default reporter
     * @private
     * @param {errorsCollection} errorsCollection
     */
    function defaultReporter( errorsCollection ) {
        errorsCollection.forEach( function( errors ) {
            if ( !errors.isEmpty() ) {
                errors.getErrorList().forEach( function( error ) {
                    grunt.log.writeln( errors.explainError( error, true ) );
                } );
            }
        } );
    }

    /**
     * Create new instance of jscs Checker module
     * @constructor
     * @param {Object} options
     * @return {JSCS}
     */
    function JSCS( options ) {
        this.checker = new Checker();
        this.options = options;
        this._reporter = null;

        this.checker.registerDefaultRules();
        this.checker.configure( this.getConfig() );

        this.registerReporter( options.reporter );
    }

    /**
     * @see Checker#checkPath
     */
    JSCS.prototype.check = function( path ) {
        var checkPath = this.checker.checkPath( path );

        checkPath.fail( function( error ) {
            grunt.warn( error );
        } );

        return checkPath;
    };

    /**
     * Get config
     * @return {Object}
     */
    JSCS.prototype.getConfig = function() {
        var configOption = this.options.config,
            config = this.findConfig(),
            options = this.getOptions();

        // If the config option is null, but we have inline options,
        // we'll only use them as our config.
        if ( configOption == null && !isEmptyObject( options ) ) {
            config = options;

        } else {
            assign( config, options );
        }

        this.throwForConfig( config );

        return config;
    };

    /**
     * Throw if something wrong with config file or with inline options
     * @param {Object} config
    **/
    JSCS.prototype.throwForConfig = function( config ) {
        var configOption = this.options.config;

        if ( isEmptyObject( config ) ) {
            if ( configOption && typeof configOption === "string" ) {
                if ( grunt.file.exists( configOption ) ) {
                    grunt.fatal( "\"" + configOption + "\" config is empty" );

                } else {
                    grunt.fatal( "The config file \"" + configOption + "\" was not found" );
                }

            } else {
                grunt.fatal( "Neither config file nor grunt options were defined" );
            }
        }

        return this;
    };

    /**
     * Read config file
     * @return {Object}
     */
    JSCS.prototype.findConfig = function() {
        var config = this.options && this.options.config;

        // If falsy value different than undefined was given, we'll return empty object
        if ( !config && config != null ) {
            return {};
        }

        // true or null will use default jscs config loader
        config = config === true ? null : config;
        return jscsConfig.load( config, process.cwd() ) || {};
    };

    /**
     * Get inline options
     * @return {Object}
     */
    JSCS.prototype.getOptions = function() {
        var option,
            _options = {};

        // Copy options to another object so this method would not be destructive
        for ( option in this.options ) {

            // If to jscs would be given a grunt task option
            // that not defined in jscs it would throw
            if ( !~taskOptions.indexOf( option ) ) {
                _options[ option ] = this.options[ option ];
            }
        }

        return _options;
    };

    /**
     * Register reporter
     * @param {String} name - name or path to the reporter
     * @return {Reporter|null}
     */
    JSCS.prototype.registerReporter = function( name ) {
        if ( !name ) {
            this._reporter = defaultReporter;

            return this;
        }

        var reporter = jscsConfig.getReporter( name );

        if ( reporter.writer ) {
            this._reporter = reporter.writer;

            return this;
        }

        grunt.fatal( "Reporter \"" + reporter.path + "\" does not exist" );
    };

    /**
     * Return reporter
     * @return {Reporter}
     */
    JSCS.prototype.getReporter = function() {
        return this._reporter;
    };

    /**
     * Set errors collection as instance property
     * @param {errorsCollection} errorsCollection
     */
    JSCS.prototype.setErrors = function( errorsCollection ) {

        // Filter excluded files ("excludeFiles" option)
        this._errors = errorsCollection.filter( function( errors ) {
            return errors;
        } );

        return this;
    };

    /**
     * Return instance errors
     * @return {Array}
     */
    JSCS.prototype.getErrors = function() {
        return this._errors;
    };

    /**
     * Count and return errors
     * @param {errorsCollection} [errorsCollection]
     * @return {Number}
     */
    JSCS.prototype.count = function() {
        var result = 0;

        this._errors.forEach( function( errors ) {
            result += errors.getErrorCount();
        } );

        return result;
    };

    /**
     * Send errors to the reporter
     * @return {JSCS}
     */
    JSCS.prototype.report = function() {
        var options = this.options,
            shouldHook = options.reporterOutput,
            content = "";

        if ( shouldHook ) {
            hooker.hook( process.stdout, "write", {
                pre: function( out ) {
                    content += out;

                    return hooker.preempt();
                }
            } );
        }

        this._result = this._reporter( this._errors );

        if ( shouldHook ) {
            grunt.file.write( options.reporterOutput, content );
            hooker.unhook( process.stdout, "write" );
        }

        return this;
    };

    /**
     * Print number of found errors
     * @return {JSCS}
     */
    JSCS.prototype.notify = function() {
        var errorCount = this.count();

        if ( errorCount ) {
            grunt.log.error( errorCount + " code style errors found!" );

        } else {
            grunt.log.ok( this._errors.length + " files without code style errors." );
        }

        return this;
    };

    return JSCS;
};
<commit_msg>Convert reporter option toString<commit_after>"use strict";

var Checker = require( "jscs" ),
    jscsConfig = require( "jscs/lib/cli-config" ),

    assign = require( "lodash" ).assign,
    hooker = require( "hooker" );

exports.init = function( grunt ) {

    // Task specific options
    var taskOptions = [ "config", "force", "reporter", "reporterOutput" ];

    /**
     * @see jQuery.isEmptyObject
     * @private
     */
    function isEmptyObject( obj ) {
        var name;

        for ( name in obj ) {
            return false;
        }

        return true;
    }

    /**
     * Default reporter
     * @private
     * @param {errorsCollection} errorsCollection
     */
    function defaultReporter( errorsCollection ) {
        errorsCollection.forEach( function( errors ) {
            if ( !errors.isEmpty() ) {
                errors.getErrorList().forEach( function( error ) {
                    grunt.log.writeln( errors.explainError( error, true ) );
                } );
            }
        } );
    }

    /**
     * Create new instance of jscs Checker module
     * @constructor
     * @param {Object} options
     * @return {JSCS}
     */
    function JSCS( options ) {
        this.checker = new Checker();
        this.options = options;
        this._reporter = null;

        this.checker.registerDefaultRules();
        this.checker.configure( this.getConfig() );

        this.registerReporter( options.reporter );
    }

    /**
     * @see Checker#checkPath
     */
    JSCS.prototype.check = function( path ) {
        var checkPath = this.checker.checkPath( path );

        checkPath.fail( function( error ) {
            grunt.warn( error );
        } );

        return checkPath;
    };

    /**
     * Get config
     * @return {Object}
     */
    JSCS.prototype.getConfig = function() {
        var configOption = this.options.config,
            config = this.findConfig(),
            options = this.getOptions();

        // If the config option is null, but we have inline options,
        // we'll only use them as our config.
        if ( configOption == null && !isEmptyObject( options ) ) {
            config = options;

        } else {
            assign( config, options );
        }

        this.throwForConfig( config );

        return config;
    };

    /**
     * Throw if something wrong with config file or with inline options
     * @param {Object} config
    **/
    JSCS.prototype.throwForConfig = function( config ) {
        var configOption = this.options.config;

        if ( isEmptyObject( config ) ) {
            if ( configOption && typeof configOption === "string" ) {
                if ( grunt.file.exists( configOption ) ) {
                    grunt.fatal( "\"" + configOption + "\" config is empty" );

                } else {
                    grunt.fatal( "The config file \"" + configOption + "\" was not found" );
                }

            } else {
                grunt.fatal( "Neither config file nor grunt options were defined" );
            }
        }

        return this;
    };

    /**
     * Read config file
     * @return {Object}
     */
    JSCS.prototype.findConfig = function() {
        var config = this.options && this.options.config;

        // If falsy value different than undefined was given, we'll return empty object
        if ( !config && config != null ) {
            return {};
        }

        // true or null will use default jscs config loader
        config = config === true ? null : config;
        return jscsConfig.load( config, process.cwd() ) || {};
    };

    /**
     * Get inline options
     * @return {Object}
     */
    JSCS.prototype.getOptions = function() {
        var option,
            _options = {};

        // Copy options to another object so this method would not be destructive
        for ( option in this.options ) {

            // If to jscs would be given a grunt task option
            // that not defined in jscs it would throw
            if ( !~taskOptions.indexOf( option ) ) {
                _options[ option ] = this.options[ option ];
            }
        }

        return _options;
    };

    /**
     * Register reporter
     * @param {String} name - name or path to the reporter
     * @return {Reporter|null}
     */
    JSCS.prototype.registerReporter = function( name ) {
        if ( !name ) {
            this._reporter = defaultReporter;

            return this;
        }

        var reporter = jscsConfig.getReporter( name.toString() );

        if ( reporter.writer ) {
            this._reporter = reporter.writer;

            return this;
        }

        grunt.fatal( "Reporter \"" + reporter.path + "\" does not exist" );
    };

    /**
     * Return reporter
     * @return {Reporter}
     */
    JSCS.prototype.getReporter = function() {
        return this._reporter;
    };

    /**
     * Set errors collection as instance property
     * @param {errorsCollection} errorsCollection
     */
    JSCS.prototype.setErrors = function( errorsCollection ) {

        // Filter excluded files ("excludeFiles" option)
        this._errors = errorsCollection.filter( function( errors ) {
            return errors;
        } );

        return this;
    };

    /**
     * Return instance errors
     * @return {Array}
     */
    JSCS.prototype.getErrors = function() {
        return this._errors;
    };

    /**
     * Count and return errors
     * @param {errorsCollection} [errorsCollection]
     * @return {Number}
     */
    JSCS.prototype.count = function() {
        var result = 0;

        this._errors.forEach( function( errors ) {
            result += errors.getErrorCount();
        } );

        return result;
    };

    /**
     * Send errors to the reporter
     * @return {JSCS}
     */
    JSCS.prototype.report = function() {
        var options = this.options,
            shouldHook = options.reporterOutput,
            content = "";

        if ( shouldHook ) {
            hooker.hook( process.stdout, "write", {
                pre: function( out ) {
                    content += out;

                    return hooker.preempt();
                }
            } );
        }

        this._result = this._reporter( this._errors );

        if ( shouldHook ) {
            grunt.file.write( options.reporterOutput, content );
            hooker.unhook( process.stdout, "write" );
        }

        return this;
    };

    /**
     * Print number of found errors
     * @return {JSCS}
     */
    JSCS.prototype.notify = function() {
        var errorCount = this.count();

        if ( errorCount ) {
            grunt.log.error( errorCount + " code style errors found!" );

        } else {
            grunt.log.ok( this._errors.length + " files without code style errors." );
        }

        return this;
    };

    return JSCS;
};
<|endoftext|>


<commit_before>/*
 * grunt-nunjucks
 * https://github.com/jlongster/nunjucks-grunt
 *
 * Copyright (c) 2013 James Long
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {
    var nunjucks = require('nunjucks');
    var lib = require('nunjucks/src/lib');

    grunt.registerMultiTask('nunjucks', 'Precompile nunjucks', function () {
        // Merge task-specific and/or target-specific options with these defaults.
        var opts = this.options({
            asFunction: false,
            env: null
        });

        var nameFunc = lib.isFunction(opts.name) ? opts.name : function(filepath) {
            return filepath;
        };

        this.files.forEach(function (f) {
            var src = f.src.filter(function (filepath) {
                if (!grunt.file.exists(filepath)) {
                    grunt.log.warn('Source file "' + filepath + '" not found.');
                    return false;
                } else {
                    return true;
                }
            }).map(function(filepath) {
                if (f.baseDir) {
                    if (f.baseDir.substr(-1) !== '/') {
                        // Append a trailing slash, if there isn't one.
                        f.baseDir += '/';
                    }
                    if (filepath.substr(0, f.baseDir.length) === f.baseDir) {
                        // Strip leading `baseDir` from filename.
                        opts.name = filepath.substr(f.baseDir.length);
                    }
                }
                opts.name = nameFunc(filepath);
                return nunjucks.precompile(filepath, opts);
            }).join('');

            grunt.file.write(f.dest, src);
            grunt.log.writeln('File "' + f.dest + '" created.');
        });
    });
};
<commit_msg>fix `nameFunc`<commit_after>/*
 * grunt-nunjucks
 * https://github.com/jlongster/nunjucks-grunt
 *
 * Copyright (c) 2013 James Long
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {
    var nunjucks = require('nunjucks');
    var lib = require('nunjucks/src/lib');

    grunt.registerMultiTask('nunjucks', 'Precompile nunjucks', function () {
        // Merge task-specific and/or target-specific options with these defaults.
        var opts = this.options({
            asFunction: false,
            env: null
        });

        var nameFunc = lib.isFunction(opts.name) ? opts.name(filepath) : opts.name;

        this.files.forEach(function (f) {
            var src = f.src.filter(function (filepath) {
                if (!grunt.file.exists(filepath)) {
                    grunt.log.warn('Source file "' + filepath + '" not found.');
                    return false;
                } else {
                    return true;
                }
            }).map(function(filepath) {
                if (f.baseDir) {
                    if (f.baseDir.substr(-1) !== '/') {
                        // Append a trailing slash, if there isn't one.
                        f.baseDir += '/';
                    }
                    if (filepath.substr(0, f.baseDir.length) === f.baseDir) {
                        // Strip leading `baseDir` from filename.
                        opts.name = filepath.substr(f.baseDir.length);
                    }
                }
                opts.name = nameFunc(filepath);
                return nunjucks.precompile(filepath, opts);
            }).join('');

            grunt.file.write(f.dest, src);
            grunt.log.writeln('File "' + f.dest + '" created.');
        });
    });
};
<|endoftext|>


<commit_before>/**
 * grunt-nunjucks-2-html
 * https://github.com/vitkarpov/grunt-nunjucks-2-html
 *
 * Copyright (c) 2014 Vit Karpov
 * Licensed under the MIT license.
 */

var nunjucks = require('nunjucks');
var path = require('path');
var async = require('async');
var _ = require('lodash');

module.exports = function(grunt) {
    'use strict';

    grunt.registerMultiTask('nunjucks', 'Renders nunjucks` template to HTML', function() {
        var options = this.options();
        var completeTask = this.async();

        if (!options.data) {
            grunt.log.warn('Template`s data is empty. Guess you forget to specify data option');
        }

        var envOptions = { watch: false };
        if (options.tags) {
            envOptions.tags = options.tags;
        }

        var basePath = options.paths || '';
        var env = nunjucks.configure(basePath, envOptions);

        if (typeof options.configureEnvironment === 'function') {
            options.configureEnvironment.call(this, env, nunjucks);
        }

        async.each(this.files, function(f, done) {
            var filepath = path.join(process.cwd(), f.src[0]);

            // We need to clone the data
            var data = _.cloneDeep(options.data || {});

            if (typeof options.preprocessData === 'function') {
                data = options.preprocessData.call(f, data);
            }

            var template = grunt.file.read(filepath);
            env.renderString(template, data, function(err, res) {
                if (err) {
                    grunt.log.error(err);
                    return done();
                }
                grunt.file.write(f.dest, res);
                grunt.log.writeln('File "' + f.dest + '" created.');
                done();
            });

        }, function(err) {
            if (err) {
                grunt.log.error(err);
            }
            completeTask();
        });
    });
};
<commit_msg>fail build in case of error with warning, closes #28<commit_after>/**
 * grunt-nunjucks-2-html
 * https://github.com/vitkarpov/grunt-nunjucks-2-html
 *
 * Copyright (c) 2014 Vit Karpov
 * Licensed under the MIT license.
 */

var nunjucks = require('nunjucks');
var path = require('path');
var async = require('async');
var _ = require('lodash');

module.exports = function(grunt) {
    'use strict';

    grunt.registerMultiTask('nunjucks', 'Renders nunjucks` template to HTML', function() {
        var options = this.options();
        var completeTask = this.async();

        if (!options.data) {
            grunt.log.warn('Template`s data is empty. Guess you forget to specify data option');
        }

        var envOptions = { watch: false };
        if (options.tags) {
            envOptions.tags = options.tags;
        }

        var basePath = options.paths || '';
        var env = nunjucks.configure(basePath, envOptions);

        if (typeof options.configureEnvironment === 'function') {
            options.configureEnvironment.call(this, env, nunjucks);
        }

        async.each(this.files, function(f, done) {
            var filepath = path.join(process.cwd(), f.src[0]);

            // We need to clone the data
            var data = _.cloneDeep(options.data || {});

            if (typeof options.preprocessData === 'function') {
                data = options.preprocessData.call(f, data);
            }

            var template = grunt.file.read(filepath);
            env.renderString(template, data, function(err, res) {
                if (err) {
                    grunt.log.error(err);
                    grunt.fail.warn('Faild to compile one of sources.');
                    return done();
                }
                grunt.file.write(f.dest, res);
                grunt.log.writeln('File "' + f.dest + '" created.');
                done();
            });

        }, function(err) {
            if (err) {
                grunt.log.error(err);
                grunt.fail.warn('Something went wrong.');
            }
            completeTask();
        });
    });
};
<|endoftext|>


<commit_before>/*
 * grunt-smartrev
 *
 *
 * Copyright (c) 2014 Disqus
 * Licensed under the Apache 2.0 license.
 */

'use strict';

var crypto = require('crypto');
var fs = require('fs');
var path = require('path');

var _ = require('lodash');

var normalizePath = function (name) {
    // We need the split/join below due to Windows having \ as path separator :(
    return path.normalize(name).split(path.sep).join('/');
};

var Dependency;  // will be defined below and is used by Tree.prototype.get
var Tree = function (baseUrl, noRename, hashAlgo) {
    this.baseUrl = baseUrl;
    this.noRename = noRename;
    this.hashAlgo = hashAlgo || 'md5';
    this.nodes = {};
};

Tree.handlers = require('./handlers');

Tree._dummyHandler = {
    extract: _.noop,
    substitute: _.noop
};

Tree.getHandler = function (node) {
    return this.handlers[node.ext] || Tree._dummyHandler;
};

Tree.prototype.generate = function (files) {
    var file;
    for (var i = 0, len = files.length; i < len; i++) {
        file = files[i];
        this.get(file).findDependencies();
    }

    return this;
};

Tree.prototype.get = function (name) {
    name = normalizePath(name);
    var dep = this.nodes[name];
    if (!dep)
        dep = this.nodes[name] = new Dependency(name, this);

    return dep;
};

Tree.prototype.process = function () {
    var levels = _.groupBy(this.nodes, function (node) {
        return node.height();
    });

    var hashAlgo = this.hashAlgo;
    var level, node, name;
    for (var height = 0, maxHeight = _.size(levels) - 1; height <= maxHeight; height++) {
        level = levels[height];
        for (var i = 0, len = level.length; i < len; i++) {
            node = level[i];
            name = node.name;

            // Should be done before hashing and renaming!
            node.updateDependencyReferences();

            node.marks = null;
            node.ast = null;

            if (_.contains(this.noRename, name))
                continue;

            node.hash = crypto.createHash(hashAlgo)
                              .update(fs.readFileSync(name))
                              .digest('hex');
            node.name = normalizePath(
                path.dirname(name) + '/' +
                path.basename(name, node.ext) + '.' +  node.hash + node.ext
            );

            fs.renameSync(name, node.name);
        }
    }

    return this;
};

Tree.prototype.stats = function () {
    var tree = this;
    return Object.keys(tree.nodes).reduce(function (stats, name) {
        var dep = tree.nodes[name];
        stats[name] = {
            newName: dep.name,
            height: dep.height(),
            size: fs.statSync(dep.name).size,
            dependencies: Object.keys(dep.dependencies)
        };

        return stats;
    }, {});
};

Dependency = function (name, tree) {
    this.tree = tree;
    this.name = name;
    this.ext = path.extname(name);
    this.dependencies = {};

    // This array will store the "AST-nodes" that contain references to other
    // files so that we won't need to parse the source again, when replacing
    // those references with the modified files names (the ones with hashes).
    this.marks = [];
};

Dependency.prototype._height = null;
Dependency.prototype.ast = null;
Dependency.prototype.hash = null;

Dependency.prototype.resolve = function (url) {
    return path.relative(process.cwd(), path.resolve(path.dirname(this.name), url));
};

// Returns hashed url relative to file (this.name)
Dependency.prototype.resolveAsHashedUrl = function (url) {
    var resolvedUrl = this.resolve(url);
    var hashedUrl = this.tree.get(resolvedUrl).name;
    var baseUrl = this.tree.baseUrl;
    var basePath = baseUrl ? process.cwd() : path.dirname(this.name);

    var finalUrl = path.normalize(path.relative(basePath, hashedUrl));

    if (baseUrl)
        finalUrl = baseUrl + '/' + resolvedUrl;

    return finalUrl.split(path.sep).join('/');  // Because these are URLs (and Windows)
};

Dependency.prototype.dependOn = function (node) {
    this.dependencies[node.name] = node;
};

Dependency.prototype.height = function () {
    if (this._height !== null)
        return this._height;

    var dependencies = _.values(this.dependencies);
    var result;
    if (!dependencies.length)
        result = 0;
    else
        result = 1 + Math.max.apply(Math, _.invoke(dependencies, 'height'));

    /* jshint boss: true */
    return this._height = result;
    /* jshint boss: false */
};

Dependency.prototype.findDependencies = function () {
    Tree.getHandler(this).extract.call(this);

    return this;
};

Dependency.prototype.updateDependencyReferences = function () {
    // Zero-height nodes don't have any dependencies so we don't need to update
    // any references. Yay, skip!
    if (!this.height())
        return this;

    Tree.getHandler(this).substitute.call(this);

    return this;
};

module.exports = function (grunt) {
    var filterFiles = function (filepath) {
        if (!grunt.file.exists(filepath)) {
            grunt.log.warn('Source file "' + filepath + '" not found.');
            return false;
        } else {
            return true;
        }
    };

    grunt.registerMultiTask(
        'smartrev', 'Walks all files, creates a dependency tree and renames all of them using hashes of their contents',
        function () {
            var owd = process.cwd();
            var options = this.options({
                cwd: '.',
                baseUrl: '',
                noRename: [],
                algorithm: 'md5'
            });

            process.chdir(options.cwd);

            // Iterate over all specified file groups.
            this.files.forEach(function (f) {
                var tree = new Tree(
                    _.result(options, 'baseUrl'),
                    grunt.file.expand({}, options.noRename),
                    options.algorithm
                ).generate(f.src.filter(filterFiles)).process();

                if (f.dest)
                    grunt.file.write(f.dest, JSON.stringify(tree.stats()));
            });

            process.chdir(owd);
        }
    );
};
<commit_msg>Fix tests<commit_after>/*
 * grunt-smartrev
 *
 *
 * Copyright (c) 2014 Disqus
 * Licensed under the Apache 2.0 license.
 */

'use strict';

var crypto = require('crypto');
var fs = require('fs');
var path = require('path');

var _ = require('lodash');

var normalizePath = function (name) {
    // We need the split/join below due to Windows having \ as path separator :(
    return path.normalize(name).split(path.sep).join('/');
};

var Dependency;  // will be defined below and is used by Tree.prototype.get
var Tree = function (baseUrl, noRename, hashAlgo) {
    this.baseUrl = baseUrl;
    this.noRename = noRename;
    this.hashAlgo = hashAlgo || 'md5';
    this.nodes = {};
};

Tree.handlers = require('./handlers');

Tree._dummyHandler = {
    extract: _.noop,
    substitute: _.noop
};

Tree.getHandler = function (node) {
    return this.handlers[node.ext] || Tree._dummyHandler;
};

Tree.prototype.generate = function (files) {
    var file;
    for (var i = 0, len = files.length; i < len; i++) {
        file = files[i];
        this.get(file).findDependencies();
    }

    return this;
};

Tree.prototype.get = function (name) {
    name = normalizePath(name);
    var dep = this.nodes[name];
    if (!dep)
        dep = this.nodes[name] = new Dependency(name, this);

    return dep;
};

Tree.prototype.process = function () {
    var levels = _.groupBy(this.nodes, function (node) {
        return node.height();
    });

    var hashAlgo = this.hashAlgo;
    var level, node, name;
    for (var height = 0, maxHeight = _.size(levels) - 1; height <= maxHeight; height++) {
        level = levels[height];
        for (var i = 0, len = level.length; i < len; i++) {
            node = level[i];
            name = node.name;

            // Should be done before hashing and renaming!
            node.updateDependencyReferences();

            node.marks = null;
            node.ast = null;

            if (_.contains(this.noRename, name))
                continue;

            node.hash = crypto.createHash(hashAlgo)
                              .update(fs.readFileSync(name))
                              .digest('hex');
            node.name = normalizePath(
                path.dirname(name) + '/' +
                path.basename(name, node.ext) + '.' +  node.hash + node.ext
            );

            fs.renameSync(name, node.name);
        }
    }

    return this;
};

Tree.prototype.stats = function () {
    var tree = this;
    return Object.keys(tree.nodes).reduce(function (stats, name) {
        var dep = tree.nodes[name];
        stats[name] = {
            newName: dep.name,
            height: dep.height(),
            size: fs.statSync(dep.name).size,
            dependencies: Object.keys(dep.dependencies)
        };

        return stats;
    }, {});
};

Dependency = function (name, tree) {
    this.tree = tree;
    this.name = name;
    this.ext = path.extname(name);
    this.dependencies = {};

    // This array will store the "AST-nodes" that contain references to other
    // files so that we won't need to parse the source again, when replacing
    // those references with the modified files names (the ones with hashes).
    this.marks = [];
};

Dependency.prototype._height = null;
Dependency.prototype.ast = null;
Dependency.prototype.hash = null;

Dependency.prototype.resolve = function (url) {
    return path.relative(process.cwd(), path.resolve(path.dirname(this.name), url));
};

// Returns hashed url relative to file (this.name)
Dependency.prototype.resolveAsHashedUrl = function (url) {
    var hashedUrl = this.tree.get(this.resolve(url)).name;
    var baseUrl = this.tree.baseUrl;
    var basePath = baseUrl ? process.cwd() : path.dirname(this.name);
    var resolvedUrl = path.normalize(path.relative(basePath, hashedUrl));

    if (baseUrl)
        resolvedUrl = baseUrl + '/' + resolvedUrl;

    return resolvedUrl.split(path.sep).join('/');  // Because these are URLs (and Windows)
};

Dependency.prototype.dependOn = function (node) {
    this.dependencies[node.name] = node;
};

Dependency.prototype.height = function () {
    if (this._height !== null)
        return this._height;

    var dependencies = _.values(this.dependencies);
    var result;
    if (!dependencies.length)
        result = 0;
    else
        result = 1 + Math.max.apply(Math, _.invoke(dependencies, 'height'));

    /* jshint boss: true */
    return this._height = result;
    /* jshint boss: false */
};

Dependency.prototype.findDependencies = function () {
    Tree.getHandler(this).extract.call(this);

    return this;
};

Dependency.prototype.updateDependencyReferences = function () {
    // Zero-height nodes don't have any dependencies so we don't need to update
    // any references. Yay, skip!
    if (!this.height())
        return this;

    Tree.getHandler(this).substitute.call(this);

    return this;
};

module.exports = function (grunt) {
    var filterFiles = function (filepath) {
        if (!grunt.file.exists(filepath)) {
            grunt.log.warn('Source file "' + filepath + '" not found.');
            return false;
        } else {
            return true;
        }
    };

    grunt.registerMultiTask(
        'smartrev', 'Walks all files, creates a dependency tree and renames all of them using hashes of their contents',
        function () {
            var owd = process.cwd();
            var options = this.options({
                cwd: '.',
                baseUrl: '',
                noRename: [],
                algorithm: 'md5'
            });

            process.chdir(options.cwd);

            // Iterate over all specified file groups.
            this.files.forEach(function (f) {
                var tree = new Tree(
                    _.result(options, 'baseUrl'),
                    grunt.file.expand({}, options.noRename),
                    options.algorithm
                ).generate(f.src.filter(filterFiles)).process();

                if (f.dest)
                    grunt.file.write(f.dest, JSON.stringify(tree.stats()));
            });

            process.chdir(owd);
        }
    );
};
<|endoftext|>