<commit_before>/*
 * TODO:
 *  - https://github.com/filamentgroup/grunt-criticalcss
 *  - GULP + comment
 *  - grunt modernizr (webapp)
 *  - sass source maps
 *  - make imagemin work
 *  - TODO.md
 *  - update to new h5bp structure
 *  - drop compass ?
 *  - drop Foundation ?
 *  - https://github.com/yeoman/grunt-usemin#blockreplacements for
 *  - picturefill + http://vimeo.com/92794354 (img/original -> img/scaled)
 *  - Modernizr CDN
 *  - visuallyhidden -> vh? (+ remove unneccessary/unused classes)
 *  - humans.txt + rel attr
 *  - uncss, class names minification
 *  - GA (https://github.com/dciccale/grunt-processhtml, https://github.com/changer/grunt-targethtml) + ask for key
 *    - new task ("dploy"/"production"), because of build is sometimes being used for testing final product (don't wanna analyze this :))
 *  - modernizr custom build/CDN
 *  - do I need to include normalize, h5bp, foundation & compass resets?
 *  - support IE desktops https://github.com/jtangelder/grunt-stripmq, http://robin.medvedi.eu/mobile-first-and-ie8-solution-introducing-grunt-legacssy/
 *  - separate print styles and add media element for IE8-
 *  - print.scss, ie.scss (if supported)
 *  - git initialization
 *  - README - file system (to both READMEs)
 *  - open sublime when ready
 *  - check svgmin options
 *
 */

'use strict';
var util = require('util');
var path = require('path');
var yeoman = require('yeoman-generator');
var file = yeoman.file;

var WebProjectGenerator = module.exports = function WebProjectGenerator(args, options, config) {
	yeoman.generators.Base.apply(this, arguments);

	this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
};

util.inherits(WebProjectGenerator, yeoman.generators.Base);

WebProjectGenerator.prototype.askFor = function askFor() {
	var cb = this.async();

	// welcome message
	console.log(this.yeoman);
	console.log('Foundation5 with Compass and HTML5 Boilerplate are prepared!');

	var prompts = [{
		name: 'language',
		message: 'Which language would you like to use? (ISO abbreviation)',
		default: 'en'
	}, {
		type: 'confirm',
		name: 'createSublimeTextProjectFile',
		message: 'Create Sublime Text project file?',
		default: true
	}, {
		name: 'htmlTitle',
		message: 'Your HTML <title>?',
		default: this.appname
	}];

	this.prompt(prompts, function (answers) {
		// // manually deal with the response, get back and store the results.
		// // we change a bit this way of doing to automatically do this in the self.prompt() method.
		this.language = answers.language;
		this.createSublimeTextProjectFile = answers.createSublimeTextProjectFile;
		this.htmlTitle = answers.htmlTitle;

		cb();
	}.bind(this));
};

WebProjectGenerator.prototype.gruntfile = function gruntfile() {
	this.template('Gruntfile.js');
};

WebProjectGenerator.prototype.packageJSON = function packageJSON() {
	this.template('_package.json', 'package.json');
};

WebProjectGenerator.prototype.SassConfig = function SassConfig() {
	this.copy('configs/config.rb', 'config.rb');
};

WebProjectGenerator.prototype.git = function git() {
	this.copy('configs/gitignore', '.gitignore');
	this.copy('configs/gitattributes', '.gitattributes');
};

WebProjectGenerator.prototype.bower = function bower() {
	this.copy('configs/bowerrc', '.bowerrc');
	this.template('_bower.json', 'bower.json');
};

WebProjectGenerator.prototype.editor = function editor() {
	this.copy('configs/editorconfig', '.editorconfig');
	if (this.createSublimeTextProjectFile) {
		this.template('configs/project.sublime-project', this._.slugify(this.appname) + '.sublime-project');
	}
};

WebProjectGenerator.prototype.assets = function assets() {
	this.mkdir('assets');
	this.mkdir('assets/font');
	this.mkdir('assets/img');
	this.mkdir('assets/js');
	this.mkdir('assets/scss');

	this.mkdir('assets/scss/components');
	this.mkdir('assets/scss/helpers');
	this.mkdir('assets/scss/layout');
	this.mkdir('assets/scss/settings');
	this.mkdir('assets/scss/vendor');
};

WebProjectGenerator.prototype.files = function files() {
	this.template('_README.md', 'README.md');

	if (file.exists(this.src._base + '/404/404_' + this.language + '.html')) {
		this.copy('404/404_' + this.language + '.html', '404.html');
	}
	else {
		console.log('There is not 404.html error page in your choosen language, I\'m including english version.');
		this.copy('404/404_en.html', '404.html');
	}

	this.copy('icons/favicon.ico', 'favicon.ico');
	this.copy('icons/apple-touch-icon-precomposed.png', 'apple-touch-icon-precomposed.png');

	this.copy('configs/htaccess', '.htaccess');
	this.copy('configs/robots.txt', 'robots.txt');
	this.copy('configs/crossdomain.xml', 'crossdomain.xml');

	this.copy('scss/main.scss', 'assets/scss/main.scss');
	this.copy('scss/ie8.scss', 'assets/scss/ie8.scss');
	this.copy('scss/settings.scss', 'assets/scss/settings/_foundation.scss');
	this.copy('scss/h5bp.scss', 'assets/scss/vendor/_h5bp.scss');
	this.copy('scss/foundation.scss', 'assets/scss/vendor/_foundation.scss');

	this.copy('scss/mixins.scss', 'assets/scss/helpers/_mixins.scss');
	this.copy('scss/placeholders.scss', 'assets/scss/helpers/_placeholders.scss');

	this.copy('scss/z-index-settings.scss', 'assets/scss/settings/_z-index.scss');
	this.copy('scss/z-index-helper.scss', 'assets/scss/helpers/_z-index.scss');

	this.copy('js/main.js', 'assets/js/main.js');
	this.copy('js/plugins.js', 'assets/js/plugins.js');
	this.copy('js/jquery-2.1.0.js', 'assets/js/jquery.js'); // for dev CDN fallback, for production compiled by grunt from bower_components
	this.copy('js/jquery-1.8.0.js', 'assets/js/jquery-1.8.0.js');
	this.copy('js/selectivizr-1.0.3b.js', 'assets/js/selectivizr-1.0.3b.js');
};

WebProjectGenerator.prototype.index = function index() {

	this.copy('index.html', 'index.html');
};

WebProjectGenerator.prototype.install = function () {
	var done = this.async();
	this.installDependencies({
		callback: done
	});
};<commit_msg>Update TODO<commit_after>/*
 * TODO:
 *  - $button-bg -> $button-bg-color
 *  - https://github.com/filamentgroup/grunt-criticalcss
 *  - GULP + comment
 *  - grunt modernizr (webapp)
 *  - sass source maps
 *  - make imagemin work
 *  - TODO.md
 *  - update to new h5bp structure
 *  - drop compass ?
 *  - drop Foundation ?
 *  - https://github.com/yeoman/grunt-usemin#blockreplacements for
 *  - picturefill + http://vimeo.com/92794354 (img/original -> img/scaled)
 *  - Modernizr CDN
 *  - visuallyhidden -> vh? (+ remove unneccessary/unused classes)
 *  - humans.txt + rel attr
 *  - uncss, class names minification
 *  - GA (https://github.com/dciccale/grunt-processhtml, https://github.com/changer/grunt-targethtml) + ask for key
 *    - new task ("dploy"/"production"), because of build is sometimes being used for testing final product (don't wanna analyze this :))
 *  - modernizr custom build/CDN
 *  - do I need to include normalize, h5bp, foundation & compass resets?
 *  - support IE desktops https://github.com/jtangelder/grunt-stripmq, http://robin.medvedi.eu/mobile-first-and-ie8-solution-introducing-grunt-legacssy/
 *  - separate print styles and add media element for IE8- (https://github.com/bpscott/breakup)
 *  - print.scss, ie.scss (if supported)
 *  - git initialization
 *  - README - file system (to both READMEs)
 *  - open sublime when ready
 *  - check svgmin options
 *
 */

'use strict';
var util = require('util');
var path = require('path');
var yeoman = require('yeoman-generator');
var file = yeoman.file;

var WebProjectGenerator = module.exports = function WebProjectGenerator(args, options, config) {
	yeoman.generators.Base.apply(this, arguments);

	this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
};

util.inherits(WebProjectGenerator, yeoman.generators.Base);

WebProjectGenerator.prototype.askFor = function askFor() {
	var cb = this.async();

	// welcome message
	console.log(this.yeoman);
	console.log('Foundation5 with Compass and HTML5 Boilerplate are prepared!');

	var prompts = [{
		name: 'language',
		message: 'Which language would you like to use? (ISO abbreviation)',
		default: 'en'
	}, {
		type: 'confirm',
		name: 'createSublimeTextProjectFile',
		message: 'Create Sublime Text project file?',
		default: true
	}, {
		name: 'htmlTitle',
		message: 'Your HTML <title>?',
		default: this.appname
	}];

	this.prompt(prompts, function (answers) {
		// // manually deal with the response, get back and store the results.
		// // we change a bit this way of doing to automatically do this in the self.prompt() method.
		this.language = answers.language;
		this.createSublimeTextProjectFile = answers.createSublimeTextProjectFile;
		this.htmlTitle = answers.htmlTitle;

		cb();
	}.bind(this));
};

WebProjectGenerator.prototype.gruntfile = function gruntfile() {
	this.template('Gruntfile.js');
};

WebProjectGenerator.prototype.packageJSON = function packageJSON() {
	this.template('_package.json', 'package.json');
};

WebProjectGenerator.prototype.SassConfig = function SassConfig() {
	this.copy('configs/config.rb', 'config.rb');
};

WebProjectGenerator.prototype.git = function git() {
	this.copy('configs/gitignore', '.gitignore');
	this.copy('configs/gitattributes', '.gitattributes');
};

WebProjectGenerator.prototype.bower = function bower() {
	this.copy('configs/bowerrc', '.bowerrc');
	this.template('_bower.json', 'bower.json');
};

WebProjectGenerator.prototype.editor = function editor() {
	this.copy('configs/editorconfig', '.editorconfig');
	if (this.createSublimeTextProjectFile) {
		this.template('configs/project.sublime-project', this._.slugify(this.appname) + '.sublime-project');
	}
};

WebProjectGenerator.prototype.assets = function assets() {
	this.mkdir('assets');
	this.mkdir('assets/font');
	this.mkdir('assets/img');
	this.mkdir('assets/js');
	this.mkdir('assets/scss');

	this.mkdir('assets/scss/components');
	this.mkdir('assets/scss/helpers');
	this.mkdir('assets/scss/layout');
	this.mkdir('assets/scss/settings');
	this.mkdir('assets/scss/vendor');
};

