<commit_before>var path = require('path');
var fs = require('graceful-fs');
var crypto = require('crypto');
var mm = require('minimatch');

var log = require('./logger').create('preprocess');

var sha1 = function(data) {
  var hash = crypto.createHash('sha1');
  hash.update(data);
  return hash.digest('hex');
};

var isBinary = Object.create(null);
[
  'adp', 'au', 'mid', 'mp4a', 'mpga', 'oga', 's3m', 'sil', 'eol', 'dra', 'dts', 'dtshd', 'lvp',
  'pya', 'ecelp4800', 'ecelp7470', 'ecelp9600', 'rip', 'weba', 'aac', 'aif', 'caf', 'flac', 'mka',
  'm3u', 'wax', 'wma', 'wav', 'xm', 'flac', '3gp', '3g2', 'h261', 'h263', 'h264', 'jpgv', 'jpm',
  'mj2', 'mp4', 'mpeg', 'ogv', 'qt', 'uvh', 'uvm', 'uvp', 'uvs', 'dvb', 'fvt', 'mxu', 'pyv', 'uvu',
  'viv', 'webm', 'f4v', 'fli', 'flv', 'm4v', 'mkv', 'mng', 'asf', 'vob', 'wm', 'wmv', 'wmx', 'wvx',
  'movie', 'smv', 'ts', 'bmp', 'cgm', 'g3', 'gif', 'ief', 'jpg', 'jpeg', 'ktx', 'png', 'btif',
  'sgi', 'svg', 'tiff', 'psd', 'uvi', 'sub', 'djvu', 'dwg', 'dxf', 'fbs', 'fpx', 'fst', 'mmr',
  'rlc', 'mdi', 'wdp', 'npx', 'wbmp', 'xif', 'webp', '3ds', 'ras', 'cmx', 'fh', 'ico', 'pcx', 'pic',
  'pnm', 'pbm', 'pgm', 'ppm', 'rgb', 'tga', 'xbm', 'xpm', 'xwd', 'zip', 'rar', 'tar', 'bz2', 'eot',
  'ttf', 'woff', 'dat'
].forEach(function(extension) {
  isBinary['.' + extension] = true;
});

// TODO(vojta): instantiate preprocessors at the start to show warnings immediately
var createPreprocessor = function(config, basePath, injector) {
  var patterns = Object.keys(config);
  var alreadyDisplayedWarnings = Object.create(null);

  return function(file, done) {
    var thisFileIsBinary = isBinary[path.extname(file.originalPath)];
    var preprocessors = [];
    var nextPreprocessor = function(error, content) {
      // normalize B-C
      if (arguments.length === 1 && typeof error === 'string') {
        content = error;
        error = null;
      }

      if (error) {
        file.content = null;
        file.contentPath = null;
        return done(error);
      }

      if (!preprocessors.length) {
        file.contentPath = null;
        file.content = content;
        return done();
      }

      preprocessors.shift()(content, file, nextPreprocessor);
    };
    var instantiatePreprocessor = function(name) {
      if (alreadyDisplayedWarnings[name]) {
        return;
      }

      try {
        preprocessors.push(injector.get('preprocessor:' + name));
      } catch (e) {
        if (e.message.indexOf('No provider for "preprocessor:' + name + '"') !== -1) {
          log.warn('Can not load "%s", it is not registered!\n  ' +
                   'Perhaps you are missing some plugin?', name);
        } else {
          log.warn('Can not load "%s"!\n  ' + e.stack, name);
        }

        alreadyDisplayedWarnings[name] = true;
      }
    };

    // collects matching preprocessors
    // TODO(vojta): should we cache this ?
    for (var i = 0; i < patterns.length; i++) {
      if (mm(file.originalPath, patterns[i])) {
        if (thisFileIsBinary) {
          log.warn('Ignoring preprocessing (%s) %s because it is a binary file.',
              config[patterns[i]].join(', '), file.originalPath);
        } else {
          config[patterns[i]].forEach(instantiatePreprocessor);
        }
      }
    }

    return fs.readFile(file.originalPath, function(err, buffer) {
      file.sha = sha1(buffer);
      nextPreprocessor(null, thisFileIsBinary ? buffer : buffer.toString());
    });
  };
};
createPreprocessor.$inject = ['config.preprocessors', 'config.basePath', 'injector'];

exports.createPreprocessor = createPreprocessor;
<commit_msg>fix(preprocessor): consider SVG files as text files, not binary files<commit_after>var path = require('path');
var fs = require('graceful-fs');
var crypto = require('crypto');
var mm = require('minimatch');

var log = require('./logger').create('preprocess');

var sha1 = function(data) {
  var hash = crypto.createHash('sha1');
  hash.update(data);
  return hash.digest('hex');
};

var isBinary = Object.create(null);
[
  'adp', 'au', 'mid', 'mp4a', 'mpga', 'oga', 's3m', 'sil', 'eol', 'dra', 'dts', 'dtshd', 'lvp',
  'pya', 'ecelp4800', 'ecelp7470', 'ecelp9600', 'rip', 'weba', 'aac', 'aif', 'caf', 'flac', 'mka',
  'm3u', 'wax', 'wma', 'wav', 'xm', 'flac', '3gp', '3g2', 'h261', 'h263', 'h264', 'jpgv', 'jpm',
  'mj2', 'mp4', 'mpeg', 'ogv', 'qt', 'uvh', 'uvm', 'uvp', 'uvs', 'dvb', 'fvt', 'mxu', 'pyv', 'uvu',
  'viv', 'webm', 'f4v', 'fli', 'flv', 'm4v', 'mkv', 'mng', 'asf', 'vob', 'wm', 'wmv', 'wmx', 'wvx',
  'movie', 'smv', 'ts', 'bmp', 'cgm', 'g3', 'gif', 'ief', 'jpg', 'jpeg', 'ktx', 'png', 'btif',
  'sgi', 'tiff', 'psd', 'uvi', 'sub', 'djvu', 'dwg', 'dxf', 'fbs', 'fpx', 'fst', 'mmr',
  'rlc', 'mdi', 'wdp', 'npx', 'wbmp', 'xif', 'webp', '3ds', 'ras', 'cmx', 'fh', 'ico', 'pcx', 'pic',
  'pnm', 'pbm', 'pgm', 'ppm', 'rgb', 'tga', 'xbm', 'xpm', 'xwd', 'zip', 'rar', 'tar', 'bz2', 'eot',
  'ttf', 'woff', 'dat'
].forEach(function(extension) {
  isBinary['.' + extension] = true;
});

// TODO(vojta): instantiate preprocessors at the start to show warnings immediately
var createPreprocessor = function(config, basePath, injector) {
  var patterns = Object.keys(config);
  var alreadyDisplayedWarnings = Object.create(null);

  return function(file, done) {
    var thisFileIsBinary = isBinary[path.extname(file.originalPath)];
    var preprocessors = [];
    var nextPreprocessor = function(error, content) {
      // normalize B-C
      if (arguments.length === 1 && typeof error === 'string') {
        content = error;
        error = null;
      }

      if (error) {
        file.content = null;
        file.contentPath = null;
        return done(error);
      }

      if (!preprocessors.length) {
        file.contentPath = null;
        file.content = content;
        return done();
      }

      preprocessors.shift()(content, file, nextPreprocessor);
    };
    var instantiatePreprocessor = function(name) {
      if (alreadyDisplayedWarnings[name]) {
        return;
      }

      try {
        preprocessors.push(injector.get('preprocessor:' + name));
      } catch (e) {
        if (e.message.indexOf('No provider for "preprocessor:' + name + '"') !== -1) {
          log.warn('Can not load "%s", it is not registered!\n  ' +
                   'Perhaps you are missing some plugin?', name);
        } else {
          log.warn('Can not load "%s"!\n  ' + e.stack, name);
        }

        alreadyDisplayedWarnings[name] = true;
      }
    };

    // collects matching preprocessors
    // TODO(vojta): should we cache this ?
    for (var i = 0; i < patterns.length; i++) {
      if (mm(file.originalPath, patterns[i])) {
        if (thisFileIsBinary) {
          log.warn('Ignoring preprocessing (%s) %s because it is a binary file.',
              config[patterns[i]].join(', '), file.originalPath);
        } else {
          config[patterns[i]].forEach(instantiatePreprocessor);
        }
      }
    }

    return fs.readFile(file.originalPath, function(err, buffer) {
      file.sha = sha1(buffer);
      nextPreprocessor(null, thisFileIsBinary ? buffer : buffer.toString());
    });
  };
};
createPreprocessor.$inject = ['config.preprocessors', 'config.basePath', 'injector'];

exports.createPreprocessor = createPreprocessor;
<|endoftext|>


<commit_before>const DEFAULT_ENCODING = 'UTF8';

var fs = require('fs');
var path = require('path');
var util = require('util');
var EventEmitter = require('events').EventEmitter;

var _ = require('underscore');
var workerFarm = require('worker-farm');

var workers;

var Preprocessor = function( preprocessor_path, options ){

  // properly inherit from EventEmitter part 1
  EventEmitter.call( this );

  var server = options.server;
  var logger = server.logger;
  var raven_client = server.raven_client;
  var preprocessor = this;
  var data = this.data = '{}';
  this.path = preprocessor_path;

  // run preprocessor on supplied data
  this.process = function( context, callback ){

    workers( context, this.path, server.session.bind(function( err, preprocessed_context ){
      // preprocessor errors don't bubble up
      // so log them here
      if( err ){
        logger.log( 'Preprocessor Error:\n'+ err.stack, 0 );
        if( raven_client ){
          raven_client.captureError( err, {
            extra: {
              context: context
            }
          });
        }
        if( callback ) return callback( context );
      }
      if( callback ) return callback( preprocessed_context );
    }));

  };

};

// properly inherit from EventEmitter part 2
util.inherits( Preprocessor, EventEmitter );

Preprocessor.setWorkers = function(){
  workers = workerFarm({
    maxCallsPerWorker: 100,
    maxConcurrentWorkers: 4,
    maxConcurrentCallsPerWorker: Infinity,
    maxCallTime: 2000,
    forcedKillTime: 0 // Preprocessors don't listen to system messages, just kill them
  }, require.resolve('./preprocessor_worker.js'));
};

// destroy and re-initialize worker farm
// this is used to update preprocessor modules in development
Preprocessor.resetWorkers = function(){
  workerFarm.end( workers );
  Preprocessor.setWorkers();
};

Preprocessor.setWorkers();

module.exports = Preprocessor;<commit_msg>Log preprocessor errors correctly. Fixes #127.<commit_after>const DEFAULT_ENCODING = 'UTF8';

var fs = require('fs');
var path = require('path');
var util = require('util');
var EventEmitter = require('events').EventEmitter;

var _ = require('underscore');
var workerFarm = require('worker-farm');

var workers;

var Preprocessor = function( preprocessor_path, options ){

  // properly inherit from EventEmitter part 1
  EventEmitter.call( this );

  var server = options.server;
  var logger = server.logger;
  var raven_client = server.raven_client;
  var preprocessor = this;
  var data = this.data = '{}';
  this.path = preprocessor_path;

  // run preprocessor on supplied data
  this.process = function( context, callback ){

    workers( context, this.path, server.session.bind(function( err, preprocessed_context ){
      // preprocessor errors don't bubble up
      // so log them here
      if( err ){
        logger.log( 'Preprocessor Error:\n'+ (err.stack || err.message), 0 );
        if( raven_client ){
          raven_client.captureError( err, {
            extra: {
              context: context
            }
          });
        }
        if( callback ) return callback( context );
      }
      if( callback ) return callback( preprocessed_context );
    }));

  };

};