WebProjectGenerator.prototype.files = function files() {
	this.template('_README.md', 'README.md');

	if (file.exists(this.src._base + '/404/404_' + this.language + '.html')) {
		this.copy('404/404_' + this.language + '.html', '404.html');
	}
	else {
		console.log('There is not 404.html error page in your choosen language, I\'m including english version.');
		this.copy('404/404_en.html', '404.html');
	}

	this.copy('icons/favicon.ico', 'favicon.ico');
	this.copy('icons/apple-touch-icon-precomposed.png', 'apple-touch-icon-precomposed.png');

	this.copy('configs/htaccess', '.htaccess');
	this.copy('configs/robots.txt', 'robots.txt');
	this.copy('configs/crossdomain.xml', 'crossdomain.xml');

	this.copy('scss/main.scss', 'assets/scss/main.scss');
	this.copy('scss/ie8.scss', 'assets/scss/ie8.scss');
	this.copy('scss/settings.scss', 'assets/scss/settings/_foundation.scss');
	this.copy('scss/h5bp.scss', 'assets/scss/vendor/_h5bp.scss');
	this.copy('scss/foundation.scss', 'assets/scss/vendor/_foundation.scss');

	this.copy('scss/mixins.scss', 'assets/scss/helpers/_mixins.scss');
	this.copy('scss/placeholders.scss', 'assets/scss/helpers/_placeholders.scss');

	this.copy('scss/z-index-settings.scss', 'assets/scss/settings/_z-index.scss');
	this.copy('scss/z-index-helper.scss', 'assets/scss/helpers/_z-index.scss');

	this.copy('js/main.js', 'assets/js/main.js');
	this.copy('js/plugins.js', 'assets/js/plugins.js');
	this.copy('js/jquery-2.1.0.js', 'assets/js/jquery.js'); // for dev CDN fallback, for production compiled by grunt from bower_components
	this.copy('js/jquery-1.8.0.js', 'assets/js/jquery-1.8.0.js');
	this.copy('js/selectivizr-1.0.3b.js', 'assets/js/selectivizr-1.0.3b.js');
};

WebProjectGenerator.prototype.index = function index() {

	this.copy('index.html', 'index.html');
};

WebProjectGenerator.prototype.install = function () {
	var done = this.async();
	this.installDependencies({
		callback: done
	});
};<|endoftext|>


<commit_before>/* vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab : */
'use strict';
var util = require('util');
var path = require('path');
var fs = require('fs');
var yeoman = require('yeoman-generator');

var BeezSubmoduleGenerator = module.exports = function BeezSubmoduleGenerator(args, options, config) {
  yeoman.generators.Base.apply(this, arguments);

  this.on('end', function () {
    // bower & npm install settings
    this.installDependencies({
      bower: false,
      npm: true,
      skipInstall: options['skip-install'],
      skipMessage: true,
      callback: function () {
        fs.unlink('package.json');
      }
    });
  });

  this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
};

util.inherits(BeezSubmoduleGenerator, yeoman.generators.Base);

BeezSubmoduleGenerator.prototype.askFor = function askFor() {
  var cb = this.async(),
      moduleName = function moduleName() {
        var name;

        if (this.args.length > 0) {
          name = this.args[0];
        } else {
          name = path.basename(process.cwd());
        }

        return name;
      }.bind(this);

  // have Yeoman greet the user.
  console.log(this.yeoman);

  var prompts = [{
    type: 'checkbox',
    name: 'mvcr',
    message: 'Check necessary parts',
    choices: [
      {
        name: 'Model',
        checked: false
      },
      {
        name: 'Collection',
        checked: false
      },
      {
        name: 'View',
        checked: true
      }
    ],
    validate: function (c) {
      var done = this.async();

      if (c.length === 0) {
        done('At least check one property');
      }

      done(true);
    }
  }, {
    name: 'name',
    message: 'Submodule Name',
    default: moduleName,
    validate: function (w) {
      var done = this.async();

      // if directory is existed.
      if (fs.existsSync(w)) {
        done(w + ' has been already existed. The submodule should be have another name.');

        return;
      }

      done(true);
    }
  }, {
    name: 'description',
    message: 'Description',
    default: 'The best submodule ever.'
  }, {
    name: 'authorName',
    message: 'Author\'s Name',
    validate: function (w) {
      var done = this.async();

      // if no author name then show message.
      if (w.length === 0) {
        done('You should put your name.');
      }

      done(true);
    },
      // use git username when set
    default: this.user.git.username
  }, {
    name: 'authorEmail',
    message: 'Author\'s Email',
    validate: function (w) {
      var done = this.async();

      // if no email then show message.
      if (w.length === 0) {
        done('You should put your email.');
      }

      done(true);
    },
    // use git email when set
    default: this.user.git.email
  }];

  this.prompt(prompts, function (props) {
    // slugify name
    this.slugname = this._.slugify(props.name);
    this.safeSlugname = this.slugname.replace(
      /-([a-z])/g,
      function (g) { return g[1].toUpperCase(); }
    );

    if (props.mvcr.length >= 0) {
      props.mvcr.forEach(function (i) {
        if (i === 'Model') {
          props.model = true;
        }
        if (i === 'View') {
          props.view = true;
        }
        if (i === 'Collection') {
          props.collection = true;
        }
      });
    }

    this.props = props;

    cb();
  }.bind(this));
};

BeezSubmoduleGenerator.prototype.app = function app() {
  var submoduleName = this.props.name,
      yellow = '\u001b[33m',
      message = '\u001b[31m' + 'Put below code in your configure file. (in conf directory)\n',
      directory;

  message += yellow + 'Appends the routing configuration - {ProjectDir}/conf/[env]/[key].json\n\n';
  message += yellow + '"' + this.slugname + '": {\n';
  message += yellow + '\t  "route": "' + this.slugname + '",\n';
  message += yellow + '\t  "name": "' + this.slugname + '",\n';
  message += yellow + '\t  "require": "' + this.slugname + '/index' + '",\n';
  message += yellow + '\t  "xpath": "/@/' + this.slugname + '"\n';
  message += yellow + '}"\n';

  // if pass a argument make directory using argument name
  if (this.args.length > 0) {
    directory = this.slugname + '/';

    this.mkdir(directory);
  } else {
    directory = '';
  }

  this.mkdir(directory + 'img');
  this.template('index.js', directory + 'index.js');

  if (this.props.model) {
    this.template('model/index.js', directory + 'model/index.js');
  }
  if (this.props.collection) {
    this.template('collection/index.js', directory + 'collection/index.js');
  }
  if (this.props.view) {
    this.template('view/index.js', directory + 'view/index.js');
  }

  this.template('i18n/ja.js', directory + 'i18n/ja.js');
  this.template('hbs/submodule.hbs', directory + 'hbs/' + submoduleName + '.hbs');
  this.template('styl/submodule.styl', directory + 'styl/' + submoduleName + '.styl');
  this.template('test/index.js', directory + 'test/index.js');
  this.template('mock.submodule.html.hbs', directory + 'mock.' + submoduleName + '.html.hbs');

  console.log(message);
};

BeezSubmoduleGenerator.prototype.projectfiles = function projectfiles() {
  this.template('_package.json', 'package.json');
};
<commit_msg>Fix: small fix<commit_after>/* vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab : */
'use strict';
var util = require('util');
var path = require('path');
var fs = require('fs');
var yeoman = require('yeoman-generator');

var BeezSubmoduleGenerator = module.exports = function BeezSubmoduleGenerator(args, options, config) {
  yeoman.generators.Base.apply(this, arguments);

  this.on('end', function () {
    // bower & npm install settings
    this.installDependencies({
      bower: false,
      npm: true,
      skipInstall: options['skip-install'],
      skipMessage: true,
      callback: function () {
        fs.unlink('package.json');
      }
    });
  });

  this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
};

util.inherits(BeezSubmoduleGenerator, yeoman.generators.Base);

BeezSubmoduleGenerator.prototype.askFor = function askFor() {
  var cb = this.async(),
      moduleName = function moduleName() {
        var name;

        if (this.args.length > 0) {
          name = this.args[0];
        } else {
          name = path.basename(process.cwd());
        }

        return name;
      }.bind(this);

  // have Yeoman greet the user.
  console.log(this.yeoman);

  var prompts = [{
    type: 'checkbox',
    name: 'mvcr',
    message: 'Check necessary parts',
    choices: [
      {
        name: 'Model',
        checked: false
      },
      {
        name: 'Collection',
        checked: false
      },
      {
        name: 'View',
        checked: true
      }
    ],
    validate: function (c) {
      var done = this.async();

      if (c.length === 0) {
        done('At least check one property');
      }

      done(true);
    }
  }, {
    name: 'name',
    message: 'Submodule Name',
    default: moduleName,
    validate: function (w) {
      var done = this.async();

      // if directory is existed.
      if (fs.existsSync(w)) {
        done(w + ' has been already existed. The submodule should be have another name.');

        return;
      }

      done(true);
    }
  }, {
    name: 'description',
    message: 'Description',
    default: 'The best submodule ever.'
  }, {
    name: 'authorName',
    message: 'Author\'s Name',
    validate: function (w) {
      var done = this.async();

      // if no author name then show message.
      if (w.length === 0) {
        done('You should put your name.');
      }

      done(true);
    },
      // use git username when set
    default: this.user.git.username
  }, {
    name: 'authorEmail',
    message: 'Author\'s Email',
    validate: function (w) {
      var done = this.async();

      // if no email then show message.
      if (w.length === 0) {
        done('You should put your email.');
      }

      done(true);
    },
    // use git email when set
    default: this.user.git.email
  }];

  this.prompt(prompts, function (props) {
    // slugify name
    this.slugname = this._.slugify(props.name);
    this.safeSlugname = this.slugname.replace(
      /-([a-z])/g,
      function (g) { return g[1].toUpperCase(); }
    );

    if (props.mvcr.length >= 0) {
      props.mvcr.forEach(function (i) {
        if (i === 'Model') {
          props.model = true;
        }
        if (i === 'View') {
          props.view = true;
        }
        if (i === 'Collection') {
          props.collection = true;
        }
      });
    }

    this.props = props;

    cb();
  }.bind(this));
};

BeezSubmoduleGenerator.prototype.app = function app() {
  var submoduleName = this.props.name,
      yellow = '\u001b[33m',
      message = '\u001b[31m' + 'Appends the routing configuration - {ProjectDir}/conf/[env]/[key].json\n\n',
      directory;

  message += yellow + '>>>>\n\t"' + this.slugname + '": {\n';
  message += yellow + '\t\t"route": "' + this.slugname + '",\n';
  message += yellow + '\t\t"name": "' + this.slugname + '",\n';
  message += yellow + '\t\t"require": "' + this.slugname + '/index' + '",\n';
  message += yellow + '\t\t"xpath": "/@/' + this.slugname + '"\n';
  message += yellow + '\t}\n<<<<\n';

  // if pass a argument make directory using argument name
  if (this.args.length > 0) {
    directory = this.slugname + '/';

    this.mkdir(directory);
  } else {
    directory = '';
  }

  this.mkdir(directory + 'img');
  this.template('index.js', directory + 'index.js');

  if (this.props.model) {
    this.template('model/index.js', directory + 'model/index.js');
  }
  if (this.props.collection) {
    this.template('collection/index.js', directory + 'collection/index.js');
  }
  if (this.props.view) {
    this.template('view/index.js', directory + 'view/index.js');
  }

  this.template('i18n/ja.js', directory + 'i18n/ja.js');
  this.template('hbs/submodule.hbs', directory + 'hbs/' + submoduleName + '.hbs');
  this.template('styl/submodule.styl', directory + 'styl/' + submoduleName + '.styl');
  this.template('test/index.js', directory + 'test/index.js');
  this.template('mock.submodule.html.hbs', directory + 'mock.' + submoduleName + '.html.hbs');

  console.log(message);
};

BeezSubmoduleGenerator.prototype.projectfiles = function projectfiles() {
  this.template('_package.json', 'package.json');
};
<|endoftext|>


<commit_before>define(
  'ephox.alloy.ui.composite.TabSectionSpec',

  [
    'ephox.alloy.alien.EventRoot',
    'ephox.alloy.api.SystemEvents',
    'ephox.alloy.api.behaviour.Highlighting',
    'ephox.alloy.api.behaviour.Replacing',
    'ephox.alloy.api.behaviour.Representing',
    'ephox.alloy.construct.EventHandler',
    'ephox.boulder.api.Objects',
    'ephox.compass.Arr',
    'ephox.sugar.api.Attr'
  ],

  function (EventRoot, SystemEvents, Highlighting, Replacing, Representing, EventHandler, Objects, Arr, Attr) {
    var make = function (detail, components, spec, externals) {

      var changeTab = function (button) {
        var tabValue = Representing.getValue(button);
        button.getSystem().getByUid(detail.partUids().tabview).each(function (tabview) {
          var tabData = Arr.find(detail.tabs(), function (t) {
            return t.value === tabValue;
          });

          var panel = tabData.view();

          // Update the tabview to refer to the current tab.
          Attr.set(tabview.element(), 'aria-labelledby', Attr.get(button.element(), 'id'));
          Replacing.set(tabview, panel);
        });
      };

      return {
        uid: detail.uid(),
        uiType: 'custom',
        dom: detail.dom(),
        components: components,

        events: Objects.wrapAll([
          {
            key: SystemEvents.systemInit(),
            value: EventHandler.nu({
              run: function (section, simulatedEvent) {
                if (detail.selectFirst() && EventRoot.isSource(section, simulatedEvent)) {
                  section.getSystem().getByUid(detail.partUids().tabbar).each(function (tabbar) {
                    Highlighting.getFirst(tabbar).each(function (button) {
                      changeTab(button);
                    });
                  });
                }
              }
            })
          },

          {
            key: SystemEvents.changeTab(),
            value: EventHandler.nu({
              run: function (section, simulatedEvent) {
                var button = simulatedEvent.event().button();
                changeTab(button);
              }
            })
          }

        ])
      };

    };

    return {
      make: make
    };
  }
);<commit_msg>VAN-44-wheel-hackery-apis-2: tab section<commit_after>define(
  'ephox.alloy.ui.composite.TabSectionSpec',

  [
    'ephox.alloy.alien.EventRoot',
    'ephox.alloy.api.SystemEvents',
    'ephox.alloy.api.behaviour.Highlighting',
    'ephox.alloy.api.behaviour.Replacing',
    'ephox.alloy.api.behaviour.Representing',
    'ephox.alloy.construct.EventHandler',
    'ephox.boulder.api.Objects',
    'ephox.compass.Arr',
    'ephox.sugar.api.Attr'
  ],

  function (EventRoot, SystemEvents, Highlighting, Replacing, Representing, EventHandler, Objects, Arr, Attr) {
    var make = function (detail, components, spec, externals) {

      var changeTab = function (button) {
        var tabValue = Representing.getValue(button);
        button.getSystem().getByUid(detail.partUids().tabview).each(function (tabview) {
          var tabData = Arr.find(detail.tabs(), function (t) {
            return t.value === tabValue;
          });

          var panel = tabData.view();

          // Update the tabview to refer to the current tab.
          Attr.set(tabview.element(), 'aria-labelledby', Attr.get(button.element(), 'id'));
          Replacing.set(tabview, panel);
        });
      };

      return {
        uid: detail.uid(),
        uiType: 'custom',
        dom: detail.dom(),
        components: components,

        events: Objects.wrapAll([
          {
            key: SystemEvents.systemInit(),
            value: EventHandler.nu({
              run: function (section, simulatedEvent) {
                if (detail.selectFirst() && EventRoot.isSource(section, simulatedEvent)) {
                  section.getSystem().getByUid(detail.partUids().tabbar).each(function (tabbar) {
                    Highlighting.getFirst(tabbar).each(function (button) {
                      Highlighting.highlight(tabbar, button);
                      changeTab(button);
                    });
                  });
                }
              }
            })
          },

          {
            key: SystemEvents.changeTab(),
            value: EventHandler.nu({
              run: function (section, simulatedEvent) {
                var button = simulatedEvent.event().button();
                changeTab(button);
              }
            })
          }

        ])
      };

    };

    return {
      make: make
    };
  }
);<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash');

var themeFunctions = require('theme/functions') || {};
var config = require('config');

var applyHooks = function (posts, functionArray) {
  var posts = posts;
  functionArray.forEach(function(callback){
    posts = callback(posts);
  });

  return posts;
}

var getFunctions = function (hookName) {
  var functions = [];

  if (themeFunctions[hookName]) {
    functions.push(themeFunctions[hookName]);
  }

  // if (config.plugins) {
  //   _.each(config.plugins, function (pluginName) {
  //     var plugin = require(pluginName);
  //     if(plugin && plugin.functions && plugin.functions[hookName]) {
  //       functions.push(plugin.functions[hookName]);
  //     }
  //   });
  // }

  if (config.site.functions && config.site.functions[hookName]) {
    functions.push(config.site.functions[hookName]);
  }

  return functions;
}

module.exports = {

  preProcessPosts: function (posts) {
    return applyHooks(posts, getFunctions('preProcessPosts'));
  },

  postProcessPosts: function (posts) {
    return applyHooks(posts, getFunctions('postProcessPosts'));
  }

}
<commit_msg>Posts hooks for plugins.<commit_after>'use strict';
var _ = require('lodash');

var themeFunctions = require('theme/functions') || {};
var config = require('config');

var applyHooks = function (posts, functionArray) {
  var posts = posts;
  functionArray.forEach(function(callback){
    posts = callback(posts);
  });

  return posts;
}

var getFunctions = function (hookName) {
  var functions = [];

  if (themeFunctions[hookName]) {
    functions.push(themeFunctions[hookName]);
  }
  if (config.site.plugins) {
    _.each(config.site.plugins, function (plugin) {
      if(plugin.functions && plugin.functions[hookName]) {
        functions.push(plugin.functions[hookName]);
      }
    });
  }
  if (config.site.functions && config.site.functions[hookName]) {
    functions.push(config.site.functions[hookName]);
  }

  return functions;
}

module.exports = {

  preProcessPosts: function (posts) {
    return applyHooks(posts, getFunctions('preProcessPosts'));
  },

  postProcessPosts: function (posts) {
    return applyHooks(posts, getFunctions('postProcessPosts'));
  }

}
<|endoftext|>


<commit_before>'use strict';
var util = require('util');
var path = require('path');
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var sh = require('execSync');
var _s = require('underscore.string');

var AuroraGenerator = yeoman.generators.Base.extend({
  init: function () {
    this.pkg = require('../package.json');

    var _this = this;

    this.on('end', function () {
      process.chdir(this.projectSlug);

      //////////////////////////////
      // Install dependencies unless --skip-install is passed
      //////////////////////////////
      if (!this.options['skip-install']) {
        var bower = this.projectOptions.indexOf('Bower') > -1 ? true : false;
        var npm = this.projectOptions.indexOf('Task Runner') > -1 ? true : false;

        sh.run('bundle install --path vendor');

        if (bower || npm) {
          this.installDependencies({
            bower: bower,
            npm: npm
          });
        }
      }

      //////////////////////////////
      // If the --git flag is passed, initialize git and add for initial commit
      //////////////////////////////
      sh.run('git init');
      sh.run('git add . && git commit -m "Aurora Generation"');
    });
  },

  askFor: function () {
    var done = this.async();

    // have Yeoman greet the user
    // this.log(this.yeoman);

    var welcome = '\n' + chalk.grey('____________________________________________________________________________________________        ') +
'\n' + chalk.grey(' ____________________________________________________________________________________________       ') +
'\n' + chalk.grey('  ____________________________________________________________________________________________      ') +
'\n' + chalk.grey('   __') + '/\\\\\\\\\\\\\\\\\\' + chalk.grey('______') + '/\\\\\\' + chalk.grey('____') + '/\\\\\\' + chalk.grey('___') + '/\\\\/\\\\\\\\\\\\\\' + chalk.grey('_______') + '/\\\\\\\\\\' + chalk.grey('______') + '/\\\\/\\\\\\\\\\\\\\' + chalk.grey('____') + '/\\\\\\\\\\\\\\\\\\' + chalk.grey('____') + '     ' +
'\n' + chalk.grey('    _') + '\\////////\\\\\\' + chalk.grey('____') + '\\/\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('__') + '\\/\\\\\\/////\\\\\\' + chalk.grey('____') + '/\\\\\\///\\\\\\' + chalk.grey('___') + '\\/\\\\\\/////\\\\\\' + chalk.grey('__') + '\\////////\\\\\\' + chalk.grey('___') + '    ' +
'\n' + chalk.grey('     ___') + '/\\\\\\\\\\\\\\\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('__') + '\\/\\\\\\' + chalk.grey('___') + '\\///' + chalk.grey('____') + '/\\\\\\' + chalk.grey('__') + '\\//\\\\\\' + chalk.grey('__') + '\\/\\\\\\' + chalk.grey('___') + '\\///' + chalk.grey('_____') + '/\\\\\\\\\\\\\\\\\\\\' + chalk.grey('__') + '   ' +
'\n' + chalk.grey('      __') + '/\\\\\\/////\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('__') + '\\/\\\\\\' + chalk.grey('__________') + '\\//\\\\\\' + chalk.grey('__') + '/\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('___________') + '/\\\\\\/////\\\\\\' + chalk.grey('__') + '  ' +
'\n' + chalk.grey('       _') + '\\//\\\\\\\\\\\\\\\\/\\\\' + chalk.grey('__') + '\\//\\\\\\\\\\\\\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('___________') + '\\///\\\\\\\\\\/' + chalk.grey('____') + '\\/\\\\\\' + chalk.grey('__________') + '\\//\\\\\\\\\\\\\\\\/\\\\' + chalk.grey('_') + ' ' +
'\n' + chalk.grey('        __') + '\\////////\\//' + chalk.grey('____') + '\\/////////' + chalk.grey('____') + '\\///' + chalk.grey('______________') + '\\/////' + chalk.grey('______') + '\\///' + chalk.grey('____________') + '\\////////\\//' + chalk.grey('__');

    this.log(welcome);

    // replace it with a short and sweet description of your generator
    this.log(chalk.magenta('\nYou\'re creating an Aurora based Drupal theme.\n' + chalk.grey('http://drupal.org/project/aurora') + ' - ' + chalk.grey('http://snugug.github.io/Aurora/\n')));

    var prompts = [
      {
        type: 'string',
        name: 'projectName',
        message: 'What\'s your theme\'s name?' + chalk.red(' (Required)'),
        validate: function (input) {
          if (input === '') {
            return 'Please enter your theme\'s name';
          }
          return true;
        }
      },
      {
        type: 'list',
        name: 'projectType',
        message: 'What Aurora base would you like to use?',
        choices: ['Aurora', 'Corona', 'Polaris', 'North'],
        default: 'Aurora'
      },
      {
        type: 'checkbox',
        name: 'projectOptions',
        message: 'What options would you like to include?',
        choices: ['Task Runner', 'Bower']
      }
    ];

    this.prompt(prompts, function (props) {
      this.projectName = props.projectName;
      this.projectSlug = _s.slugify(props.projectName);
      this.projectType = props.projectType;
      this.projectOptions = props.projectOptions;

      done();
    }.bind(this));
  },

  core: function () {
    this.copy('editorconfig', this.projectSlug + '/.editorconfig');
    this.copy('jshintrc', this.projectSlug + '/.jshintrc');
    this.copy('gitignore', this.projectSlug + '/.gitignore');

    this.copy('Gemfile', this.projectSlug + '/Gemfile');
    this.copy('config.rb', this.projectSlug + '/config.rb');

    this.copy('README-Sass.md', this.projectSlug + '/sass/README.md');
    this.copy('README-Partials.md', this.projectSlug + '/sass/partials/README.md');

    var keep = ['images', 'fonts', 'js'];
    for (var i in keep) {
      this.copy('gitkeep', this.projectSlug + '/' + keep[i] + '/.gitkeep');
    }
  },

  drupal: function () {
    this.template('_aurora.info', this.projectSlug + '/' + this.projectSlug + '.info');

    this.template('_template.php', this.projectSlug + '/template.php');
    this.copy('README-templates.md', this.projectSlug + '/templates/README.md');
  },

  options: function () {
    if (this.projectOptions.indexOf('Gulp') > -1) {
      this.template('_package.json', this.projectSlug + '/package.json');
      this.template('Gulpfile.js', this.projectSlug + '/Gulpfile.js');
    }

    if (this.projectOptions.indexOf('Bower') > -1) {
      this.template('_bower.json', this.projectSlug + '/bower.json');
    }
  },

  type: function () {
    switch (_s.slugify(this.projectType)) {
      case 'aurora':
        this.directory('aurora', this.projectSlug + '/sass');
        break;
      case 'corona':
        this.directory('corona', this.projectSlug + '/sass');
        break;
      case 'polaris':
        this.directory('polaris', this.projectSlug + '/sass');
        break;
      case 'north':
        this.copy('north/style.scss', this.projectSlug + '/sass/style.scss');

        //////////////////////////////
        // North Globals
        //////////////////////////////
        var globals = ['variables', 'functions', 'mixins', 'extends'];
        for (var i in globals) {
	  this.copy('north/all.scss', this.projectSlug + '/sass/partials/global/_' + globals[i] + '.scss');
	  this.copy('gitkeep', this.projectSlug + '/sass/partials/global/' + globals[i] + '/.gitkeep');
        }

        //////////////////////////////
        // North Keep
        //////////////////////////////
        var keep = ['sass/partials', 'sass/partials/components', 'sass/partials/layouts', 'sass/enhancements', 'sass/fallbacks'];
        for (var i in keep) {
          this.copy('gitkeep', this.projectSlug + '/' + keep[i] + '/.gitkeep');
        }
        break;
    }
  }

});