// properly inherit from EventEmitter part 2
util.inherits( Preprocessor, EventEmitter );

Preprocessor.setWorkers = function(){
  workers = workerFarm({
    maxCallsPerWorker: 100,
    maxConcurrentWorkers: 4,
    maxConcurrentCallsPerWorker: Infinity,
    maxCallTime: 2000,
    forcedKillTime: 0 // Preprocessors don't listen to system messages, just kill them
  }, require.resolve('./preprocessor_worker.js'));
};

// destroy and re-initialize worker farm
// this is used to update preprocessor modules in development
Preprocessor.resetWorkers = function(){
  workerFarm.end( workers );
  Preprocessor.setWorkers();
};

Preprocessor.setWorkers();

module.exports = Preprocessor;<|endoftext|>


<commit_before>const DEFAULT_ENCODING = 'UTF8';

var fs = require('fs');
var path = require('path');
var util = require('util');
var EventEmitter = require('events').EventEmitter;

var _ = require('underscore');
var workerFarm = require('worker-farm');
var workers = workerFarm({
	maxCallsPerWorker: 100,
	maxConcurrentWorkers: 4,
	maxConcurrentCallsPerWorker: -1,
	maxCallTime: 1000
}, require.resolve('./preprocessor_worker.js'));

var Preprocessor = function( preprocessor_path, options ){

	// properly inherit from EventEmitter part 1
	EventEmitter.call( this );

	var server = options.server;
	var preprocessor = this;
	var data = this.data = '{}';
	this.path = preprocessor_path;

	// run preprocessor on supplied data
	this.process = function( context, callback ){

		workers( context, this.path, function( err, preprocessed_context ){
			if( err ){
				//console.log( 'preprocessor error', err );
				if( callback ) return callback( context );
			}
			if( callback ) return callback( preprocessed_context );
		});

	};

	// update the source of the preprocessor
	this.updateSource = function( callback ){

		delete require.cache[this.path];
		callback();

	};

	this.updateSource( function(){
		preprocessor.emit( 'ready' );
	});

};

// properly inherit from EventEmitter part 2
util.inherits( Preprocessor, EventEmitter );

module.exports = Preprocessor;<commit_msg>properly log preprocessor errors<commit_after>const DEFAULT_ENCODING = 'UTF8';

var fs = require('fs');
var path = require('path');
var util = require('util');
var EventEmitter = require('events').EventEmitter;

var _ = require('underscore');
var workerFarm = require('worker-farm');
var workers = workerFarm({
	maxCallsPerWorker: 100,
	maxConcurrentWorkers: 4,
	maxConcurrentCallsPerWorker: -1,
	maxCallTime: 1000
}, require.resolve('./preprocessor_worker.js'));

var Preprocessor = function( preprocessor_path, options ){

	// properly inherit from EventEmitter part 1
	EventEmitter.call( this );

	var server = options.server;
	var logger = server.logger;
	var preprocessor = this;
	var data = this.data = '{}';
	this.path = preprocessor_path;

	// run preprocessor on supplied data
	this.process = function( context, callback ){

		workers( context, this.path, function( err, preprocessed_context ){
			if( err ){
				logger.log( 'Preprocessor Error:\n'+ err.stack, 0 );
				if( callback ) return callback( context );
			}
			if( callback ) return callback( preprocessed_context );
		});

	};

	// update the source of the preprocessor
	this.updateSource = function( callback ){

		delete require.cache[this.path];
		callback();

	};

	this.updateSource( function(){
		preprocessor.emit( 'ready' );
	});

};

// properly inherit from EventEmitter part 2
util.inherits( Preprocessor, EventEmitter );

module.exports = Preprocessor;<|endoftext|>


<commit_before>var env = process.env;
var gzip = require('zlib').gzip;
var compressLimit = 680;
var defaultHeader = {'content-type': 'text/plain'};
var WS;

exports.broadcast = broadcast;
exports.message = message;
exports.link = link;
exports.httpError = httpError;
exports.wsError = wsError;
exports.setWebsocket = function (ws) {
    WS = ws;
};

function convertToBuffer (data, headers) {

    if (data === undefined) {
        return new Buffer(0);
    }

    if (typeof data === 'string') {
        return new Buffer(data);
    }

    if (data instanceof Buffer) {
        return data;
    }

    try {
        data = JSON.stringify(data);

        if (headers) {
            headers['content-type'] = 'application/json; charset=utf-8';
        }
    } catch (err) {
        if (headers) {
            headers['content-type'] = 'text/plain';
        }
        return false;
    }

    if (data === undefined) {
        return false;
    }

    return new Buffer(data);
}

function createMessage (instanceName, err, data, msgId) {

    // return if data is binary
    if (data instanceof Buffer) {
        return data;
    }

    // mono ws protocoll: ["instanceName:msgid","err","data"]
    var message = [instanceName];

    if (msgId) {
        message[0] += ':' + msgId;
    }

    if (data) {
        message[1] = 0,
        message[2] = data;
    }

    if (err) {
        message[1] = err.message || err;
    }

    // parse json
    try {
        message = JSON.stringify(message);
    } catch (err) {
        message[1] = err.message;
    }

    return message;
}

// send a message on the origin socket
function message (err, data, name) {
    var self = this;

    self.ws.send(createMessage(name, err, data, self.id), function(error) {
        // sometimes a socket is closed before the operation is complete.
        // those errors can be ignored
    });
}

// broadcast message to all connected sockets
function broadcast (event, err, data) {
    var self = this;

    data = createMessage(self._._name, event, err, data);

    // broadcast
    for (var i = 0, l = WS.clients.length; i < l; ++i) {
        WS.clients[i].send(data);
    }
}

// send server http errors
function httpError (req, res, code, err) {

    err = err.message || err;

    req.resume();
    res.statusCode = code;
    res.end(convertToBuffer(err));
}

// send server websocket errors
function wsError (ws, err, msgId) {
    ws.send(createMessage(env.Z_CORE_INST, 'error', err, null, msgId));
}

// request response for operations
function link (code, data) {
    var self = this;

    var headers = self.res.headers || defaultHeader;
    headers.server = 'JCES';

    data = convertToBuffer(data, headers);

    if (data === false) {
        code = 500;
        data = 'JSON stringify error';
    }

    if (data.length >= compressLimit && !headers['content-encoding'] && headers['content-type']) {

        switch (headers['content-type'].split('/')[0]) {
            case 'text':
            case 'application':

                self = this;

                return gzip(data, function (err, data) {

                    headers['content-length'] = data.length;
                    headers['content-encoding'] = 'gzip';

                    self.res.writeHead(code, headers);
                    self.res.end(data);
                });
        }
    }

    headers['content-length'] = data.length;

    self.res.writeHead(code, headers);
    self.res.end(data);
}
<commit_msg>removed obsolete code<commit_after>var env = process.env;
var gzip = require('zlib').gzip;
var compressLimit = 680;
var defaultHeader = {'content-type': 'text/plain'};
var WS;

exports.broadcast = broadcast;
exports.message = message;
exports.link = link;
exports.httpError = httpError;
exports.wsError = wsError;
exports.setWebsocket = function (ws) {
    WS = ws;
};

function convertToBuffer (data, headers) {

    if (data === undefined) {
        return new Buffer(0);
    }

    if (typeof data === 'string') {
        return new Buffer(data);
    }

    if (data instanceof Buffer) {
        return data;
    }

    try {
        data = JSON.stringify(data);

        if (headers) {
            headers['content-type'] = 'application/json; charset=utf-8';
        }
    } catch (err) {
        if (headers) {
            headers['content-type'] = 'text/plain';
        }
        return false;
    }

    if (data === undefined) {
        return false;
    }

    return new Buffer(data);
}

function createMessage (instanceName, err, data, msgId) {

    // return if data is binary
    if (data instanceof Buffer) {
        return data;
    }

    // protocoll: ["instanceName:msgid","err","data"]
    var message = [instanceName];

    if (msgId) {
        message[0] += ':' + msgId;
    }

    if (data) {
        message[1] = 0,
        message[2] = data;
    }

    if (err) {
        message[1] = err.message || err;
    }

    // parse json
    try {
        message = JSON.stringify(message);
    } catch (err) {
        message[1] = err.message;
    }

    return message;
}

// send a message on the origin socket
function message (err, data, name) {
    var self = this;

    self.ws.send(createMessage(name, err, data, self.id), function(error) {
        // sometimes a socket is closed before the operation is complete.
        // those errors can be ignored
    });
}

// broadcast message to all connected sockets
function broadcast (event, err, data) {
    var self = this;

    data = createMessage(self._._name, event, err, data);

    // broadcast
    for (var i = 0, l = WS.clients.length; i < l; ++i) {
        WS.clients[i].send(data);
    }
}

// send server http errors
function httpError (req, res, code, err) {

    err = err.message || err;

    req.resume();
    res.statusCode = code;
    res.end(convertToBuffer(err));
}

// send server websocket errors
function wsError (ws, err, msgId) {
    ws.send(createMessage(env.Z_CORE_INST, 'error', err, null, msgId));
}