module.exports = AuroraGenerator;<commit_msg>Yo Config options, north fixes, task runner to gulp<commit_after>'use strict';
var util = require('util');
var path = require('path');
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var sh = require('execSync');
var _s = require('underscore.string');
var fs = require('fs');

var AuroraGenerator = yeoman.generators.Base.extend({
  init: function () {
    this.pkg = require('../package.json');

    var _this = this;

    this.on('end', function () {
      process.chdir(this.projectSlug);

      //////////////////////////////
      // Install dependencies unless --skip-install is passed
      //////////////////////////////
      if (!this.options['skip-install']) {
        var bower = this.projectOptions.indexOf('Bower') > -1 ? true : false;
	var npm = this.projectOptions.indexOf('Gulp') > -1 ? true : false;

        sh.run('bundle install --path vendor');

        if (bower || npm) {
          this.installDependencies({
            bower: bower,
            npm: npm
          });
        }
      }

      //////////////////////////////
      // Move Yo Storage
      //////////////////////////////
      fs.renameSync('../.yo-rc.json', '.yo-rc.json');

      //////////////////////////////
      // If the --git flag is passed, initialize git and add for initial commit
      //////////////////////////////
      sh.run('git init');
      sh.run('git add . && git commit -m "Aurora Generation"');
    });
  },

  askFor: function () {
    var done = this.async();

    // have Yeoman greet the user
    // this.log(this.yeoman);

    var welcome = '\n' + chalk.grey('____________________________________________________________________________________________        ') +
'\n' + chalk.grey(' ____________________________________________________________________________________________       ') +
'\n' + chalk.grey('  ____________________________________________________________________________________________      ') +
'\n' + chalk.grey('   __') + '/\\\\\\\\\\\\\\\\\\' + chalk.grey('______') + '/\\\\\\' + chalk.grey('____') + '/\\\\\\' + chalk.grey('___') + '/\\\\/\\\\\\\\\\\\\\' + chalk.grey('_______') + '/\\\\\\\\\\' + chalk.grey('______') + '/\\\\/\\\\\\\\\\\\\\' + chalk.grey('____') + '/\\\\\\\\\\\\\\\\\\' + chalk.grey('____') + '     ' +
'\n' + chalk.grey('    _') + '\\////////\\\\\\' + chalk.grey('____') + '\\/\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('__') + '\\/\\\\\\/////\\\\\\' + chalk.grey('____') + '/\\\\\\///\\\\\\' + chalk.grey('___') + '\\/\\\\\\/////\\\\\\' + chalk.grey('__') + '\\////////\\\\\\' + chalk.grey('___') + '    ' +
'\n' + chalk.grey('     ___') + '/\\\\\\\\\\\\\\\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('__') + '\\/\\\\\\' + chalk.grey('___') + '\\///' + chalk.grey('____') + '/\\\\\\' + chalk.grey('__') + '\\//\\\\\\' + chalk.grey('__') + '\\/\\\\\\' + chalk.grey('___') + '\\///' + chalk.grey('_____') + '/\\\\\\\\\\\\\\\\\\\\' + chalk.grey('__') + '   ' +
'\n' + chalk.grey('      __') + '/\\\\\\/////\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('__') + '\\/\\\\\\' + chalk.grey('__________') + '\\//\\\\\\' + chalk.grey('__') + '/\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('___________') + '/\\\\\\/////\\\\\\' + chalk.grey('__') + '  ' +
'\n' + chalk.grey('       _') + '\\//\\\\\\\\\\\\\\\\/\\\\' + chalk.grey('__') + '\\//\\\\\\\\\\\\\\\\\\' + chalk.grey('___') + '\\/\\\\\\' + chalk.grey('___________') + '\\///\\\\\\\\\\/' + chalk.grey('____') + '\\/\\\\\\' + chalk.grey('__________') + '\\//\\\\\\\\\\\\\\\\/\\\\' + chalk.grey('_') + ' ' +
'\n' + chalk.grey('        __') + '\\////////\\//' + chalk.grey('____') + '\\/////////' + chalk.grey('____') + '\\///' + chalk.grey('______________') + '\\/////' + chalk.grey('______') + '\\///' + chalk.grey('____________') + '\\////////\\//' + chalk.grey('__');

    this.log(welcome);

    // replace it with a short and sweet description of your generator
    this.log(chalk.magenta('\nYou\'re creating an Aurora based Drupal theme.\n' + chalk.grey('http://drupal.org/project/aurora') + ' - ' + chalk.grey('http://snugug.github.io/Aurora/\n')));

    var prompts = [
      {
        type: 'string',
        name: 'projectName',
        message: 'What\'s your theme\'s name?' + chalk.red(' (Required)'),
        validate: function (input) {
          if (input === '') {
            return 'Please enter your theme\'s name';
          }
          return true;
        }
      },
      {
        type: 'list',
        name: 'projectType',
        message: 'What Aurora base would you like to use?',
        choices: ['Aurora', 'Corona', 'Polaris', 'North'],
        default: 'Aurora'
      },
      {
        type: 'checkbox',
        name: 'projectOptions',
        message: 'What options would you like to include?',
	choices: ['Gulp', 'Bower']
      }
    ];

    this.prompt(prompts, function (props) {
      this.projectName = props.projectName;
      this.projectSlug = _s.slugify(props.projectName);
      this.projectType = props.projectType;
      this.projectOptions = props.projectOptions;

      this.config.set('projectName', this.projectName);
      this.config.set('projectSlug', this.projectSlug);
      this.config.set('projectType', this.projectType);
      this.config.set('projectOptions', this.projectOptions);

      done();
    }.bind(this));
  },

  core: function () {
    this.copy('editorconfig', this.projectSlug + '/.editorconfig');
    this.copy('jshintrc', this.projectSlug + '/.jshintrc');
    this.copy('gitignore', this.projectSlug + '/.gitignore');

    this.copy('Gemfile', this.projectSlug + '/Gemfile');
    this.copy('config.rb', this.projectSlug + '/config.rb');

    this.copy('README-Sass.md', this.projectSlug + '/sass/README.md');
    this.copy('README-Partials.md', this.projectSlug + '/sass/partials/README.md');

    var keep = ['images', 'fonts', 'js'];
    for (var i in keep) {
      this.copy('gitkeep', this.projectSlug + '/' + keep[i] + '/.gitkeep');
    }
  },

  drupal: function () {
    this.template('_aurora.info', this.projectSlug + '/' + this.projectSlug + '.info');

    this.template('_template.php', this.projectSlug + '/template.php');
    this.copy('README-templates.md', this.projectSlug + '/templates/README.md');
  },

  options: function () {
    if (this.projectOptions.indexOf('Gulp') > -1) {
      this.template('_package.json', this.projectSlug + '/package.json');
      this.template('Gulpfile.js', this.projectSlug + '/Gulpfile.js');
    }

    if (this.projectOptions.indexOf('Bower') > -1) {
      this.template('_bower.json', this.projectSlug + '/bower.json');
    }
  },

  type: function () {
    switch (_s.slugify(this.projectType)) {
      case 'aurora':
        this.directory('aurora', this.projectSlug + '/sass');
        break;
      case 'corona':
        this.directory('corona', this.projectSlug + '/sass');
        break;
      case 'polaris':
        this.directory('polaris', this.projectSlug + '/sass');
        break;
      case 'north':
        this.copy('north/style.scss', this.projectSlug + '/sass/style.scss');

        //////////////////////////////
        // North Globals
        //////////////////////////////
        var globals = ['variables', 'functions', 'mixins', 'extends'];
        for (var i in globals) {
	  this.copy('north/all.scss', this.projectSlug + '/sass/partials/global/_' + globals[i] + '.scss');
	  this.copy('gitkeep', this.projectSlug + '/sass/partials/global/' + globals[i] + '/.gitkeep');
        }

        //////////////////////////////
        // North Keep
        //////////////////////////////
        var keep = ['sass/partials', 'sass/partials/components', 'sass/partials/layouts', 'sass/enhancements', 'sass/fallbacks'];
        for (var i in keep) {
          this.copy('gitkeep', this.projectSlug + '/' + keep[i] + '/.gitkeep');
        }
        break;
    }
  }

});

module.exports = AuroraGenerator;<|endoftext|>


<commit_before>import test from 'ava'

import React, { Component } from 'react'
import { Observable } from '@reactivex/rxjs'
import { mount } from 'enzyme'

import connectStore from '../lib/decorators/connectStore'
import createDispatcher from '../lib/createDispatcher'

function Child({data}) {
  return
{data}

}

test('passes the correct static observable value', t => {
  const Tester = connectStore(Observable.of('test'))(Child)
  const wrapper = mount(<Tester/>)

  t.is(wrapper.text(), 'test')
})

test('passes selector-applied observable value based on props', t => {
  const Tester = connectStore((_, { test }) => Observable.of(test))(Child)
  const wrapper = mount(<Tester test='hello world'/>)

  t.is(wrapper.text(), 'hello world')
})

test.cb('subscribes to state and updates children', t => {
  t.plan(2)

  const something = { type: 'DO_SOMETHING' }
  const reducer = (state = 'NOTHING', action) => {
    switch (action.type) {
      case 'DO_SOMETHING': return state + 'X'
      default: return state
    }
  }

  const dispatcher = createDispatcher()
  const Tester = connectStore(() => dispatcher.reduce(reducer))(Child)
  const wrapper = mount(<Tester/>)

  dispatcher
    .reduce(reducer)
    .take(2)
    .subscribe(x => {
      t.is(wrapper.text(), x)
    }, err => {
      t.fail()
    }, () => {
      t.end()
    })

  dispatcher.next(something)
  dispatcher.next(something)
})

test('recomputes selector-applied observables on changing props', t => {
  const data = { a: 'a', b: 'b' }
  const Tester = connectStore((_, {id}) => Observable.of(data[id]))(Child)
  const wrapper = mount(<Tester id='a'/>)

  t.is(wrapper.text(), 'a')
  wrapper.setProps({ id: 'b' })
  t.is(wrapper.text(), 'b')
})

<commit_msg>Fix connectStore test<commit_after>import test from 'ava'

import React, { Component } from 'react'
import { Observable } from '@reactivex/rxjs'
import { mount } from 'enzyme'

import connectStore from '../lib/decorators/connectStore'
import createDispatcher from '../lib/createDispatcher'

function Child({data}) {
  return
{data}

}

test('passes the correct static observable value', t => {
  const Tester = connectStore(Observable.of('test'))(Child)
  const wrapper = mount(<Tester/>)

  t.is(wrapper.text(), 'test')
})

test('passes selector-applied observable value based on props', t => {
  const Tester = connectStore((_, { test }) => Observable.of(test))(Child)
  const wrapper = mount(<Tester test='hello world'/>)

  t.is(wrapper.text(), 'hello world')
})

test.cb('subscribes to state and updates children', t => {
  t.plan(4)

  const something = Observable.of({ type: 'DO_SOMETHING' })
  const reducer = (state = 'NOTHING', action) => {
    switch (action.type) {
      case 'DO_SOMETHING': return state + 'X'
      default: return state
    }
  }

  const dispatcher = createDispatcher()
  const Tester = connectStore(() => dispatcher.reduce(reducer))(Child)
  const wrapper = mount(<Tester/>)

  dispatcher
    .reduce(reducer)
    .take(4)
    .subscribe(x => {
      t.is(wrapper.text(), x)
    }, err => {
      t.fail(err)
    }, () => {
      t.end()
    })

  dispatcher.next(something.concat(something))
  dispatcher.next(something.concat(something))
})

test('recomputes selector-applied observables on changing props', t => {
  const data = { a: 'a', b: 'b' }
  const Tester = connectStore((_, { id }) => Observable.of(data[id]))(Child)

  const wrapper = mount(<Tester id='a'/>)
  t.is(wrapper.text(), 'a')
  wrapper.setProps({ id: 'b' })
  t.is(wrapper.text(), 'b')
})

<|endoftext|>


<commit_before>'use strict';
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');
var fs = require('fs-extra');
var path = require('path');

module.exports = yeoman.generators.Base.extend({
  prompting: function () {
    var done = this.async();

    // Have Yeoman greet the user.
    this.log(yosay(
      'Welcome to the slick ' + chalk.red('SymfonyConsoleScaffolding') + ' generator!'
    ));

    var prompts = [{
      type: 'confirm',
      name: 'someOption',
      message: 'Would you like to enable this option?',
      default: true
    }];

    this.prompt(prompts, function (props) {
      this.props = props;
      // To access props later use this.props.someOption;

      done();
    }.bind(this));
  },

  writing: {
    app: function () {
      this.fs.copy(
        this.templatePath('_package.json'),
        this.destinationPath('package.json')
      );
      this.fs.copy(
        this.templatePath('_bower.json'),
        this.destinationPath('bower.json')
      );
    },

    projectfiles: function () {
      this.fs.copy(
        this.templatePath('editorconfig'),
        this.destinationPath('.editorconfig')
      );
      this.fs.copy(
        this.templatePath('jshintrc'),
        this.destinationPath('.jshintrc')
      );
    }
  },

  install: function () {
    this.installDependencies();
  }
});
<commit_msg>add change-case dep to used modules<commit_after>'use strict';
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');
var fs = require('fs-extra');
var path = require('path');
var cc = require('change-case');

module.exports = yeoman.generators.Base.extend({
  prompting: function () {
    var done = this.async();

    // Have Yeoman greet the user.
    this.log(yosay(
      'Welcome to the slick ' + chalk.red('SymfonyConsoleScaffolding') + ' generator!'
    ));

    var prompts = [{
      type: 'confirm',
      name: 'someOption',
      message: 'Would you like to enable this option?',
      default: true
    }];

    this.prompt(prompts, function (props) {
      this.props = props;
      // To access props later use this.props.someOption;

      done();
    }.bind(this));
  },

  writing: {
    app: function () {
      this.fs.copy(
        this.templatePath('_package.json'),
        this.destinationPath('package.json')
      );
      this.fs.copy(
        this.templatePath('_bower.json'),
        this.destinationPath('bower.json')
      );
    },

    projectfiles: function () {
      this.fs.copy(
        this.templatePath('editorconfig'),
        this.destinationPath('.editorconfig')
      );
      this.fs.copy(
        this.templatePath('jshintrc'),
        this.destinationPath('.jshintrc')
      );
    }
  },

  install: function () {
    this.installDependencies();
  }
});
<|endoftext|>


<commit_before>(function(angular){
    'use strict';

    var app = angular.module('ui.tinymce');

    // If you want to cutomize uiTinymceConfig for your theme, please copy this file to you theme in the
    // same path (static/js/). This are the default setting for timtec
    app.value('uiTinymceConfig', {
        base_url: '/static/tinymce-dist/',
        related_url: true,
        inline: false,
        menubar: false,
        relative_urls: false,
        plugins : 'advlist lists autolink link image media autoresize',
        toolbar: 'bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | quicklink link image media fullscreen',
        skin: 'lightgray',
        theme : 'modern',
        language: 'pt_BR',
        language_url : '/static/vendor/tinymce/langs/pt_BR.js',
        resize: true,
        elementpath: false,

        // media customizations
        media_poster: false,
        media_alt_source: false,
        media_dimensions: false,
        media_url_resolver: function (data, resolve/*, reject*/) {
            var complete_url = /^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
            var result = complete_url.exec(data.url);
            if (result && result[2].length == 11) {
                var youtube_id = result[2];
                var embedHtml = '';
                resolve({html: embedHtml});
            } else {
                resolve({html: ''});
            }
        },

        // Image upload
        // enable title field in the Image dialog
        image_title: false,
        image_description: false,
        image_dimensions: false,
        // enable automatic uploads of images represented by blob or data URIs
        automatic_uploads: true,
        // here we add custom filepicker only to Image dialog
        file_picker_types: 'image',
        // and here's our custom image picker
        file_picker_callback: function(cb, value, meta) {
            var input = document.createElement('input');
            input.setAttribute('type', 'file');
            input.setAttribute('accept', 'image/*');

            // Note: In modern browsers input[type="file"] is functional without
            // even adding it to the DOM, but that might not be the case in some older
            // or quirky browsers like IE, so you might want to add it to the DOM
            // just in case, and visually hide it. And do not forget do remove it
            // once you do not need it anymore.

            input.onchange = function() {
                var file = this.files[0];

                // Note: Now we need to register the blob in TinyMCEs image blob
                // registry. In the next release this part hopefully won't be
                // necessary, as we are looking to handle it internally.
                var id = 'blobid' + (new Date()).getTime();
                var blobCache = tinymce.activeEditor.editorUpload.blobCache;
                var blobInfo = blobCache.create(id, file);
                blobCache.add(blobInfo);

                // call the callback and populate the Title field with the file name
                cb(blobInfo.blobUri(), { title: file.name });
            };

            input.click();
          }
    });

})(window.angular);
<commit_msg>Improved compatibility with IE 11 for TinyMCE images upload (refs #324)<commit_after>(function(angular){
    'use strict';

    var app = angular.module('ui.tinymce');

    // If you want to cutomize uiTinymceConfig for your theme, please copy this file to you theme in the
    // same path (static/js/). This are the default setting for timtec
    app.value('uiTinymceConfig', {
        base_url: '/static/tinymce-dist/',
        related_url: true,
        inline: false,
        menubar: false,
        relative_urls: false,
        plugins : 'advlist lists autolink link image media autoresize',
        toolbar: 'bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | quicklink link image media fullscreen',
        skin: 'lightgray',
        theme : 'modern',
        language: 'pt_BR',
        language_url : '/static/vendor/tinymce/langs/pt_BR.js',
        resize: true,
        elementpath: false,

        // media customizations
        media_poster: false,
        media_alt_source: false,
        media_dimensions: false,
        media_url_resolver: function (data, resolve/*, reject*/) {
            var complete_url = /^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
            var result = complete_url.exec(data.url);
            if (result && result[2].length == 11) {
                var youtube_id = result[2];
                var embedHtml = '';
                resolve({html: embedHtml});
            } else {
                resolve({html: ''});
            }
        },

        // Image upload
        // enable title field in the Image dialog
        image_title: false,
        image_description: false,
        image_dimensions: false,
        // enable automatic uploads of images represented by blob or data URIs
        automatic_uploads: true,
        // here we add custom filepicker only to Image dialog
        file_picker_types: 'image',
        // and here's our custom image picker
        file_picker_callback: function(cb, value, meta) {
            var input = document.createElement('input');
            input.setAttribute('type', 'file');
            input.setAttribute('accept', 'image/*');

            // Note: In modern browsers input[type="file"] is functional without
            // even adding it to the DOM, but that might not be the case in some older
            // or quirky browsers like IE, so you might want to add it to the DOM
            // just in case, and visually hide it. And do not forget do remove it
            // once you do not need it anymore.
            document.body.appendChild(input);

            input.onchange = function() {
                var file = this.files[0];

                // Note: Now we need to register the blob in TinyMCEs image blob
                // registry. In the next release this part hopefully won't be
                // necessary, as we are looking to handle it internally.
                var id = 'blobid' + (new Date()).getTime();
                var blobCache = tinymce.activeEditor.editorUpload.blobCache;
                var blobInfo = blobCache.create(id, file);
                blobCache.add(blobInfo);

                // call the callback and populate the Title field with the file name
                cb(blobInfo.blobUri(), { title: file.name });
            };

            input.click();
          }
    });

})(window.angular);
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import _ from 'lodash';
import moment from 'moment';
import Mousetrap from 'mousetrap';
import cn from 'classnames';