// request response for operations
function link (code, data) {
    var self = this;

    var headers = self.res.headers || defaultHeader;
    headers.server = 'JCES';

    data = convertToBuffer(data, headers);

    if (data === false) {
        code = 500;
        data = 'JSON stringify error';
    }

    if (data.length >= compressLimit && !headers['content-encoding'] && headers['content-type']) {

        switch (headers['content-type'].split('/')[0]) {
            case 'text':
            case 'application':

                return gzip(data, function (err, data) {

                    headers['content-length'] = data.length;
                    headers['content-encoding'] = 'gzip';

                    self.res.writeHead(code, headers);
                    self.res.end(data);
                });
        }
    }

    headers['content-length'] = data.length;

    self.res.writeHead(code, headers);
    self.res.end(data);
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 */

'use strict';

var React = require('react');
var ReactNative = require('react-native');
var {AccessibilityInfo, Text, View, TouchableOpacity} = ReactNative;

class AccessibilityIOSExample extends React.Component<{}> {
  render() {
    return (
      <View>
        <View
          onAccessibilityTap={() => alert('onAccessibilityTap success')}
          accessible={true}>
          <Text>Accessibility normal tap example</Text>
        </View>
        <View onMagicTap={() => alert('onMagicTap success')} accessible={true}>
          <Text>Accessibility magic tap example</Text>
        </View>
        <View accessibilityLabel="Some announcement" accessible={true}>
          <Text>Accessibility label example</Text>
        </View>
        <View accessibilityTraits={['button', 'selected']} accessible={true}>
          <Text>Accessibility traits example</Text>
        </View>
        <Text>
          Text's accessibilityLabel is the raw text itself unless it is set
          explicitly.
        </Text>
        <Text accessibilityLabel="Test of accessibilityLabel" accessible={true}>
          This text component's accessibilityLabel is set explicitly.
        </Text>
        <View
          accessibilityLabel="Test of accessibilityHint"
          accessibilityHint="The hint provides more info than the label does"
          accessible={true}>
          <Text>
            This view component has both an accessibilityLabel and an
            accessibilityHint explicitly set.
          </Text>
        </View>
        <Text
          accessibilityLabel="Test of accessibilityHint"
          accessibilityHint="The hint provides more info than the label does">
          This text component has both an accessibilityLabel and an
          accessibilityHint explicitly set.
        </Text>
        <TouchableOpacity
          accessibilityLabel="Test of accessibilityHint"
          accessibilityHint="The hint provides more info than the label does">
          <View>
            <Text>
              This button has both an accessibilityLabel and an
              accessibilityHint explicitly set.
            </Text>
          </View>
        </TouchableOpacity>
        <View accessibilityElementsHidden={true}>
          <Text>
            This view's children are hidden from the accessibility tree
          </Text>
        </View>
      </View>
    );
  }
}

class ScreenReaderStatusExample extends React.Component<{}, $FlowFixMeState> {
  state = {
    screenReaderEnabled: false,
  };

  componentDidMount() {
    AccessibilityInfo.addEventListener(
      'change',
      this._handleScreenReaderToggled,
    );
    AccessibilityInfo.fetch().done(isEnabled => {
      this.setState({
        screenReaderEnabled: isEnabled,
      });
    });
  }

  componentWillUnmount() {
    AccessibilityInfo.removeEventListener(
      'change',
      this._handleScreenReaderToggled,
    );
  }

  _handleScreenReaderToggled = isEnabled => {
    this.setState({
      screenReaderEnabled: isEnabled,
    });
  };

  render() {
    return (
      <View>
        <Text>
          The screen reader is{' '}
          {this.state.screenReaderEnabled ? 'enabled' : 'disabled'}.
        </Text>
      </View>
    );
  }
}

exports.title = 'AccessibilityIOS';
exports.description = "Interface to show iOS' accessibility samples";
exports.examples = [
  {
    title: 'Accessibility elements',
    render(): React.Element<any> {
      return <AccessibilityIOSExample />;
    },
  },
  {
    title: 'Check if the screen reader is enabled',
    render(): React.Element<any> {
      return <ScreenReaderStatusExample />;
    },
  },
];
<commit_msg>accessibilityTraits + accessibilityComponentType >> accessibilityRole + accessibilityStates 3/3<commit_after>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 */

'use strict';

var React = require('react');
var ReactNative = require('react-native');
var {AccessibilityInfo, Text, View, TouchableOpacity} = ReactNative;

class AccessibilityIOSExample extends React.Component<{}> {
  render() {
    return (
      <View>
        <View
          onAccessibilityTap={() => alert('onAccessibilityTap success')}
          accessible={true}>
          <Text>Accessibility normal tap example</Text>
        </View>
        <View onMagicTap={() => alert('onMagicTap success')} accessible={true}>
          <Text>Accessibility magic tap example</Text>
        </View>
        <View accessibilityLabel="Some announcement" accessible={true}>
          <Text>Accessibility label example</Text>
        </View>
        <View
          accessibilityRole="button"
          accessibilityStates={['selected']}
          accessible={true}>
          <Text>Accessibility traits example</Text>
        </View>
        <Text>
          Text's accessibilityLabel is the raw text itself unless it is set
          explicitly.
        </Text>
        <Text accessibilityLabel="Test of accessibilityLabel" accessible={true}>
          This text component's accessibilityLabel is set explicitly.
        </Text>
        <View
          accessibilityLabel="Test of accessibilityHint"
          accessibilityHint="The hint provides more info than the label does"
          accessible={true}>
          <Text>
            This view component has both an accessibilityLabel and an
            accessibilityHint explicitly set.
          </Text>
        </View>
        <Text
          accessibilityLabel="Test of accessibilityHint"
          accessibilityHint="The hint provides more info than the label does">
          This text component has both an accessibilityLabel and an
          accessibilityHint explicitly set.
        </Text>
        <TouchableOpacity
          accessibilityLabel="Test of accessibilityHint"
          accessibilityHint="The hint provides more info than the label does">
          <View>
            <Text>
              This button has both an accessibilityLabel and an
              accessibilityHint explicitly set.
            </Text>
          </View>
        </TouchableOpacity>
        <View accessibilityElementsHidden={true}>
          <Text>
            This view's children are hidden from the accessibility tree
          </Text>
        </View>
      </View>
    );
  }
}

class ScreenReaderStatusExample extends React.Component<{}, $FlowFixMeState> {
  state = {
    screenReaderEnabled: false,
  };

  componentDidMount() {
    AccessibilityInfo.addEventListener(
      'change',
      this._handleScreenReaderToggled,
    );
    AccessibilityInfo.fetch().done(isEnabled => {
      this.setState({
        screenReaderEnabled: isEnabled,
      });
    });
  }

  componentWillUnmount() {
    AccessibilityInfo.removeEventListener(
      'change',
      this._handleScreenReaderToggled,
    );
  }

  _handleScreenReaderToggled = isEnabled => {
    this.setState({
      screenReaderEnabled: isEnabled,
    });
  };

  render() {
    return (
      <View>
        <Text>
          The screen reader is{' '}
          {this.state.screenReaderEnabled ? 'enabled' : 'disabled'}.
        </Text>
      </View>
    );
  }
}

exports.title = 'AccessibilityIOS';
exports.description = "Interface to show iOS' accessibility samples";
exports.examples = [
  {
    title: 'Accessibility elements',
    render(): React.Element<any> {
      return <AccessibilityIOSExample />;
    },
  },
  {
    title: 'Check if the screen reader is enabled',
    render(): React.Element<any> {
      return <ScreenReaderStatusExample />;
    },
  },
];
<|endoftext|>


<commit_before>"use strict";

var jsdom   = require('jsdom'),
    request = require('request'),
    is      = require('check-types'),
    config  = require('../config.json');

exports.convert = function (url, params, cb) {
  const self = this;

  params.title = params.title || {}

  self.cbPresent       = is.function(cb);
  self.articleSelector = params.articleQuery || 'article';
  self.tagsToInclude   = (is.array(params.tagQueries) && params.tagQueries.lenght > 0) ? params.tagQueries : ['p','img'];
  self.title           = {
    textOnly:   params.title.textOnly   || true,
    tagToWrap:  params.title.tagToWrap  || 'h2',
    query:      params.title.query      || (function () {
      let resStr = [];
      for(let i = 1; i < 7; i++) {
        resStr.push(`${self.articleSelector} h${i}:first`);
      }
      return resStr.join(', ');
    }())
  }

  self.tagsQuery = function () {
    let resultStrings = [];

    for(let i = 0; i < self.tagsToInclude.length; i++) {
      resultStrings.push(`${self.articleSelector} ${self.tagsToInclude[i]}`);
    }
    return resultStrings.join(', ')
  }

  request({ uri: url }, function (error, response, body) {

  if (error && response.statusCode !== 200) {
    cb(err, null);
  }

  jsdom.env({
    html: body,
    scripts: [
      config.jqueryUrl
    ],
    done: function (err, window) {
        if (is.assigned(err) && self.cbPresent) {
          cb(err, null);
        } else {
          let $     = window.jQuery,
              res   = "",
              title = (function () {
                let element = $(self.title.query).first();
                let fElement = (self.title.textOnly ? $(self.title.tagToWrap).html(element.text()) : element)[0]
                if(is.assigned(fElement)) {
                  return fElement.outerHTML;
                } else {
                  '';
                }

              }())

          res += title;

          $(self.tagsQuery()).each(function (i, el) {
            res += el.outerHTML;
          });
          if(self.cbPresent) { cb(undefined, res); };
        }
      }
    });
  });
}
<commit_msg>Added reading view responder function<commit_after>"use strict";

var jsdom           = require('jsdom'),
    request         = require('request'),
    is              = require('check-types'),
    config          = require('../config.json'),
    nonCustomizable = require('./non-customizable');

exports.convert = function (url, params, cb) {
  const self = this;

  params.title = params.title || {}

  self.cbPresent       = is.function(cb);
  self.articleSelector = params.articleQuery || 'article';
  self.tagsToInclude   = (is.array(params.tagQueries) && params.tagQueries.lenght > 0) ? params.tagQueries : ['p','img'];
  self.title           = {
    textOnly:   params.title.textOnly   || true,
    tagToWrap:  params.title.tagToWrap  || 'h2',
    query:      params.title.query      || (function () {
      let resStr = [];
      for(let i = 1; i < 7; i++) {
        resStr.push(`${self.articleSelector} h${i}:first`);
      }
      return resStr.join(', ');
    }())
  }

  self.tagsQuery = function () {
    let resultStrings = [];

    for(let i = 0; i < self.tagsToInclude.length; i++) {
      resultStrings.push(`${self.articleSelector} ${self.tagsToInclude[i]}`);
    }
    return resultStrings.join(', ')
  }

  request({ uri: url }, function (error, response, body) {

  if (error && response.statusCode !== 200) {
    respond(err, undefined, cb);
  }

  jsdom.env({
    html: body,
    scripts: [
      config.jqueryUrl
    ],
    done: function (err, window) {
        if (is.assigned(err) && self.cbPresent) {
          respond(err, undefined, cb);
        } else {
          let $     = window.jQuery,
              res   = "",
              title = (function () {
                let element = $(self.title.query).first();
                let fElement = (self.title.textOnly ? $(self.title.tagToWrap).html(element.text()) : element)[0]
                if(is.assigned(fElement)) {
                  return fElement.outerHTML;
                } else {
                  '';
                }

              }())

          res += title;

          $(self.tagsQuery()).each(function (i, el) {
            res += el.outerHTML;
          });
          respond(err, res, cb);
        }
      }
    });
  });
}

function respond (err, res, cb) {
  if(err) {
    cb(err);
  } else if(is.function(cb)) {
    cb(undefined, res);
  }
}
<|endoftext|>


<commit_before>function members($$$mptypes){
  var filter=[];
  if (extendsType({t:FunctionDeclaration$meta$declaration},$$$mptypes.Kind$members))filter.push('m');
  if (extendsType({t:ValueDeclaration$meta$declaration},$$$mptypes.Kind$members))filter.push('a','g','o', 's');
  if (extendsType({t:ClassDeclaration$meta$declaration},$$$mptypes.Kind$members))filter.push('c');
  if (extendsType({t:InterfaceDeclaration$meta$declaration},$$$mptypes.Kind$members))filter.push('i');
  if (extendsType({t:AliasDeclaration$meta$declaration},$$$mptypes.Kind$members))filter.push('als');
  var r=[];
  for (var mn in this._pkg) {
    var m = this._pkg[mn];
    var mt = m.mt;
    if (filter.indexOf(mt)>=0 && (m.pa&1)) {
      if (mt === 'm') {
        r.push(OpenFunction(this, m));
      } else if (mt==='c') {
        r.push(OpenClass$jsint(this, m));
      } else if (mt==='i') {
        r.push(OpenInterface$jsint(this, m));
      } else if (mt==='a'||mt==='g'||mt==='o') {
        r.push(OpenValue$jsint(this, m));
      } else if (mt==='s') {
        r.push(OpenSetter(OpenValue$jsint(this, m)));
      } else if (mt==='als') {
        r.push(OpenAlias$jsint(_findTypeFromModel(this,m)));
      }
    }
  }
  return r.length===0?getEmpty():ArraySequence(r,{Element$ArraySequence:$$$mptypes.Kind$members});
}
<commit_msg>fix ceylon/ceylon-js#405<commit_after>function members($$$mptypes){
  var filter=[];
  if (extendsType({t:FunctionDeclaration$meta$declaration},$$$mptypes.Kind$members))filter.push('m');
  if (extendsType({t:ValueDeclaration$meta$declaration},$$$mptypes.Kind$members))filter.push('a','g','s');
  if (extendsType({t:ClassDeclaration$meta$declaration},$$$mptypes.Kind$members))filter.push('c','o');
  if (extendsType({t:InterfaceDeclaration$meta$declaration},$$$mptypes.Kind$members))filter.push('i');
  if (extendsType({t:AliasDeclaration$meta$declaration},$$$mptypes.Kind$members))filter.push('als');
  var r=[];
  for (var mn in this._pkg) {
    var m = this._pkg[mn];
    var mt = m.mt;
    if (filter.indexOf(mt)>=0 && (m.pa&1)) {
      if (mt === 'm') {
        r.push(OpenFunction(this, m));
      } else if (mt==='c'||mt==='o') {
        r.push(OpenClass$jsint(this, m));
      } else if (mt==='i') {
        r.push(OpenInterface$jsint(this, m));
      } else if (mt==='a'||mt==='g') {
        r.push(OpenValue$jsint(this, m));
      } else if (mt==='s') {
        r.push(OpenSetter(OpenValue$jsint(this, m)));
      } else if (mt==='als') {
        r.push(OpenAlias$jsint(_findTypeFromModel(this,m)));
      }
    }
  }
  return r.length===0?getEmpty():ArraySequence(r,{Element$ArraySequence:$$$mptypes.Kind$members});
}
<|endoftext|>


<commit_before>'use strict';

const error = Bento.Error;
const API   = Bento.Helpers.Case.toParam(Bento.config.api.name);

/*
 |--------------------------------------------------------------------------------
 | Redis Bucket
 |--------------------------------------------------------------------------------
 |
 | This class is written to simplify the management of redis stores by placing
 | them in categorized buckets. The inspiration for this class was based on
 | the bucket concept presented in AWS S3 file stores.
 |
 | @author Christoffer Rødvik <snapgravy@gmail.com>
 |
 */

class RedisBucket {

  /**
   * Sets up the redis bucket class.
   * @param  {Object} redis
   * @param  {String} store
   * @return {Void}
   */
  constructor(redis, store) {
    this.redis = redis;
    this.store = store;
  }

  /**
   * Registers a new value with the redis store.
   * @param {String} id
   * @param {String} val
   * @param {Number} [expire]
   */
  *set(id, val, expire) {
    yield this.redis.set((this.store + id), val);
    if (expire) {
      yield this.expire(id, expire);
    }
  }

  // The same as above but dealing with lists...
  *lset(id, val, expire) {
    let key = this.store + id;

    yield this.redis.lpush(key, val);

    if (expire) {
      yield this.expire(id, expire);
    }

    // A hygenic lazy garbage collector
    if(Math.floor(Math.random() * 5) === 0) {
      let len = yield this.redis.llen(key);

      // We do some arbitrary cut-off
      if(len > 15) {

        // Drop us down to 10
        yield this.redis.ltrim(key, 0, len - 10);
      }
    }

  }

  /**
   * Registers a new JSON object with the redis store.
   * @param {String} id
   * @param {Object} val
   * @param {Number} [expire]
   */
  *setJSON(id, val, expire) {
    yield this.set(id, JSON.stringify(val));
    if (expire) {
      yield this.expire(id, expire);
    }
  }

  /**
   * Returns a registered value from the redis store.
   * @param  {String} id
   * @return {String}
   */
  *get(id) {
    return yield this.redis.get(this.store + id);
  }

  *lget(id, val) {
    // our arbitrary cutoff is pretty low, so this should be fine.
    let all = yield this.redis.lrange(this.store + id, 0, 100);

    // we make this backwards compatible with get by returning
    // the value in this case
    if (all.indexOf(val) != -1) {
      return val;
    }
  }

  /**
   * Returns a registered JSON object from the redis store.
   * @param  {String} id
   * @return {Object}
   */
  *getJSON(id) {
    let result = yield this.get(id);
    if (result) {
      return JSON.parse(result);
    }
    return null;
  }

  /**
   * Updates a JSON object with new data.
   * @param {String} id
   * @param {Object} data
   * @param {Number} [expire]
   */
  *putJSON(id, data, expire) {
    let stored = yield this.getJSON(id);
    if (!stored) {
      throw error.parse({
        code    : 'REDIS_BUCKET_NOT_FOUND',
        message : `The redis bucket ${ id } does not exist`
      }, 404);
    }
    yield this.setJSON(id, Object.assign(stored, data), expire);
  }

  /**
   * Deletes a redis key => value pair from the redis store.
   * @param  {String} id
   * @return {Object}
   */
  *del(id) {
    return yield this.redis.del(this.store + id);
  }

  *ldel(id, val) {
    return yield this.redis.lrem(this.store + id, val, 0);
  }

  /**
   * Updates, or sets an expiration timer on a registered key => value pair
   * in the redis store.
   * @param  {String} id
   * @param  {Number} timer
   * @return {Object}
   */
  *expire(id, timer) {
    return yield this.redis.expire((this.store + id), timer);
  }

  /**
   * Removes any expiration timer on the registered key => value pair
   * in the redis store.
   * @param  {String} id
   * @return {Object}
   */
  *persist(id) {
    return yield this.redis.persist(this.store + id);
  }

};

module.exports = function(redis, store) {
  return new RedisBucket(redis, API + ':' + store + ':');
};
<commit_msg>Trimming the garbage collector for redis bucket<commit_after>'use strict';

const error = Bento.Error;
const API   = Bento.Helpers.Case.toParam(Bento.config.api.name);

/*
 |--------------------------------------------------------------------------------
 | Redis Bucket
 |--------------------------------------------------------------------------------
 |
 | This class is written to simplify the management of redis stores by placing
 | them in categorized buckets. The inspiration for this class was based on
 | the bucket concept presented in AWS S3 file stores.
 |
 | @author Christoffer Rødvik <snapgravy@gmail.com>
 |
 */

class RedisBucket {

  /**
   * Sets up the redis bucket class.
   * @param  {Object} redis
   * @param  {String} store
   * @return {Void}
   */
  constructor(redis, store) {
    this.redis = redis;
    this.store = store;
  }

  /**
   * Registers a new value with the redis store.
   * @param {String} id
   * @param {String} val
   * @param {Number} [expire]
   */
  *set(id, val, expire) {
    yield this.redis.set((this.store + id), val);
    if (expire) {
      yield this.expire(id, expire);
    }
  }

  // The same as above but dealing with lists...
  *lset(id, val, expire) {
    let key = this.store + id;

    yield this.redis.lpush(key, val);

    if (expire) {
      yield this.expire(id, expire);
    }

    // A hygenic lazy garbage collector
    if(Math.floor(Math.random() * 5) === 0) {
      let len = yield this.redis.llen(key);

      // We do some arbitrary cut-off
      if(len > 8) {

        // Drop us down to a smaller amount
        yield this.redis.ltrim(key, 0, len - 5);
      }
    }

  }

  /**
   * Registers a new JSON object with the redis store.
   * @param {String} id
   * @param {Object} val
   * @param {Number} [expire]
   */
  *setJSON(id, val, expire) {
    yield this.set(id, JSON.stringify(val));
    if (expire) {
      yield this.expire(id, expire);
    }
  }

  /**
   * Returns a registered value from the redis store.
   * @param  {String} id
   * @return {String}
   */
  *get(id) {
    return yield this.redis.get(this.store + id);
  }

  *lget(id, val) {
    // our arbitrary cutoff is pretty low, so this should be fine.
    let all = yield this.redis.lrange(this.store + id, 0, 100);

    // we make this backwards compatible with get by returning
    // the value in this case
    if (all.indexOf(val) != -1) {
      return val;
    }
  }

  /**
   * Returns a registered JSON object from the redis store.
   * @param  {String} id
   * @return {Object}
   */
  *getJSON(id) {
    let result = yield this.get(id);
    if (result) {
      return JSON.parse(result);
    }
    return null;
  }

  /**
   * Updates a JSON object with new data.
   * @param {String} id
   * @param {Object} data
   * @param {Number} [expire]
   */
  *putJSON(id, data, expire) {
    let stored = yield this.getJSON(id);
    if (!stored) {
      throw error.parse({
        code    : 'REDIS_BUCKET_NOT_FOUND',
        message : `The redis bucket ${ id } does not exist`
      }, 404);
    }
    yield this.setJSON(id, Object.assign(stored, data), expire);
  }

  /**
   * Deletes a redis key => value pair from the redis store.
   * @param  {String} id
   * @return {Object}
   */
  *del(id) {
    return yield this.redis.del(this.store + id);
  }

  *ldel(id, val) {
    return yield this.redis.lrem(this.store + id, val, 0);
  }

  /**
   * Updates, or sets an expiration timer on a registered key => value pair
   * in the redis store.
   * @param  {String} id
   * @param  {Number} timer
   * @return {Object}
   */
  *expire(id, timer) {
    return yield this.redis.expire((this.store + id), timer);
  }

  /**
   * Removes any expiration timer on the registered key => value pair
   * in the redis store.
   * @param  {String} id
   * @return {Object}
   */
  *persist(id) {
    return yield this.redis.persist(this.store + id);
  }

};

module.exports = function(redis, store) {
  return new RedisBucket(redis, API + ':' + store + ':');
};
<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');
var exec = require('child_process').exec;
var Step = require('step');
var markdown = require('robotskirt');