import { Sigil } from '/components/lib/icons/sigil';

import { uuid, uxToHex, hexToRgba } from '/lib/util';

const DEFAULT_INPUT_HEIGHT = 28;

function getAdvance(a, b) {
  let res = '';
  if(!a) {
    return b;
  }
  for (let i = 0; i < Math.min(a.length, b.length); i++) {
    if (a[i] !== b[i]) {
      return res;
    }
    res = res.concat(a[i]);
  }
  return res;
}

function ChatInputSuggestion({ ship, contacts, selected, onSelect }) {
  let contact = contacts[ship];
  let color = "#000000";
  let sigilClass = "v-mid mix-blend-diff"
  let nickname;
  let nameStyle = {};
  const isSelected = ship === selected;
  if (contact) {
    const hex = uxToHex(contact.color);
    color = `#${hex}`;
    nameStyle.color = hexToRgba(hex, .7);
    nameStyle.textShadow = '0px 0px 0px #000';
    nameStyle.filter = 'contrast(1.3) saturate(1.5)';
    sigilClass = "v-mid";
    nickname = contact.nickname;
  }

  return (

 onSelect(ship)}
      className={cn(
        'f8 pv1 ph3 pointer hover-bg-gray1-d hover-bg-gray4 relative flex items-center',
        {
          'white-d bg-gray0-d bg-white': !isSelected,
          'black-d bg-gray1-d bg-gray4': isSelected,
        }
      )}
      key={ship}
    >
      <Sigil
        ship={'~' + ship}
        size={24}
        color={color}
        classes={sigilClass}
      />
      { nickname && (

{nickname}
)
      }

        {'~' + ship}

        {status}

  );

}

function ChatInputSuggestions({ suggestions, onSelect, selected, contacts }) {
  return (

      {suggestions.map(ship =>
        (<ChatInputSuggestion
           onSelect={onSelect}
           key={ship}
           selected={selected}
           contacts={contacts}
           ship={ship} />)
      )}

  );
}

export class ChatInput extends Component {
  constructor(props) {
    super(props);

    this.state = {
      message: '',
      textareaHeight: DEFAULT_INPUT_HEIGHT,
      patpSuggestions: [],
      selectedSuggestion: null
    };

    this.textareaRef = React.createRef();

    this.messageSubmit = this.messageSubmit.bind(this);
    this.messageChange = this.messageChange.bind(this);

    this.onEnter = this.onEnter.bind(this);

    this.patpAutocomplete = this.patpAutocomplete.bind(this);
    this.nextAutocompleteSuggestion = this.nextAutocompleteSuggestion.bind(this);
    this.completePatp = this.completePatp.bind(this);

    this.clearSuggestions = this.clearSuggestions.bind(this);

    // Call once per frame @ 60hz
    this.textareaInput = _.debounce(this.textareaInput.bind(this), 16);

    // perf testing:
    /*let closure = () => {
      let x = 0;
      for (var i = 0; i < 30; i++) {
        x++;
        props.api.chat.message(
          props.station,
          `~${window.ship}`,
          Date.now(),
          {
            text: `${x}`
          }
        );
      }
      setTimeout(closure, 1000);
    };
    this.closure = closure.bind(this);*/

    moment.updateLocale('en', {
        relativeTime : {
            past: function(input) {
              return input === 'just now'
                ? input
                : input + ' ago'
            },
            s  : 'just now',
            future: "in %s",
            ss : '%d sec',
            m:  "a minute",
            mm: "%d min",
            h:  "an hr",
            hh: "%d hrs",
            d:  "a day",
            dd: "%d days",
            M:  "a month",
            MM: "%d months",
            y:  "a year",
            yy: "%d years"
        }
    });
  }

  componentDidMount() {
    this.bindShortcuts();
  }

  nextAutocompleteSuggestion(backward = false) {
    const { patpSuggestions } = this.state;
    let idx = patpSuggestions.findIndex(s => s === this.state.selectedSuggestion);

    idx = backward ? idx - 1 : idx + 1;
    idx = idx % patpSuggestions.length;
    if(idx < 0) {
      idx = patpSuggestions.length - 1;
    }

    this.setState({ selectedSuggestion: patpSuggestions[idx] });
  }

  patpAutocomplete(message, fresh = false) {
    const match = /~([a-zA-Z\-]*)$/.exec(message);

    if (!match ) {
      this.setState({ patpSuggestions: [] })
      return;
    }

    const needle = match[1].toLowerCase();

    const matchString = hay => {
      hay = hay.toLowerCase();

      return hay.startsWith(needle)
        || _.some(_.words(hay), s => s.startsWith(needle));
    };

    const contacts = _.chain(this.props.contacts)
      .defaultTo({})
      .map((details, ship) => ({...details, ship }))
      .filter(({ nickname, ship }) => matchString(nickname) || matchString(ship))
      .map('ship')
      .value()

    const suggestions = _.chain(this.props.envelopes)
      .defaultTo([])
      .map("author")
      .uniq()
      .reverse()
      .filter(matchString)
      .union(contacts)
      .filter(s => s.length < 28) // exclude comets
      .take(5)
      .value();

    let newState = {
      patpSuggestions: suggestions,
      selectedSuggestion: suggestions[0]
    };

    this.setState(newState);
  }

  clearSuggestions() {
    this.setState({
      patpSuggestions: []
    })
  }

  completePatp(suggestion) {
    this.setState({
      message: this.state.message.replace(
        /[a-zA-Z\-]*$/,
        suggestion
      ),
      patpSuggestions: []
    });
  }

  onEnter(e) {
    if (this.state.patpSuggestions.length !== 0) {
      this.completePatp(this.state.selectedSuggestion);
    } else {
      this.messageSubmit(e);
    }
  }

  bindShortcuts() {
    let mousetrap = Mousetrap(this.textareaRef.current);
    mousetrap.bind('enter', e => {
      e.preventDefault();
      e.stopPropagation();

      this.onEnter(e);
    });

    mousetrap.bind('tab', e => {
      e.preventDefault();
      e.stopPropagation();
      if(this.state.patpSuggestions.length === 0) {
        this.patpAutocomplete(this.state.message, true);
      } else {
        this.nextAutocompleteSuggestion(false);
      }
    });
    mousetrap.bind(['up', 'shift+tab'], e => {
      if(this.state.patpSuggestions.length !== 0) {
        e.preventDefault();
        e.stopPropagation();
        this.nextAutocompleteSuggestion(true)
      }

    });
    mousetrap.bind('down', e => {
      if(this.state.patpSuggestions.length !== 0) {
        e.preventDefault();
        e.stopPropagation();
        this.nextAutocompleteSuggestion(false)
      }
    });
    mousetrap.bind('esc', e => {
      if(this.state.patpSuggestions.length !== 0) {
        e.preventDefault();
        e.stopPropagation();
        this.clearSuggestions();
      }})
  }

  messageChange(event) {
    const message = event.target.value;
    this.setState({
      message
    });

    const { patpSuggestions } = this.state;
    if(patpSuggestions.length !== 0) {
      this.patpAutocomplete(message, false);
    }

  }

  textareaInput() {
    const newHeight = this.textareaRef.current.scrollHeight < DEFAULT_INPUT_HEIGHT * 8
      ? `${this.textareaRef.current.scrollHeight}px`
      : `${DEFAULT_INPUT_HEIGHT * 8}px`

    this.setState({
      textareaHeight: newHeight
    });
  }

  getLetterType(letter) {
    if (letter[0] === '#') {
      letter = letter.slice(1);
      // remove insignificant leading whitespace.
      // aces might be relevant to style.
      while (letter[0] === '\n') {
        letter = letter.slice(1);
      }

      return {
        code: {
          expression: letter,
          output: undefined
        }
      }
    } else if (letter[0] === '@') {
      letter = letter.slice(1);
      // remove insignificant leading whitespace.
      // aces might be relevant to style.
      while (letter[0] === '\n') {
        letter = letter.slice(1);
      }

      return {
        me: letter
      }
    } else if (this.isUrl(letter)) {
       return {
        url: letter
      }
    } else {
      return {
        text: letter
      }
    }
  }