var ReleaseTools = module.exports = function releaseTools(options) {
  options = options || {};
  options.currentPath = options.currentPath || path.join(__dirname, '..');

  var getCurrentVersion = function() {
    return JSON.parse(
      fs.readFileSync(path.join(options.currentPath, "package.json"), 'utf8')
    ).version;
  };

  var formatDate = function(d) {
    var months = [
      "January", "February", "March", "April", "May", "June",
      "July", "August", "September", "October", "November", "December"
    ];

    return months[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear();
  };

  var createPagesBranch = function(callback) {
    Step(
      function() {
        exec('git checkout -b gh-pages', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('ls | grep -v docs | xargs rm', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git mv docs/* .', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git commit -a -m "Initial commit in pages branch"', callback);
      }
    );
  };

  this.isWorkingCopyClean = function(file, callback) {
    if (typeof callback === 'undefined') {
      callback = file;
      file = '';
    }

    exec('git status --porcelain ' + file, function(err, stdout, stderr) {
      if (err) {
        callback(err);
      }
      else if (stdout) {
        callback(null, false);
      } else {
        callback(null, true);
      }
    });
  };

  this.updateChangelog = function(callback) {

    var currentVersion = getCurrentVersion();

    Step(
      function(){
        exec('git checkout History.md', this);
      },
      function(){
        exec('git tag | tail -1', this);
      },
      function(err, tag) {
        var interval = '';
        if (tag !== '') {
          if (tag == getCurrentVersion()) {
            throw 'You have to first update your package.json with the release version';
          }
          interval = tag + '..HEAD ';
        }

        exec('git log ' + interval + '--pretty=format:"  * %s"', function(err, stdout, stderr) {
          if (err) {
            callback("Error while getting the git commits: " + err);
          }

          var changelog = '### ' + version + ' — *' + formatDate(new Date()) + '*\n';

          changelog += '\n' + stdout + '\n\n';
          changelog += fs.readFileSync(path.join(options.currentPath, 'History.md'), 'utf8');;

          // Write contents to `History.md` file again
          fs.writeFileSync('History.md', changelog, 'utf8');

          callback();
        });
      }
    );
  };

  this.updateAuthorsFile = function(callback) {
    exec('git log --all --format="%aN <%aE>" | sort -u', function(err, stdout, stderr) {
      if (err) {
        callback('Error while getting the git contributors: ' + err);
        return;
      }
      fs.writeFileSync(path.join(options.currentPath, 'AUTHORS'), stdout, 'utf8');
      callback();
    });
  };

  this.createExamples = function(callback) {
    var doccoExec = path.join(options.currentPath, 'node_modules', 'docco', 'bin', 'docco');
    var examplesPath = path.join(options.currentPath, 'examples', '*');

    exec(doccoExec + ' ' + examplesPath, function(err, stdout, stderr) {
      if (err) {
        callback(err);
        return;
      }
      callback();
    });
  };

  this.createSite = function(callback) {
    // Insert README.md and History.md between site/_header.html and site/_footer.html
    var html = fs.readFileSync(path.join(
      options.currentPath, 'site', 'index.html'), 'utf8'
    );

    var pattern = /\{\{\s*([A-Za-z0-9\.\-\_]*)\s*\}\}/gm;

    html = html.replace(pattern, function(fullMatch, match) {
      return markdown.toHtmlSync(
        fs.readFileSync(path.join(options.currentPath, match), 'utf8')
      );
    });

    // Write the result into docs/index.html
    fs.writeFileSync(path.join(options.currentPath, 'docs', 'index.html'), html, 'utf8');

    // Copy all the assets to docs/ folder
    exec('cp -r site/javascripts site/stylesheets docs', function(err, stdout, stderr) {
      if (err) {
        callback('Error while copying the assets from site/ folder to docs/ folder: ' + err);
        return;
      }
      callback();
    });
  };

  this.commitToGit = function(callback) {
    var version = getCurrentVersion();

    Step(
      function() {
        exec('git add AUTHORS docs/* History.md', this);
      },
      function() {
        exec('git commit -a -m "Bump version to ' + version + '"', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git tag ' + version, callback);
      }
    );
  };

  this.updatePagesBranch = function(callback) {
    Step(
      function() {
        exec('git branch | grep gh-pages | wc -l', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        if (parseInt(stdout, 10) !== 1) {
          createPagesBranch(this);
        } else {
          exec('git checkout gh-pages', this);
        }
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git merge -s recursive -Xsubtree master', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git checkout master', callback);
      }
    );
  };

  this.pushToGit = function(callback) {
    exec('git push origin master gh-pages --tags', callback);
  };

  this.npmPublish = function(callback) {
    exec('npm publish', callback);
  };

  this.updateVersionInPackageJson = function(releaseType, callback) {
    RELEASE_TYPES = [
      'major',
      'minor',
      'patch'
    ];

    Step(
      function() {
        this.isWorkingCopyClean(this);
      },
      function(err, isClean) {
        if (err) throw err;
        if (!isClean) {
          callback('There are local changes in your git repository, please commit them');
          return;
        }

        var jsonData = JSON.parse(fs.readFileSync(path.join(options.currentPath, "package.json"), 'utf8'));
        var version = jsonData.version.split('.');

        var releaseIndex = RELEASE_TYPES.indexOf(releaseType);
        if (releaseIndex !== -1) {
          releaseIndex = 2;
          version[releaseIndex]++;
          version = version.join('.');
        } else if (releaseType.split('.').length === 3) {
          version = releaseType;
        }

        jsonData.version = version;
        fs.writeFileSync(path.join(options.currentPath, "package.json"), JSON.stringify(jsonData, null, 2), 'utf8');
        callback(null, version);
      }
    );
  };

  return this;
}();<commit_msg>Now it doesn't fail if the History.md file is missing<commit_after>var path = require('path');
var fs = require('fs');
var exec = require('child_process').exec;
var Step = require('step');
var markdown = require('robotskirt');

var ReleaseTools = module.exports = function releaseTools(options) {
  options = options || {};
  options.currentPath = options.currentPath || path.join(__dirname, '..');

  var getCurrentVersion = function() {
    return JSON.parse(
      fs.readFileSync(path.join(options.currentPath, "package.json"), 'utf8')
    ).version;
  };

  var formatDate = function(d) {
    var months = [
      "January", "February", "March", "April", "May", "June",
      "July", "August", "September", "October", "November", "December"
    ];

    return months[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear();
  };

  var createPagesBranch = function(callback) {
    Step(
      function() {
        exec('git checkout -b gh-pages', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('ls | grep -v docs | xargs rm', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git mv docs/* .', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git commit -a -m "Initial commit in pages branch"', callback);
      }
    );
  };

  this.isWorkingCopyClean = function(file, callback) {
    if (typeof callback === 'undefined') {
      callback = file;
      file = '';
    }

    exec('git status --porcelain ' + file, function(err, stdout, stderr) {
      if (err) {
        callback(err);
      }
      else if (stdout) {
        callback(null, false);
      } else {
        callback(null, true);
      }
    });
  };

  this.updateChangelog = function(callback) {

    var currentVersion = getCurrentVersion();

    Step(
      function(){
        exec('git checkout History.md', this);
      },
      function(){
        exec('git tag | tail -1', this);
      },
      function(err, tag) {
        var interval = '';
        if (tag !== '') {
          if (tag == getCurrentVersion()) {
            throw 'You have to first update your package.json with the release version';
          }
          interval = tag + '..HEAD ';
        }

        exec('git log ' + interval + '--pretty=format:"  * %s"', function(err, stdout, stderr) {
          if (err) {
            callback("Error while getting the git commits: " + err);
          }

          var changelog = '### ' + version + ' — *' + formatDate(new Date()) + '*\n';

          changelog += '\n' + stdout + '\n\n';
          if (fs.statSync(path.join(options.currentPath, 'History.md'))) {
            changelog += fs.readFileSync(path.join(options.currentPath, 'History.md'), 'utf8');;
          }

          // Write contents to `History.md` file again
          fs.writeFileSync('History.md', changelog, 'utf8');

          callback();
        });
      }
    );
  };

  this.updateAuthorsFile = function(callback) {
    exec('git log --all --format="%aN <%aE>" | sort -u', function(err, stdout, stderr) {
      if (err) {
        callback('Error while getting the git contributors: ' + err);
        return;
      }
      fs.writeFileSync(path.join(options.currentPath, 'AUTHORS'), stdout, 'utf8');
      callback();
    });
  };

  this.createExamples = function(callback) {
    var doccoExec = path.join(options.currentPath, 'node_modules', 'docco', 'bin', 'docco');
    var examplesPath = path.join(options.currentPath, 'examples', '*');

    exec(doccoExec + ' ' + examplesPath, function(err, stdout, stderr) {
      if (err) {
        callback(err);
        return;
      }
      callback();
    });
  };

  this.createSite = function(callback) {
    // Insert README.md and History.md between site/_header.html and site/_footer.html
    var html = fs.readFileSync(path.join(
      options.currentPath, 'site', 'index.html'), 'utf8'
    );

    var pattern = /\{\{\s*([A-Za-z0-9\.\-\_]*)\s*\}\}/gm;

    html = html.replace(pattern, function(fullMatch, match) {
      return markdown.toHtmlSync(
        fs.readFileSync(path.join(options.currentPath, match), 'utf8')
      );
    });

    // Write the result into docs/index.html
    fs.writeFileSync(path.join(options.currentPath, 'docs', 'index.html'), html, 'utf8');

    // Copy all the assets to docs/ folder
    exec('cp -r site/javascripts site/stylesheets docs', function(err, stdout, stderr) {
      if (err) {
        callback('Error while copying the assets from site/ folder to docs/ folder: ' + err);
        return;
      }
      callback();
    });
  };

  this.commitToGit = function(callback) {
    var version = getCurrentVersion();

    Step(
      function() {
        exec('git add AUTHORS docs/* History.md', this);
      },
      function() {
        exec('git commit -a -m "Bump version to ' + version + '"', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git tag ' + version, callback);
      }
    );
  };

  this.updatePagesBranch = function(callback) {
    Step(
      function() {
        exec('git branch | grep gh-pages | wc -l', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        if (parseInt(stdout, 10) !== 1) {
          createPagesBranch(this);
        } else {
          exec('git checkout gh-pages', this);
        }
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git merge -s recursive -Xsubtree master', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git checkout master', callback);
      }
    );
  };

  this.pushToGit = function(callback) {
    exec('git push origin master gh-pages --tags', callback);
  };

  this.npmPublish = function(callback) {
    exec('npm publish', callback);
  };

  this.updateVersionInPackageJson = function(releaseType, callback) {
    RELEASE_TYPES = [
      'major',
      'minor',
      'patch'
    ];

    Step(
      function() {
        this.isWorkingCopyClean(this);
      },
      function(err, isClean) {
        if (err) throw err;
        if (!isClean) {
          callback('There are local changes in your git repository, please commit them');
          return;
        }

        var jsonData = JSON.parse(fs.readFileSync(path.join(options.currentPath, "package.json"), 'utf8'));
        var version = jsonData.version.split('.');

        var releaseIndex = RELEASE_TYPES.indexOf(releaseType);
        if (releaseIndex !== -1) {
          releaseIndex = 2;
          version[releaseIndex]++;
          version = version.join('.');
        } else if (releaseType.split('.').length === 3) {
          version = releaseType;
        }

        jsonData.version = version;
        fs.writeFileSync(path.join(options.currentPath, "package.json"), JSON.stringify(jsonData, null, 2), 'utf8');
        callback(null, version);
      }
    );
  };

  return this;
}();<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');
var exec = require('child_process').exec;
var Step = require('step');
var markdown = require('robotskirt');

var ReleaseTools = module.exports = function releaseTools(options) {
  options = options || {};
  options.currentPath = options.currentPath || path.join(__dirname, '..');

  var isWorkingCopyClean = function(callback) {
    exec('git status --porcelain', function(err, stdout, stderr) {
      if (err) {
        callback(err);
      }
      else if (stdout) {
        callback(null, false);
      } else {
        callback(null, true);
      }
    });
  };

  this.createExamples = function(callback) {
    var doccoExec = path.join(options.currentPath, 'node_modules', 'docco', 'bin', 'docco');
    var examplesPath = path.join(options.currentPath, 'examples', '*');

    exec(doccoExec + ' ' + examplesPath, function(err, stdout, stderr) {
      if (err) {
        callback(err);
        return;
      }
      callback();
    });
  };

  this.createSite = function(callback) {
    // Insert README.md and History.md between site/_header.html and site/_footer.html
    var html = fs.readFileSync(path.join(
      options.currentPath, 'site', '_header.html'), 'utf8'
    );
    html += markdown.toHtmlSync(
      fs.readFileSync(path.join(options.currentPath, "README.md"), 'utf8')
    );
    html += markdown.toHtmlSync(
      fs.readFileSync(path.join(options.currentPath, "History.md"), 'utf8')
    );
    html += fs.readFileSync(path.join(options.currentPath, 'site', '_footer.html'));

    // Write the result into docs/index.html
    fs.writeFileSync(path.join(options.currentPath, 'docs', 'index.html'), html, 'utf8');

    // Copy all the assets to docs/ folder
    exec('cp -r site/javascripts site/stylesheets docs', function(err, stdout, stderr){
      if (err) {
        callback('Error while copying the assets from site/ folder to docs/ folder: ' + err);
        return;
      }
      callback();
    });
  };

  this.createAuthorsFile = function(callback) {
    exec('git shortlog -nse | cut -c8- >| AUTHORS', function(err, stdout, stderr) {
      if (err) {
        callback('Error while getting the git contributors: ' + err);
        return;
      }
      callback();
    });
  };

  this.updateVersion = function(releaseType, callback) {
    RELEASE_TYPES = [
      'major',
      'minor',
      'patch'
    ];

    Step(
      function() {
        isWorkingCopyClean(this);
      },
      function(err, isClean) {
        if (err) throw err;
        if (!isClean) {
          callback('There are local changes in your git repository, please commit them');
          return;
        }

        var jsonData = JSON.parse(fs.readFileSync(path.join(options.currentPath, "package.json"), 'utf8'));
        var version = jsonData.version.split('.');

        var releaseIndex = RELEASE_TYPES.indexOf(releaseType);
        if (releaseIndex !== -1) {
          releaseIndex = 2;
          version[releaseIndex]++;
          version = version.join('.');
        } else if (releaseType.split('.').length === 3) {
          version = releaseType;
        }

        jsonData.version = version;
        fs.writeFileSync(path.join(options.currentPath, "package.json"), JSON.stringify(jsonData, null, 2), 'utf8');
        callback(null, version);
      }
    );
  };

  this.updateChangelog = function(version, callback) {
    var months = [
      "January", "February", "March", "April", "May", "June",
      "July", "August", "September", "October", "November", "December"
    ];

    Step(
      function(){
        exec('git tag | tail -1', this);
      },
      function(err, stdout) {
        if (err) throw err;

        if (stdout === '') {
          exec('git log --reverse -1 --format=%H', this)
        } else {
          return stdout;
        }
      },
      function(err, tag){
        tag = tag.replace(/\n/g, "");
        exec('git log ' + tag + '..HEAD --pretty=format:"  * %s"', function(err, stdout, stderr) {
          if (err) {
            callback("Error while getting the git commits: " + err);
          }

          var d = new Date();
          var changelog = '### ' + version + ' — *' + months[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear() + '*';

          changelog += '\n' + stdout + '\n';
          changelog += fs.readFileSync(path.join(options.currentPath, 'History.md'), 'utf8');

          // Write contents to `History.md` file again
          fs.writeFileSync('History.md', changelog, 'utf8');

          callback();
        });
      }
    );
  };

  this.commitToGit = function(version, callback) {
    Step(
      function() {
        exec('git commit -a -m "Bump version to ' + version + '"', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git tag ' + version, callback);
      }
    );
  };

  this.createPagesBranch = function(callback) {
    Step(
      function() {
        exec('git checkout -b gh-pages', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('ls | grep -v docs | xargs rm', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git mv docs/* .', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git commit -a -m "Initial commit in pages branch"', callback);
      }
    );
  };

  this.updatePagesBranch = function(callback) {
    Step(
      function() {
        exec('git branch | grep gh-pages | wc -l', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        if (parseInt(stdout, 10) !== 1) {
          this.createPagesBranch(this);
        } else {
          exec('git checkout gh-pages', this);
        }
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git merge -s recursive -Xsubtree master', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git checkout master', callback);
      }
    );
  };

  this.pushToGit = function(callback) {
    exec('git push origin master gh-pages --tags', callback);
  };

  this.npmPublish = function(callback) {
    exec('npm publish', callback);
  };

  return this;
}();<commit_msg>Fixed getting the first commit of a git repository<commit_after>var path = require('path');
var fs = require('fs');
var exec = require('child_process').exec;
var Step = require('step');
var markdown = require('robotskirt');

var ReleaseTools = module.exports = function releaseTools(options) {
  options = options || {};
  options.currentPath = options.currentPath || path.join(__dirname, '..');

  var isWorkingCopyClean = function(callback) {
    exec('git status --porcelain', function(err, stdout, stderr) {
      if (err) {
        callback(err);
      }
      else if (stdout) {
        callback(null, false);
      } else {
        callback(null, true);
      }
    });
  };

  this.createExamples = function(callback) {
    var doccoExec = path.join(options.currentPath, 'node_modules', 'docco', 'bin', 'docco');
    var examplesPath = path.join(options.currentPath, 'examples', '*');

    exec(doccoExec + ' ' + examplesPath, function(err, stdout, stderr) {
      if (err) {
        callback(err);
        return;
      }
      callback();
    });
  };

  this.createSite = function(callback) {
    // Insert README.md and History.md between site/_header.html and site/_footer.html
    var html = fs.readFileSync(path.join(
      options.currentPath, 'site', '_header.html'), 'utf8'
    );
    html += markdown.toHtmlSync(
      fs.readFileSync(path.join(options.currentPath, "README.md"), 'utf8')
    );
    html += markdown.toHtmlSync(
      fs.readFileSync(path.join(options.currentPath, "History.md"), 'utf8')
    );
    html += fs.readFileSync(path.join(options.currentPath, 'site', '_footer.html'));

    // Write the result into docs/index.html
    fs.writeFileSync(path.join(options.currentPath, 'docs', 'index.html'), html, 'utf8');

    // Copy all the assets to docs/ folder
    exec('cp -r site/javascripts site/stylesheets docs', function(err, stdout, stderr){
      if (err) {
        callback('Error while copying the assets from site/ folder to docs/ folder: ' + err);
        return;
      }
      callback();
    });
  };

  this.createAuthorsFile = function(callback) {
    exec('git shortlog -nse | cut -c8- >| AUTHORS', function(err, stdout, stderr) {
      if (err) {
        callback('Error while getting the git contributors: ' + err);
        return;
      }
      callback();
    });
  };

  this.updateVersion = function(releaseType, callback) {
    RELEASE_TYPES = [
      'major',
      'minor',
      'patch'
    ];

    Step(
      function() {
        isWorkingCopyClean(this);
      },
      function(err, isClean) {
        if (err) throw err;
        if (!isClean) {
          callback('There are local changes in your git repository, please commit them');
          return;
        }

        var jsonData = JSON.parse(fs.readFileSync(path.join(options.currentPath, "package.json"), 'utf8'));
        var version = jsonData.version.split('.');

        var releaseIndex = RELEASE_TYPES.indexOf(releaseType);
        if (releaseIndex !== -1) {
          releaseIndex = 2;
          version[releaseIndex]++;
          version = version.join('.');
        } else if (releaseType.split('.').length === 3) {
          version = releaseType;
        }

        jsonData.version = version;
        fs.writeFileSync(path.join(options.currentPath, "package.json"), JSON.stringify(jsonData, null, 2), 'utf8');
        callback(null, version);
      }
    );
  };

  this.updateChangelog = function(version, callback) {
    var months = [
      "January", "February", "March", "April", "May", "June",
      "July", "August", "September", "October", "November", "December"
    ];

    Step(
      function(){
        exec('git tag | tail -1', this);
      },
      function(err, stdout) {
        if (err) throw err;

        if (stdout === '') {
          exec('git log --format=%H | tail -1', this)
        } else {
          return stdout;
        }
      },
      function(err, tag) {
        tag = tag.replace(/\n/g, "");
        exec('git log ' + tag + '..HEAD --pretty=format:"  * %s"', function(err, stdout, stderr) {
          if (err) {
            callback("Error while getting the git commits: " + err);
          }

          var d = new Date();
          var changelog = '### ' + version + ' — *' + months[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear() + '*';

          changelog += '\n' + stdout + '\n';
          changelog += fs.readFileSync(path.join(options.currentPath, 'History.md'), 'utf8');

          // Write contents to `History.md` file again
          fs.writeFileSync('History.md', changelog, 'utf8');

          callback();
        });
      }
    );
  };

  this.commitToGit = function(version, callback) {
    Step(
      function() {
        exec('git commit -a -m "Bump version to ' + version + '"', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git tag ' + version, callback);
      }
    );
  };

  this.createPagesBranch = function(callback) {
    Step(
      function() {
        exec('git checkout -b gh-pages', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('ls | grep -v docs | xargs rm', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git mv docs/* .', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git commit -a -m "Initial commit in pages branch"', callback);
      }
    );
  };

  this.updatePagesBranch = function(callback) {
    Step(
      function() {
        exec('git branch | grep gh-pages | wc -l', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        if (parseInt(stdout, 10) !== 1) {
          this.createPagesBranch(this);
        } else {
          exec('git checkout gh-pages', this);
        }
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git merge -s recursive -Xsubtree master', this);
      },
      function(err, stdout, stderr) {
        if (err) throw err;
        exec('git checkout master', callback);
      }
    );
  };

  this.pushToGit = function(callback) {
    exec('git push origin master gh-pages --tags', callback);
  };

  this.npmPublish = function(callback) {
    exec('npm publish', callback);
  };

  return this;
}();<|endoftext|>


<commit_before>// const { get } = require('birsky-struct/lib/get')
const widgets = require('../widget/widgets')
const { isWidget } = require('../get')

const onRemove = (t, key) => t.emitters && t.emitters.remove ||
  t.inherits && onRemove(t.inherits)

module.exports = (t, state, type, subs, tree, id, pid, order) => {
  if (type === 'remove') {
    for (let i = widgets.length - 1; i >= 0; i = i - 3) {
      const wtree = widgets[i]
      let ptree = wtree
      while (ptree) {
        if (tree === ptree) {
          emitRemove(widgets[i - 2], state, wtree, widgets[i - 1])
          widgets.splice(i - 2, 3)
        }
        ptree = ptree._p
      }
    }
    if (onRemove(t) && !isWidget(t)) {
      emitRemove(t, state, tree, id)
    }
  } else if (!tree._) {
    tree._ = {}
  }
  return t.render.state(t, state, type, subs, tree, id, pid, order)
}

function emitRemove (t, state, tree, id) {
  const data = { target: tree._ && tree._[id], state }
  t.emit('remove', data, state.stamp)
}
<commit_msg>cleanup<commit_after>const widgets = require('../widget/widgets')
const { isWidget } = require('../get')

module.exports = (t, state, type, subs, tree, id, pid, order) => {
  if (type === 'remove') {
    for (let i = widgets.length - 1; i >= 0; i = i - 3) {
      const wtree = widgets[i]
      let ptree = wtree
      while (ptree) {
        if (tree === ptree) {
          emitRemove(widgets[i - 2], state, wtree, widgets[i - 1])
          widgets.splice(i - 2, 3)
        }
        ptree = ptree._p
      }
    }
    if (onRemove(t) && !isWidget(t)) {
      emitRemove(t, state, tree, id)
    }
  } else if (!tree._) {
    tree._ = {}
  }
  return t.render.state(t, state, type, subs, tree, id, pid, order)
}

const emitRemove = (t, state, tree, id) => {
  const data = { target: tree._ && tree._[id], state }
  t.emit('remove', data, state.stamp)
}

const onRemove = (t, key) => t.emitters && t.emitters.remove ||
  t.inherits && onRemove(t.inherits)
<|endoftext|>


<commit_before>/**
 * Module of mixed-in functions shared between node and client code
 */
var isObject = require('./is-object');

/**
 * Expose `RequestBase`.
 */

module.exports = RequestBase;

/**
 * Initialize a new `RequestBase`.
 *
 * @api public
 */

function RequestBase(obj) {
  if (obj) return mixin(obj);
}

/**
 * Mixin the prototype properties.
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

function mixin(obj) {
  for (var key in RequestBase.prototype) {
    obj[key] = RequestBase.prototype[key];
  }
  return obj;
}

/**
 * Clear previous timeout.
 *
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.clearTimeout = function _clearTimeout(){
  this._timeout = 0;
  clearTimeout(this._timer);
  return this;
};

/**
 * Override default response body parser
 *
 * This function will be called to convert incoming data into request.body
 *
 * @param {Function}
 * @api public
 */

RequestBase.prototype.parse = function parse(fn){
  this._parser = fn;
  return this;
};

/**
 * Override default request body serializer
 *
 * This function will be called to convert data set via .send or .attach into payload to send
 *
 * @param {Function}
 * @api public
 */

RequestBase.prototype.serialize = function serialize(fn){
  this._serializer = fn;
  return this;
};

/**
 * Set timeout to `ms`.
 *
 * @param {Number} ms
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.timeout = function timeout(ms){
  this._timeout = ms;
  return this;
};

/**
 * Promise support
 *
 * @param {Function} resolve
 * @param {Function} reject
 * @return {Request}
 */

RequestBase.prototype.then = function then(resolve, reject) {
  if (!this._fullfilledPromise) {
    var self = this;
    this._fullfilledPromise = new Promise(function(innerResolve, innerReject){
      self.end(function(err, res){
        if (err) innerReject(err); else innerResolve(res);
      });
    });
  }
  return this._fullfilledPromise.then(resolve, reject);
}

RequestBase.prototype.catch = function(cb) {
  return this.then(undefined, cb);
};

/**
 * Allow for extension
 */

RequestBase.prototype.use = function use(fn) {
  fn(this);
  return this;
}

/**
 * Get request header `field`.
 * Case-insensitive.
 *
 * @param {String} field
 * @return {String}
 * @api public
 */

RequestBase.prototype.get = function(field){
  return this._header[field.toLowerCase()];
};

/**
 * Get case-insensitive header `field` value.
 * This is a deprecated internal API. Use `.get(field)` instead.
 *
 * (getHeader is no longer used internally by the superagent code base)
 *
 * @param {String} field
 * @return {String}
 * @api private
 * @deprecated
 */

RequestBase.prototype.getHeader = RequestBase.prototype.get;

/**
 * Set header `field` to `val`, or multiple fields with one object.
 * Case-insensitive.
 *
 * Examples:
 *
 *      req.get('/')
 *        .set('Accept', 'application/json')
 *        .set('X-API-Key', 'foobar')
 *        .end(callback);
 *
 *      req.get('/')
 *        .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
 *        .end(callback);
 *
 * @param {String|Object} field
 * @param {String} val
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.set = function(field, val){
  if (isObject(field)) {
    for (var key in field) {
      this.set(key, field[key]);
    }
    return this;
  }
  this._header[field.toLowerCase()] = val;
  this.header[field] = val;
  return this;
};

/**
 * Remove header `field`.
 * Case-insensitive.
 *
 * Example:
 *
 *      req.get('/')
 *        .unset('User-Agent')
 *        .end(callback);
 *
 * @param {String} field
 */
RequestBase.prototype.unset = function(field){
  delete this._header[field.toLowerCase()];
  delete this.header[field];
  return this;
};

/**
 * Write the field `name` and `val`, or multiple fields with one object
 * for "multipart/form-data" request bodies.
 *
 * ``` js
 * request.post('/upload')
 *   .field('foo', 'bar')
 *   .end(callback);
 *
 * request.post('/upload')
 *   .field({ foo: 'bar', baz: 'qux' })
 *   .end(callback);
 * ```
 *
 * @param {String|Object} name
 * @param {String|Blob|File|Buffer|fs.ReadStream} val
 * @return {Request} for chaining
 * @api public
 */
RequestBase.prototype.field = function(name, val) {

  // name should be either a string or an object.
  if (null === name ||  undefined === name) {
    throw new Error('.field(name, val) name can not be empty');
  }

  if (isObject(name)) {
    for (var key in name) {
      this.field(key, name[key]);
    }
    return this;
  }

  // val should be defined now
  if (null === val || undefined === val) {
    throw new Error('.field(name, val) val can not be empty');
  }
  this._getFormData().append(name, val);
  return this;
};

/**
 * Abort the request, and clear potential timeout.
 *
 * @return {Request}
 * @api public
 */
RequestBase.prototype.abort = function(){
  if (this._aborted) {
    return this;
  }
  this._aborted = true;
  this.xhr && this.xhr.abort(); // browser
  this.req && this.req.abort(); // node
  this.clearTimeout();
  this.emit('abort');
  return this;
};

/**
 * Enable transmission of cookies with x-domain requests.
 *
 * Note that for this to work the origin must not be
 * using "Access-Control-Allow-Origin" with a wildcard,
 * and also must set "Access-Control-Allow-Credentials"
 * to "true".
 *
 * @api public
 */

RequestBase.prototype.withCredentials = function(){
  // This is browser-only functionality. Node side is no-op.
  this._withCredentials = true;
  return this;
};

/**
 * Set the max redirects to `n`. Does noting in browser XHR implementation.
 *
 * @param {Number} n
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.redirects = function(n){
  this._maxRedirects = n;
  return this;
};

/**
 * Convert to a plain javascript object (not JSON string) of scalar properties.
 * Note as this method is designed to return a useful non-this value,
 * it cannot be chained.
 *
 * @return {Object} describing method, url, and data of this request
 * @api public
 */

RequestBase.prototype.toJSON = function(){
  return {
    method: this.method,
    url: this.url,
    data: this._data,
    headers: this._header
  };
};

/**
 * Send `data` as the request body, defaulting the `.type()` to "json" when
 * an object is given.
 *
 * Examples:
 *
 *       // manual json
 *       request.post('/user')
 *         .type('json')
 *         .send('{"name":"tj"}')
 *         .end(callback)
 *
 *       // auto json
 *       request.post('/user')
 *         .send({ name: 'tj' })
 *         .end(callback)
 *
 *       // manual x-www-form-urlencoded
 *       request.post('/user')
 *         .type('form')
 *         .send('name=tj')
 *         .end(callback)
 *
 *       // auto x-www-form-urlencoded
 *       request.post('/user')
 *         .type('form')
 *         .send({ name: 'tj' })
 *         .end(callback)
 *
 *       // defaults to x-www-form-urlencoded
 *      request.post('/user')
 *        .send('name=tobi')
 *        .send('species=ferret')
 *        .end(callback)
 *
 * @param {String|Object} data
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.send = function(data){
  var isObj = isObject(data);
  var type = this._header['content-type'];

  if (isObj && !this._data) {
    if (Array.isArray(data)) {
      this._data = [];
    } else if (!this._isHost(data)) {
      this._data = {};
    }
  } else if (data && this._data && this._isHost(this._data)) {
    throw Error("Can't merge these send calls");
  }

  // merge
  if (isObj && isObject(this._data)) {
    for (var key in data) {
      this._data[key] = data[key];
    }
  } else if ('string' == typeof data) {
    // default to x-www-form-urlencoded
    if (!type) this.type('form');
    type = this._header['content-type'];
    if ('application/x-www-form-urlencoded' == type) {
      this._data = this._data
        ? this._data + '&' + data
        : data;
    } else {
      this._data = (this._data || '') + data;
    }
  } else {
    this._data = data;
  }

  if (!isObj || this._isHost(data)) return this;

  // default to json
  if (!type) this.type('json');
  return this;
};

/**
 * Sort `querystring` by the sort function
 *
 *
 * Examples:
 *
 *       // default order
 *       request.get('/user')
 *         .query('name=Nick')
 *         .query('search=Manny')
 *         .sortQuery()
 *         .end(callback)
 *
 *       // customized sort function
 *       request.get('/user')
 *         .query('name=Nick')
 *         .query('search=Manny')
 *         .sortQuery(function(a, b){
 *           return a.length - b.length;
 *         })
 *         .end(callback)
 *
 *
 * @param {Function} sort
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.sortQuery = function(sort) {
  // _sort default to true but otherwise can be a function or boolean
  this._sort = typeof sort === 'undefined' ? true : sort;
  return this;
};
<commit_msg>Fix #994<commit_after>/**
 * Module of mixed-in functions shared between node and client code
 */
var isObject = require('./is-object');

/**
 * Expose `RequestBase`.
 */

module.exports = RequestBase;

/**
 * Initialize a new `RequestBase`.
 *
 * @api public
 */

function RequestBase(obj) {
  if (obj) return mixin(obj);
}

/**
 * Mixin the prototype properties.
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

function mixin(obj) {
  for (var key in RequestBase.prototype) {
    obj[key] = RequestBase.prototype[key];
  }
  return obj;
}

/**
 * Clear previous timeout.
 *
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.clearTimeout = function _clearTimeout(){
  this._timeout = 0;
  clearTimeout(this._timer);
  return this;
};

/**
 * Override default response body parser
 *
 * This function will be called to convert incoming data into request.body
 *
 * @param {Function}
 * @api public
 */

RequestBase.prototype.parse = function parse(fn){
  this._parser = fn;
  return this;
};

/**
 * Override default request body serializer
 *
 * This function will be called to convert data set via .send or .attach into payload to send
 *
 * @param {Function}
 * @api public
 */

RequestBase.prototype.serialize = function serialize(fn){
  this._serializer = fn;
  return this;
};

/**
 * Set timeout to `ms`.
 *
 * @param {Number} ms
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.timeout = function timeout(ms){
  this._timeout = ms;
  return this;
};

/**
 * Promise support
 *
 * @param {Function} resolve
 * @param {Function} reject
 * @return {Request}
 */

RequestBase.prototype.then = function then(resolve, reject) {
  if (!this._fullfilledPromise) {
    var self = this;
    this._fullfilledPromise = new Promise(function(innerResolve, innerReject){
      self.end(function(err, res){
        if (err) innerReject(err); else innerResolve(res);
      });
    });
  }
  return this._fullfilledPromise.then(resolve, reject);
}

RequestBase.prototype.catch = function(cb) {
  return this.then(undefined, cb);
};

/**
 * Allow for extension
 */

RequestBase.prototype.use = function use(fn) {
  fn(this);
  return this;
}

/**
 * Get request header `field`.
 * Case-insensitive.
 *
 * @param {String} field
 * @return {String}
 * @api public
 */

RequestBase.prototype.get = function(field){
  return this._header[field.toLowerCase()];
};

/**
 * Get case-insensitive header `field` value.
 * This is a deprecated internal API. Use `.get(field)` instead.
 *
 * (getHeader is no longer used internally by the superagent code base)
 *
 * @param {String} field
 * @return {String}
 * @api private
 * @deprecated
 */

RequestBase.prototype.getHeader = RequestBase.prototype.get;

/**
 * Set header `field` to `val`, or multiple fields with one object.
 * Case-insensitive.
 *
 * Examples:
 *
 *      req.get('/')
 *        .set('Accept', 'application/json')
 *        .set('X-API-Key', 'foobar')
 *        .end(callback);
 *
 *      req.get('/')
 *        .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
 *        .end(callback);
 *
 * @param {String|Object} field
 * @param {String} val
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.set = function(field, val){
  if (isObject(field)) {
    for (var key in field) {
      this.set(key, field[key]);
    }
    return this;
  }
  this._header[field.toLowerCase()] = val;
  this.header[field] = val;
  return this;
};

/**
 * Remove header `field`.
 * Case-insensitive.
 *
 * Example:
 *
 *      req.get('/')
 *        .unset('User-Agent')
 *        .end(callback);
 *
 * @param {String} field
 */
RequestBase.prototype.unset = function(field){
  delete this._header[field.toLowerCase()];
  delete this.header[field];
  return this;
};

/**
 * Write the field `name` and `val`, or multiple fields with one object
 * for "multipart/form-data" request bodies.
 *
 * ``` js
 * request.post('/upload')
 *   .field('foo', 'bar')
 *   .end(callback);
 *
 * request.post('/upload')
 *   .field({ foo: 'bar', baz: 'qux' })
 *   .end(callback);
 * ```
 *
 * @param {String|Object} name
 * @param {String|Blob|File|Buffer|fs.ReadStream} val
 * @return {Request} for chaining
 * @api public
 */
RequestBase.prototype.field = function(name, val) {

  // name should be either a string or an object.
  if (null === name ||  undefined === name) {
    throw new Error('.field(name, val) name can not be empty');
  }

  if (isObject(name)) {
    for (var key in name) {
      this.field(key, name[key]);
    }
    return this;
  }

  // val should be defined now
  if (null === val || undefined === val) {
    throw new Error('.field(name, val) val can not be empty');
  }
  if ('boolean' === typeof val) {
    val = '' + val;
  }
  this._getFormData().append(name, val);
  return this;
};

/**
 * Abort the request, and clear potential timeout.
 *
 * @return {Request}
 * @api public
 */
RequestBase.prototype.abort = function(){
  if (this._aborted) {
    return this;
  }
  this._aborted = true;
  this.xhr && this.xhr.abort(); // browser
  this.req && this.req.abort(); // node
  this.clearTimeout();
  this.emit('abort');
  return this;
};

/**
 * Enable transmission of cookies with x-domain requests.
 *
 * Note that for this to work the origin must not be
 * using "Access-Control-Allow-Origin" with a wildcard,
 * and also must set "Access-Control-Allow-Credentials"
 * to "true".
 *
 * @api public
 */

RequestBase.prototype.withCredentials = function(){
  // This is browser-only functionality. Node side is no-op.
  this._withCredentials = true;
  return this;
};

/**
 * Set the max redirects to `n`. Does noting in browser XHR implementation.
 *
 * @param {Number} n
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.redirects = function(n){
  this._maxRedirects = n;
  return this;
};

/**
 * Convert to a plain javascript object (not JSON string) of scalar properties.
 * Note as this method is designed to return a useful non-this value,
 * it cannot be chained.
 *
 * @return {Object} describing method, url, and data of this request
 * @api public
 */

RequestBase.prototype.toJSON = function(){
  return {
    method: this.method,
    url: this.url,
    data: this._data,
    headers: this._header
  };
};

/**
 * Send `data` as the request body, defaulting the `.type()` to "json" when
 * an object is given.
 *
 * Examples:
 *
 *       // manual json
 *       request.post('/user')
 *         .type('json')
 *         .send('{"name":"tj"}')
 *         .end(callback)
 *
 *       // auto json
 *       request.post('/user')
 *         .send({ name: 'tj' })
 *         .end(callback)
 *
 *       // manual x-www-form-urlencoded
 *       request.post('/user')
 *         .type('form')
 *         .send('name=tj')
 *         .end(callback)
 *
 *       // auto x-www-form-urlencoded
 *       request.post('/user')
 *         .type('form')
 *         .send({ name: 'tj' })
 *         .end(callback)
 *
 *       // defaults to x-www-form-urlencoded
 *      request.post('/user')
 *        .send('name=tobi')
 *        .send('species=ferret')
 *        .end(callback)
 *
 * @param {String|Object} data
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.send = function(data){
  var isObj = isObject(data);
  var type = this._header['content-type'];

  if (isObj && !this._data) {
    if (Array.isArray(data)) {
      this._data = [];
    } else if (!this._isHost(data)) {
      this._data = {};
    }
  } else if (data && this._data && this._isHost(this._data)) {
    throw Error("Can't merge these send calls");
  }

  // merge
  if (isObj && isObject(this._data)) {
    for (var key in data) {
      this._data[key] = data[key];
    }
  } else if ('string' == typeof data) {
    // default to x-www-form-urlencoded
    if (!type) this.type('form');
    type = this._header['content-type'];
    if ('application/x-www-form-urlencoded' == type) {
      this._data = this._data
        ? this._data + '&' + data
        : data;
    } else {
      this._data = (this._data || '') + data;
    }
  } else {
    this._data = data;
  }

  if (!isObj || this._isHost(data)) return this;

  // default to json
  if (!type) this.type('json');
  return this;
};

/**
 * Sort `querystring` by the sort function
 *
 *
 * Examples:
 *
 *       // default order
 *       request.get('/user')
 *         .query('name=Nick')
 *         .query('search=Manny')
 *         .sortQuery()
 *         .end(callback)
 *
 *       // customized sort function
 *       request.get('/user')
 *         .query('name=Nick')
 *         .query('search=Manny')
 *         .sortQuery(function(a, b){
 *           return a.length - b.length;
 *         })
 *         .end(callback)
 *
 *
 * @param {Function} sort
 * @return {Request} for chaining
 * @api public
 */

RequestBase.prototype.sortQuery = function(sort) {
  // _sort default to true but otherwise can be a function or boolean
  this._sort = typeof sort === 'undefined' ? true : sort;
  return this;
};
<|endoftext|>


<commit_before>/**
 * Created by Nicola on 25/07/2015.
 */
<commit_msg>Create basic structure for project<commit_after><|endoftext|>


<commit_before>var key_handler;

var hotkeyInformation           = {}
var bShowLoadingDialog          = true;
var bIsActivated                = true;
var bIncludeNsfwResults         = false;
var excludedBoards              = '';

var sfw_boards                  = [ 'a', 'c', 'w', 'm', 'cgl', 'cm', 'f', 'n', 'jp', 'v', 'vg', 'vp', 'vr',
                                    'co', 'g', 'tv', 'k', 'o', 'an', 'tg', 'sp', 'asp', 'sci', 'his', 'int',
                                    'out', 'toy', 'i', 'po', 'p', 'ck', 'ic', 'wg', 'mu', 'fa', '3', 'gd', 'diy',
                                    'wsg', 'qst', 'biz', 'trv', 'fit', 'x', 'lit', 'adv', 'lgbt', 'mlp', 'news',
                                    'wsr'];

var nsfw_boards                 = [ 'b', 'r9k', 'pol', 'soc', 's4s', 's', 'hc', 'hm', 'h', 'e', 'u', 'd', 'y',
                                    't', 'hr', 'gif', 'aco', 'r'];

function get_random_index( a ) {
    return a[ Math.floor( Math.random() * a.length ) ];
}

function init_handler( ) {
    var hotkey_jwerty_combo     = '';

    if( $.isEmptyObject( hotkeyInformation ) ) {
        hotkey_jwerty_combo = '⇧+→'
    }
    else {
        hotkey_jwerty_combo = hotkeyInformation.comboString.split('').join('+');
    }

    key_handler = jwerty.key( hotkey_jwerty_combo, function ( ) {
        if( !!!bIsActivated ) return true;

        if( bShowLoadingDialog ) {
            $.blockUI({
                message: '
 Loading...
',
                css: { backgroundColor: '#000000', color: '#ffffff', border: '0', borderRadius: '5px', padding: '10px' }
            });
        }

        if( window.location.href.includes(".4chan.org") ) {
            var selected_board  = '';
            var selected_thread = '';

            var possible_boards = sfw_boards;
            if( bIncludeNsfwResults ) {
                possible_boards = sfw_boards.concat( nsfw_boards );
            }

            var excludeBoardsFormatted = $.map( excludedBoards.split(','), $.trim );
            possible_boards = $( possible_boards ).not( excludeBoardsFormatted ).get();

            if( possible_boards.length == 0 ) {
                $.unblockUI();
                return true;
            }

            selected_board = get_random_index( possible_boards );

            $.getJSON( "https://a.4cdn.org/" + selected_board + "/threads.json", function( data ) {
                var selected_page = get_random_index( data );
                selected_thread   = get_random_index( selected_page.threads ).no;

                window.location = 'https://boards.4chan.org/' + selected_board + '/thread/' + selected_thread;
            })
            .fail(function() {
                $.unblockUI();
            });
        }
        else {
            window.location = 'https://www.reddit.com/r/' +
                ( ( bIncludeNsfwResults && Math.random() < 0.5 ) ? 'randnsfw' : 'random' );
        }
    });
}

chrome.storage.onChanged.addListener(function(changes, namespace) {
    for (key in changes) {
        var storageChange = changes[key];

        if( key == "hotkeyInformation" ) {
            hotkeyInformation = storageChange.newValue;

            key_handler.unbind();
            init_handler();
        }

        if( key == "showLoadingDialog" ) {
            bShowLoadingDialog = storageChange.newValue;
        }

        if( key == "isActivated" ) {
            bIsActivated = storageChange.newValue;
        }

        if( key == "includeNsfwResults" ) {
            bIncludeNsfwResults = storageChange.newValue;
        }

        if( key == "excludedBoards" ) {
            excludedBoards = storageChange.newValue;
        }
    }
});

chrome.storage.local.get({
    hotkeyInformation           : {},
    showLoadingDialog           : true,
    isActivated                 : true,
    includeNsfwResults          : false,
    excludedBoards              : ''
}, function ( items ) {
    hotkeyInformation           = items.hotkeyInformation;
    bShowLoadingDialog          = items.showLoadingDialog;
    bIsActivated                = items.isActivated;
    bIncludeNsfwResults         = items.includeNsfwResults;
    excludedBoards              = items.excludedBoards

    init_handler( );
});

<commit_msg>Cleaning up content-script to use options dict<commit_after>var key_handler;

var options = {
    "hotkeyInformation"     : {},
    "showLoadingDialog"     : true,
    "isActivated"           : true,
    "includeNsfwResults"    : false,
    "excludedBoards"        : ''
};

var sfw_boards                  = [ 'a', 'c', 'w', 'm', 'cgl', 'cm', 'f', 'n', 'jp', 'v', 'vg', 'vp', 'vr',
                                    'co', 'g', 'tv', 'k', 'o', 'an', 'tg', 'sp', 'asp', 'sci', 'his', 'int',
                                    'out', 'toy', 'i', 'po', 'p', 'ck', 'ic', 'wg', 'mu', 'fa', '3', 'gd', 'diy',
                                    'wsg', 'qst', 'biz', 'trv', 'fit', 'x', 'lit', 'adv', 'lgbt', 'mlp', 'news',
                                    'wsr'];

var nsfw_boards                 = [ 'b', 'r9k', 'pol', 'soc', 's4s', 's', 'hc', 'hm', 'h', 'e', 'u', 'd', 'y',
                                    't', 'hr', 'gif', 'aco', 'r'];

function get_random_index( a ) {
    return a[ Math.floor( Math.random() * a.length ) ];
}

function init_handler( ) {
    var hotkey_jwerty_combo     = '';

    if( $.isEmptyObject( options["hotkeyInformation"] ) ) {
        hotkey_jwerty_combo = '⇧+→'
    }
    else {
        hotkey_jwerty_combo = options["hotkeyInformation"].comboString.split('').join('+');
    }

    key_handler = jwerty.key( hotkey_jwerty_combo, function ( ) {
        if( !!!options["isActivated"] ) return true;

        if( options["showLoadingDialog"] ) {
            $.blockUI({
                message: '
 Loading...
',
                css: { backgroundColor: '#000000', color: '#ffffff', border: '0', borderRadius: '5px', padding: '10px' }
            });
        }

        if( window.location.href.includes(".4chan.org") ) {
            var selected_board  = '';
            var selected_thread = '';

            var possible_boards = sfw_boards;
            if( options["includeNsfwResults"] ) {
                possible_boards = sfw_boards.concat( nsfw_boards );
            }

            var excludeBoardsFormatted = $.map( options["excludedBoards"].split(','), $.trim );
            possible_boards = $( possible_boards ).not( excludeBoardsFormatted ).get();

            if( possible_boards.length == 0 ) {
                $.unblockUI();
                return true;
            }

            selected_board = get_random_index( possible_boards );

            $.getJSON( "https://a.4cdn.org/" + selected_board + "/threads.json", function( data ) {
                var selected_page = get_random_index( data );
                selected_thread   = get_random_index( selected_page.threads ).no;

                window.location = 'https://boards.4chan.org/' + selected_board + '/thread/' + selected_thread;
            })
            .fail(function() {
                $.unblockUI();
            });
        }
        else {
            window.location = 'https://www.reddit.com/r/' +
                ( ( options["includeNsfwResults"] && Math.random() < 0.5 ) ? 'randnsfw' : 'random' );
        }
    });
}

chrome.storage.onChanged.addListener(function(changes, namespace) {
    for (key in changes) {
        var storageChange = changes[key];

        options[ key ] = storageChange.newValue;

        if( key == "hotkeyInformation" ) {
            key_handler.unbind();
            init_handler();
        }
    }
});

chrome.storage.local.get({
    hotkeyInformation           : {},
    showLoadingDialog           : true,
    isActivated                 : true,
    includeNsfwResults          : false,
    excludedBoards              : ''
}, function ( items ) {
    for( key in items ) {
        options[ key ] = items[ key ];
    }

    init_handler( );
});

<|endoftext|>