  isUrl(string) {
    try {
      let websiteTest = new RegExp(''
      + /((\w+:\/\/)[-a-zA-Z0-9:@;?&=\/%\+\.\*!'\(\),\$_\{\}\^~\[\]`#|]+)/.source
      );
      return websiteTest.test(string);
    } catch (e) {
      return false;
    }
  }

  messageSubmit() {
    const { props, state } = this;

    if (state.message === '') {
      return;
    }

    let message = [];
    state.message.split(" ").map((each) => {
      if (this.isUrl(each)) {
        if (message.length > 0) {
          message = message.join(" ");
          message = this.getLetterType(message);
          props.api.chat.message(
            props.station,
            `~${window.ship}`,
            Date.now(),
            message
          );
          message = [];
        }
        let URL = this.getLetterType(each);
        props.api.chat.message(
          props.station,
          `~${window.ship}`,
          Date.now(),
          URL
        );
      }
      else {
        return message.push(each);
      }
    })

    if (message.length > 0) {
      message = message.join(" ");
      message = this.getLetterType(message);
      props.api.chat.message(
        props.station,
        `~${window.ship}`,
        Date.now(),
        message
      );
      message = [];
    }

    // perf:
    //setTimeout(this.closure, 2000);

    this.setState({
      message: '',
      textareaHeight: DEFAULT_INPUT_HEIGHT
    });
  }

  render() {
    const { props, state } = this;

    let color = !!props.ownerContact
      ? uxToHex(props.ownerContact.color) : '000000';

    let sigilClass = !!props.ownerContact
      ? "" : "mix-blend-diff";

    return (

        {state.patpSuggestions.length !== 0 && (
          <ChatInputSuggestions
            onSelect={this.completePatp}
            suggestions={state.patpSuggestions}
            selected={state.selectedSuggestion}
            contacts={props.contacts}
          />
        )}

          <Sigil
            ship={window.ship}
            size={24}
            color={`#${color}`}
            classes={sigilClass}
            />

          <textarea
            className={"pl3 bn bg-gray0-d white-d"}
            style={{ flexGrow: 1, height: state.textareaHeight, paddingTop: 6, resize: "none" }}
            autoCapitalize="none"
            autoFocus={(
              /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(
              navigator.userAgent
            )) ? false : true}
            ref={this.textareaRef}
            placeholder={props.placeholder}
            value={state.message}
            onChange={this.messageChange}
            onInput={this.textareaInput}
          />

    );
  }
}
<commit_msg>chat-js: adjust line height in chat input<commit_after>import React, { Component } from 'react';
import _ from 'lodash';
import moment from 'moment';
import Mousetrap from 'mousetrap';
import cn from 'classnames';

import { Sigil } from '/components/lib/icons/sigil';

import { uuid, uxToHex, hexToRgba } from '/lib/util';

// line height
const INPUT_LINE_HEIGHT = 28;

const INPUT_TOP_PADDING = 3;

function getAdvance(a, b) {
  let res = '';
  if(!a) {
    return b;
  }
  for (let i = 0; i < Math.min(a.length, b.length); i++) {
    if (a[i] !== b[i]) {
      return res;
    }
    res = res.concat(a[i]);
  }
  return res;
}

function ChatInputSuggestion({ ship, contacts, selected, onSelect }) {
  let contact = contacts[ship];
  let color = "#000000";
  let sigilClass = "v-mid mix-blend-diff"
  let nickname;
  let nameStyle = {};
  const isSelected = ship === selected;
  if (contact) {
    const hex = uxToHex(contact.color);
    color = `#${hex}`;
    nameStyle.color = hexToRgba(hex, .7);
    nameStyle.textShadow = '0px 0px 0px #000';
    nameStyle.filter = 'contrast(1.3) saturate(1.5)';
    sigilClass = "v-mid";
    nickname = contact.nickname;
  }

  return (

 onSelect(ship)}
      className={cn(
        'f8 pv1 ph3 pointer hover-bg-gray1-d hover-bg-gray4 relative flex items-center',
        {
          'white-d bg-gray0-d bg-white': !isSelected,
          'black-d bg-gray1-d bg-gray4': isSelected,
        }
      )}
      key={ship}
    >
      <Sigil
        ship={'~' + ship}
        size={24}
        color={color}
        classes={sigilClass}
      />
      { nickname && (

{nickname}
)
      }

        {'~' + ship}

        {status}

  );

}

function ChatInputSuggestions({ suggestions, onSelect, selected, contacts }) {
  return (

      {suggestions.map(ship =>
        (<ChatInputSuggestion
           onSelect={onSelect}
           key={ship}
           selected={selected}
           contacts={contacts}
           ship={ship} />)
      )}

  );
}

export class ChatInput extends Component {
  constructor(props) {
    super(props);

    this.state = {
      message: '',
      textareaHeight: INPUT_LINE_HEIGHT + INPUT_TOP_PADDING + 1,
      patpSuggestions: [],
      selectedSuggestion: null
    };

    this.textareaRef = React.createRef();

    this.messageSubmit = this.messageSubmit.bind(this);
    this.messageChange = this.messageChange.bind(this);

    this.onEnter = this.onEnter.bind(this);

    this.patpAutocomplete = this.patpAutocomplete.bind(this);
    this.nextAutocompleteSuggestion = this.nextAutocompleteSuggestion.bind(this);
    this.completePatp = this.completePatp.bind(this);

    this.clearSuggestions = this.clearSuggestions.bind(this);

    // Call once per frame @ 60hz
    this.textareaInput = _.debounce(this.textareaInput.bind(this), 16);

    // perf testing:
    /*let closure = () => {
      let x = 0;
      for (var i = 0; i < 30; i++) {
        x++;
        props.api.chat.message(
          props.station,
          `~${window.ship}`,
          Date.now(),
          {
            text: `${x}`
          }
        );
      }
      setTimeout(closure, 1000);
    };
    this.closure = closure.bind(this);*/

    moment.updateLocale('en', {
        relativeTime : {
            past: function(input) {
              return input === 'just now'
                ? input
                : input + ' ago'
            },
            s  : 'just now',
            future: "in %s",
            ss : '%d sec',
            m:  "a minute",
            mm: "%d min",
            h:  "an hr",
            hh: "%d hrs",
            d:  "a day",
            dd: "%d days",
            M:  "a month",
            MM: "%d months",
            y:  "a year",
            yy: "%d years"
        }
    });
  }

  componentDidMount() {
    this.bindShortcuts();
  }

  nextAutocompleteSuggestion(backward = false) {
    const { patpSuggestions } = this.state;
    let idx = patpSuggestions.findIndex(s => s === this.state.selectedSuggestion);

    idx = backward ? idx - 1 : idx + 1;
    idx = idx % patpSuggestions.length;
    if(idx < 0) {
      idx = patpSuggestions.length - 1;
    }

    this.setState({ selectedSuggestion: patpSuggestions[idx] });
  }

  patpAutocomplete(message, fresh = false) {
    const match = /~([a-zA-Z\-]*)$/.exec(message);

    if (!match ) {
      this.setState({ patpSuggestions: [] })
      return;
    }

    const needle = match[1].toLowerCase();

    const matchString = hay => {
      hay = hay.toLowerCase();

      return hay.startsWith(needle)
        || _.some(_.words(hay), s => s.startsWith(needle));
    };

    const contacts = _.chain(this.props.contacts)
      .defaultTo({})
      .map((details, ship) => ({...details, ship }))
      .filter(({ nickname, ship }) => matchString(nickname) || matchString(ship))
      .map('ship')
      .value()

    const suggestions = _.chain(this.props.envelopes)
      .defaultTo([])
      .map("author")
      .uniq()
      .reverse()
      .filter(matchString)
      .union(contacts)
      .filter(s => s.length < 28) // exclude comets
      .take(5)
      .value();

    let newState = {
      patpSuggestions: suggestions,
      selectedSuggestion: suggestions[0]
    };

    this.setState(newState);
  }

  clearSuggestions() {
    this.setState({
      patpSuggestions: []
    })
  }

  completePatp(suggestion) {
    this.setState({
      message: this.state.message.replace(
        /[a-zA-Z\-]*$/,
        suggestion
      ),
      patpSuggestions: []
    });
  }

  onEnter(e) {
    if (this.state.patpSuggestions.length !== 0) {
      this.completePatp(this.state.selectedSuggestion);
    } else {
      this.messageSubmit(e);
    }
  }

  bindShortcuts() {
    let mousetrap = Mousetrap(this.textareaRef.current);
    mousetrap.bind('enter', e => {
      e.preventDefault();
      e.stopPropagation();

      this.onEnter(e);
    });

    mousetrap.bind('tab', e => {
      e.preventDefault();
      e.stopPropagation();
      if(this.state.patpSuggestions.length === 0) {
        this.patpAutocomplete(this.state.message, true);
      } else {
        this.nextAutocompleteSuggestion(false);
      }
    });
    mousetrap.bind(['up', 'shift+tab'], e => {
      if(this.state.patpSuggestions.length !== 0) {
        e.preventDefault();
        e.stopPropagation();
        this.nextAutocompleteSuggestion(true)
      }

    });
    mousetrap.bind('down', e => {
      if(this.state.patpSuggestions.length !== 0) {
        e.preventDefault();
        e.stopPropagation();
        this.nextAutocompleteSuggestion(false)
      }
    });
    mousetrap.bind('esc', e => {
      if(this.state.patpSuggestions.length !== 0) {
        e.preventDefault();
        e.stopPropagation();
        this.clearSuggestions();
      }})
  }

  messageChange(event) {
    const message = event.target.value;
    this.setState({
      message
    });

    const { patpSuggestions } = this.state;
    if(patpSuggestions.length !== 0) {
      this.patpAutocomplete(message, false);
    }

  }

  textareaInput() {
    const maxHeight = INPUT_LINE_HEIGHT * 8 + INPUT_TOP_PADDING;
    const newHeight = `${Math.min(maxHeight, this.textareaRef.current.scrollHeight)}px`;

    this.setState({
      textareaHeight: newHeight
    });
  }

  getLetterType(letter) {
    if (letter[0] === '#') {
      letter = letter.slice(1);
      // remove insignificant leading whitespace.
      // aces might be relevant to style.
      while (letter[0] === '\n') {
        letter = letter.slice(1);
      }

      return {
        code: {
          expression: letter,
          output: undefined
        }
      }
    } else if (letter[0] === '@') {
      letter = letter.slice(1);
      // remove insignificant leading whitespace.
      // aces might be relevant to style.
      while (letter[0] === '\n') {
        letter = letter.slice(1);
      }

      return {
        me: letter
      }
    } else if (this.isUrl(letter)) {
       return {
        url: letter
      }
    } else {
      return {
        text: letter
      }
    }
  }

  isUrl(string) {
    try {
      let websiteTest = new RegExp(''
      + /((\w+:\/\/)[-a-zA-Z0-9:@;?&=\/%\+\.\*!'\(\),\$_\{\}\^~\[\]`#|]+)/.source
      );
      return websiteTest.test(string);
    } catch (e) {
      return false;
    }
  }

  messageSubmit() {
    const { props, state } = this;

    if (state.message === '') {
      return;
    }

    let message = [];
    state.message.split(" ").map((each) => {
      if (this.isUrl(each)) {
        if (message.length > 0) {
          message = message.join(" ");
          message = this.getLetterType(message);
          props.api.chat.message(
            props.station,
            `~${window.ship}`,
            Date.now(),
            message
          );
          message = [];
        }
        let URL = this.getLetterType(each);
        props.api.chat.message(
          props.station,
          `~${window.ship}`,
          Date.now(),
          URL
        );
      }
      else {
        return message.push(each);
      }
    })

    if (message.length > 0) {
      message = message.join(" ");
      message = this.getLetterType(message);
      props.api.chat.message(
        props.station,
        `~${window.ship}`,
        Date.now(),
        message
      );
      message = [];
    }

    // perf:
    //setTimeout(this.closure, 2000);

    this.setState({
      message: '',
      textareaHeight: INPUT_LINE_HEIGHT + INPUT_TOP_PADDING + 1
    });
  }

  render() {
    const { props, state } = this;

    let color = !!props.ownerContact
      ? uxToHex(props.ownerContact.color) : '000000';

    let sigilClass = !!props.ownerContact
      ? "" : "mix-blend-diff";

    return (

        {state.patpSuggestions.length !== 0 && (
          <ChatInputSuggestions
            onSelect={this.completePatp}
            suggestions={state.patpSuggestions}
            selected={state.selectedSuggestion}
            contacts={props.contacts}
          />
        )}

          <Sigil
            ship={window.ship}
            size={24}
            color={`#${color}`}
            classes={sigilClass}
            />

          <textarea
            className={"pl3 bn bg-gray0-d white-d lh-copy"}
            style={{ flexGrow: 1, height: state.textareaHeight, paddingTop: INPUT_TOP_PADDING, resize: "none" }}
            autoCapitalize="none"
            autoFocus={(
              /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(
              navigator.userAgent
            )) ? false : true}
            ref={this.textareaRef}
            placeholder={props.placeholder}
            value={state.message}
            onChange={this.messageChange}
            onInput={this.textareaInput}
          />

    );
  }
}
<|endoftext|>


<commit_before>'use strict';

describe('Controller: SignupCtrl', function () {

  // load the controller's module
  beforeEach(module('badgerApp'));

  var SignupCtrl, scope;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    SignupCtrl = $controller('SignupCtrl', {
      $scope: scope
    });
  }));

  it('should default to account type client', function () {
    expect($scope.user.accountType).toEqual('Client');
  });

  it('should display an error if email is left blank', function () {
    $scope.register();
    expect($('.help-block')).toEqual(true);
  });

});
<commit_msg>(#58) Fix issue where  wans't passed into signup.conroller.spec.<commit_after>'use strict';

describe('Controller: SignupCtrl', function () {

  // load the controller's module
  beforeEach(module('badgerApp'));

  var SignupCtrl, scope;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope, $scope) {
    scope = $rootScope.$new();
    SignupCtrl = $controller('SignupCtrl', {
      $scope: scope
    });
  }));

  it('should default to account type client', function ($scope) {
    expect($scope.user.accountType).toEqual('Client');
  });

  it('should display an error if email is left blank', function ($scope) {
    $scope.register();
    expect($('.help-block')).toEqual(true);
  });

});
<|endoftext|>


<commit_before>import CategoriesModule from './categories';
import CategoriesController from './categories.controller';
import CategoriesComponent from './categories.component';
import CategoriesTemplate from './categories.html';

describe('Categories', () => {
  let component, $componentController, CategoriesModel;

  beforeEach(() => {
    window.module('categories');

    window.module(($provide) => {
      $provide.value('CategoriesModel', {
        getCategories: () => {
          return {
            then: () => {}
          };
        }
      });
    });
  });

  beforeEach(inject((_$componentController_, _CategoriesModel_) => {
    CategoriesModel = _CategoriesModel_;
    $componentController = _$componentController_;
  }));

  describe('Module', () => {
    it('is named correctly', () => {
      expect(CategoriesModule.name).toEqual('categories');
    });
  });

  describe('Controller', () => {
    it('calls CategoriesModel.getCategories immediately', () => {
      spyOn(CategoriesModel, 'getCategories').and.callThrough();

      component = $componentController('categories', {
        CategoriesModel: CategoriesModel
      });
      component.$onInit();

      expect(CategoriesModel.getCategories).toHaveBeenCalled();
    });
  });

  describe('Template', () => {
    it('includes the `category-item` directive', () => {
      expect(CategoriesTemplate).toContain('category-item');
    });
  });

  describe('Component', () => {
    const component = CategoriesComponent;

    it('includes the intended template',() => {
      expect(component.template).toEqual(CategoriesTemplate);
    });

    it('uses the correct `controllerAs` label', () => {
      expect(component.controllerAs).toBe('categoriesListCtrl');
    });

    it('invokes the right controller', () => {
      expect(component.controller).toEqual(CategoriesController);
    });
  });
});
<commit_msg>cleaning up tests<commit_after>import CategoriesModule from './categories';
import CategoriesController from './categories.controller';
import CategoriesComponent from './categories.component';
import CategoriesTemplate from './categories.html';

describe('Categories', () => {
  let component, $componentController, CategoriesModel;

  beforeEach(() => {
    window.module('categories');

    window.module($provide => {
      $provide.value('CategoriesModel', {
        getCategories: () => {
          return {
            then: () => {}
          };
        }
      });
    });
  });

  beforeEach(inject((_$componentController_, _CategoriesModel_) => {
    CategoriesModel = _CategoriesModel_;
    $componentController = _$componentController_;
  }));

  describe('Module', () => {
    it('is named correctly', () => {
      expect(CategoriesModule.name).toEqual('categories');
    });
  });

  describe('Controller', () => {
    it('calls CategoriesModel.getCategories immediately', () => {
      spyOn(CategoriesModel, 'getCategories').and.callThrough();

      component = $componentController('categories', {
        CategoriesModel
      });
      component.$onInit();

      expect(CategoriesModel.getCategories).toHaveBeenCalled();
    });
  });

  describe('Template', () => {
    it('includes the `category-item` directive', () => {
      expect(CategoriesTemplate).toContain('category-item');
    });
  });

  describe('Component', () => {
    const component = CategoriesComponent;

    it('includes the intended template',() => {
      expect(component.template).toEqual(CategoriesTemplate);
    });

    it('uses the correct `controllerAs` label', () => {
      expect(component.controllerAs).toBe('categoriesListCtrl');
    });

    it('invokes the right controller', () => {
      expect(component.controller).toEqual(CategoriesController);
    });
  });
});
<|endoftext|>


<commit_before>/**
 * @license Copyright 2019 Google Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 */
'use strict';

const path = require('path');

/** @typedef {(browser: import('puppeteer').Browser, context: {url: string, options: LHCI.CollectCommand.Options}) => void} PuppeteerScript */

class PuppeteerManager {
  /** @param {LHCI.CollectCommand.Options} options */
  constructor(options) {
    this._options = options;

    /** @type {null|import('puppeteer').Browser} */
    this._browser = null;
  }

  /** @return {Promise<import('puppeteer').Browser>} */
  async _getBrowser() {
    if (!this.isActive()) throw new Error('Should not launch a browser when inactive');
    if (this._browser) return this._browser;

    // Delay require to only run after user requests puppeteer functionality.
    const puppeteer = require('puppeteer');
    this._browser = await puppeteer.launch({
      pipe: false,
      executablePath: this._options.chromePath,
    });

    return this._browser;
  }

  /** @return {boolean} */
  isActive() {
    return !!this._options.puppeteerScript;
  }

  /** @return {Promise<number>} */
  async getBrowserPort() {
    const browser = await this._getBrowser();
    return Number(new URL(browser.wsEndpoint()).port);
  }

  /**
   * @param {string} url
   * @return {Promise<void>}
   */
  async invokePuppeteerScriptForUrl(url) {
    const scriptPath = this._options.puppeteerScript;
    if (!scriptPath) return;

    const browser = await this._getBrowser();
    /** @type {PuppeteerScript} */
    const script = require(path.join(process.cwd(), scriptPath));
    await script(browser, {url, options: this._options});
  }
}

module.exports = PuppeteerManager;
<commit_msg>fix(cli): puppeteer script respects headful flag<commit_after>/**
 * @license Copyright 2019 Google Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 */
'use strict';

const path = require('path');

/** @typedef {(browser: import('puppeteer').Browser, context: {url: string, options: LHCI.CollectCommand.Options}) => void} PuppeteerScript */

class PuppeteerManager {
  /** @param {LHCI.CollectCommand.Options} options */
  constructor(options) {
    this._options = options;

    /** @type {null|import('puppeteer').Browser} */
    this._browser = null;
  }

  /** @return {Promise<import('puppeteer').Browser>} */
  async _getBrowser() {
    if (!this.isActive()) throw new Error('Should not launch a browser when inactive');
    if (this._browser) return this._browser;

    // Delay require to only run after user requests puppeteer functionality.
    const puppeteer = require('puppeteer');
    this._browser = await puppeteer.launch({
      pipe: false,
      headless: !this._options.headful,
      executablePath: this._options.chromePath,
    });

    return this._browser;
  }

  /** @return {boolean} */
  isActive() {
    return !!this._options.puppeteerScript;
  }

  /** @return {Promise<number>} */
  async getBrowserPort() {
    const browser = await this._getBrowser();
    return Number(new URL(browser.wsEndpoint()).port);
  }

  /**
   * @param {string} url
   * @return {Promise<void>}
   */
  async invokePuppeteerScriptForUrl(url) {
    const scriptPath = this._options.puppeteerScript;
    if (!scriptPath) return;

    const browser = await this._getBrowser();
    /** @type {PuppeteerScript} */
    const script = require(path.join(process.cwd(), scriptPath));
    await script(browser, {url, options: this._options});
  }
}

module.exports = PuppeteerManager;
<|endoftext|>


<commit_before>'use strict';

// plays a sound
angular.module('meanRecipieApp')
  .directive('audiocard', function ($document) {
    return {
      restrict: 'E',
      scope: {
      	message: "=message",
      	carddata: "=",
      	behaviour: "="
      },
      template:
      	'
 ' +
      		'
{{message}}
' +
      		'' +
      		'
✓
' +
      		'
✘
' +
      	'
',
      replace: true,

      link: function postLink(scope, element, attrs) {

      	var hideMarker = function() {
      		$('#feedbackMarkerSuccess').hide();
      		$('#feedbackMarkerError').hide();
      	};

      	var displayMarker = function(result) {
      		if (result) {
      			$('#feedbackMarkerSuccess').show();
      		} else {
      			$('#feedbackMarkerError').show();
      		}
      	};

      	var audioElement = $document[0].createElement('audio');

      	scope.replayAudio = function() {
      		audioElement.play();
      	};

      	hideMarker();

      	scope.$watch('carddata', function(data) {
      		if(data && data.audio) {
      			scope.carddata = data;
      			scope.message = 'Enter the word exactly as you just heard';
      			audioElement.src = data.audio;
      			audioElement.play();
      		}
      	});

      	scope.$watch('behaviour', function(data) {
      		if (data && data.flipCard) {
      			scope.message = 'Answer is:' + scope.carddata.translated;
      			displayMarker(data.isAnswerCorrect);
      		} else {
      			hideMarker();
      		}
      	});

      }
    };
  });
<commit_msg>comment and test git conflict from cmd line<commit_after>'use strict';

// plays a sound for this card and allow replay
angular.module('meanRecipieApp')
  .directive('audiocard', function ($document) {
    return {
      restrict: 'E',
      scope: {
      	message: "=message",
      	carddata: "=",
      	behaviour: "="
      },
      template:
      	'
 ' +
      		'
{{message}}
' +
      		'' +
      		'
✓
' +
      		'
✘
' +
      	'
',
      replace: true,

      link: function postLink(scope, element, attrs) {

      	var hideMarker = function() {
      		$('#feedbackMarkerSuccess').hide();
      		$('#feedbackMarkerError').hide();
      	};

      	var displayMarker = function(result) {
      		if (result) {
      			$('#feedbackMarkerSuccess').show();
      		} else {
      			$('#feedbackMarkerError').show();
      		}
      	};

      	var audioElement = $document[0].createElement('audio');

      	scope.replayAudio = function() {
      		audioElement.play();
      	};

      	hideMarker();

      	scope.$watch('carddata', function(data) {
      		if(data && data.audio) {
      			scope.carddata = data;
      			scope.message = 'Enter the word exactly as you just heard';
      			audioElement.src = data.audio;
      			audioElement.play();
      		}
      	});

      	scope.$watch('behaviour', function(data) {
      		if (data && data.flipCard) {
      			scope.message = 'Answer is:' + scope.carddata.translated;
      			displayMarker(data.isAnswerCorrect);
      		} else {
      			hideMarker();
      		}
      	});

      }
    };
  });
<|endoftext|>