<commit_before>const fetch = require('node-fetch');
const cheerio = require('cheerio');

module.exports = class Lyricist {
  constructor(accessToken) {
    if (!accessToken) throw new Error('No access token provided to lyricist!');
    this.accessToken = accessToken;
  }

  /*
  Main request function
  */

  async _request(path) {
    const url = `https://api.genius.com/${path}`;
    const headers = {
      'Authorization': `Bearer ${this.accessToken}`,
    };
    const { meta, response } = await fetch(url, { headers })
      .then(response => response.json());

    if (meta.status !== 200) {
      throw new Error(`${meta.status}: ${meta.message}`);
    }
    return response;
  }

  /*
  Search song by ID
  */

  async song(id, { fetchLyrics = 123 } = {}) {
    if (!id) throw new Error('No ID was provided to lyricist.song()');

    const { song } = await this._request(`songs/${id}`);

    const lyrics = fetchLyrics ? await this._scrapeLyrics(song.url) : null;

    return Object.assign({ lyrics }, song);
  }

  /*
  Get album by ID
  */

  async album(id, { fetchTracklist = false } = {}) {
    if (!id) throw new Error('No ID was provided to lyricist.album()');

    const { album } = await this._request(`albums/${id}`);

    const tracklist = fetchTracklist ? await this._scrapeTracklist(album.url) : null;

    return Object.assign({ tracklist }, album);
  }

  /* Get artist */

  async artist(id, opts) {
    if (!id) throw new Error('No ID was provided to lyricist.artist()');
    const { artist } = await this._request(`artists/${id}`);
    return artist;
  }

  /* Get artist songs */

  async songsByArtist(id, { page = 1, perPage = 20, sort = 'title' } = {}) {
    if (!id) throw new Error('No ID was provided to lyricist.songsByArtist()');
    const { songs } = await this._request(
      `artists/${id}/songs?per_page=${perPage}&page=${page}&sort=${sort}`
    );
    return songs;
  }

  async search(query) {
    if (!query) throw new Error('No query was provided to lyricist.search()');
    const response = await this._request(`search?q=${query}`);
    return response.hits.map(hit => hit.result);
  }

  /*
  Scrape tracklist
  */

  async _scrapeTracklist(url) {
    const html = await fetch(url).then(res => res.text());
    const $ = cheerio.load(html);
    const json = $('meta[itemprop="page_data"]').attr('content');
    const parsed = JSON.parse(json);
    const songs = parsed.album_appearances;
    return songs.map(({ song, track_number }) =>
      Object.assign({ track_number }, song)
    );
  }

  /* Scrape song lyrics */

  async _scrapeLyrics(url) {
    const response = await fetch(url);
    const text = await response.text();
    const $ = cheerio.load(text);
    return $('.lyrics').text().trim();
  }
}
<commit_msg>fixed code<commit_after>const fetch = require('node-fetch');
const cheerio = require('cheerio');

module.exports = class Lyricist {
  constructor(accessToken) {
    if (!accessToken) throw new Error('No access token provided to lyricist!');
    this.accessToken = accessToken;
  }

  /*
  Main request function
  */

  async _request(path) {
    const url = `https://api.genius.com/${path}`;
    const headers = {
      'Authorization': `Bearer ${this.accessToken}`,
    };
    const { meta, response } = await fetch(url, { headers })
      .then(response => response.json());

    if (meta.status !== 200) {
      throw new Error(`${meta.status}: ${meta.message}`);
    }
    return response;
  }

  /*
  Search song by ID
  */

  async song(id, { fetchLyrics = false } = {}) {
    if (!id) throw new Error('No ID was provided to lyricist.song()');

    const { song } = await this._request(`songs/${id}`);

    const lyrics = fetchLyrics ? await this._scrapeLyrics(song.url) : null;

    return Object.assign({ lyrics }, song);
  }

  /*
  Get album by ID
  */

  async album(id, { fetchTracklist = false } = {}) {
    if (!id) throw new Error('No ID was provided to lyricist.album()');

    const { album } = await this._request(`albums/${id}`);

    const tracklist = fetchTracklist ? await this._scrapeTracklist(album.url) : null;

    return Object.assign({ tracklist }, album);
  }

  /* Get artist */

  async artist(id, opts) {
    if (!id) throw new Error('No ID was provided to lyricist.artist()');
    const { artist } = await this._request(`artists/${id}`);
    return artist;
  }

  /* Get artist songs */

  async songsByArtist(id, { page = 1, perPage = 20, sort = 'title' } = {}) {
    if (!id) throw new Error('No ID was provided to lyricist.songsByArtist()');
    const { songs } = await this._request(
      `artists/${id}/songs?per_page=${perPage}&page=${page}&sort=${sort}`
    );
    return songs;
  }

  async search(query) {
    if (!query) throw new Error('No query was provided to lyricist.search()');
    const response = await this._request(`search?q=${query}`);
    return response.hits.map(hit => hit.result);
  }

  /*
  Scrape tracklist
  */

  async _scrapeTracklist(url) {
    const html = await fetch(url).then(res => res.text());
    const $ = cheerio.load(html);
    const json = $('meta[itemprop="page_data"]').attr('content');
    const parsed = JSON.parse(json);
    const songs = parsed.album_appearances;
    return songs.map(({ song, track_number }) =>
      Object.assign({ track_number }, song)
    );
  }

  /* Scrape song lyrics */

  async _scrapeLyrics(url) {
    const response = await fetch(url);
    const text = await response.text();
    const $ = cheerio.load(text);
    return $('.lyrics').text().trim();
  }
}
<|endoftext|>


<commit_before>
/**
 * Vantage extension which exposes
 * the command `hacker-news`. This pulls
 * the top entries from hacker news.
 */

/**
 * Module dependencies.
 */

var colors = require('colors')
  , _ = require('lodash')
  , request = require('request')
  , moment = require("moment")
  ;

module.exports = function(vantage, options) {

  vantage
    .command("hacker-news", "Lists the top stories on hacker news.")
    .option("-l, --length [amt]", "Limits the list to a given length.")
    .action(function(args, cb){
      var length = args.options.length;
      length = (isNaN(length)) ? 3 : length;
      console.log('\n  Pulling top ' + length + " stories on Hacker News:\n")
      getTopStories(length, function(err, data){
        if (!err) {
          getStories(data, function(err, data){
            if (!err) {
              data = data.sort(function(a, b){
                return (a.rank > b.rank) ? 1 : -1;
              })
              for (var i = 0; i < data.length; ++i) {
                var s = data[i];
                var url = String(s.url).split('//');
                url = (url.length > 1) ? url[1] : s.url;
                url = String(url).split('/')[0];
                url = String(url).split('.');
                url.shift();
                url = url.join(".");
                var str = String("  " + (i+1) + ". ")
                  + String(s.title).white
                  + String(" (" + url + ")")
                  + "\n     "
                  + "" + s.score + " points by " + s.by + " " + moment(parseFloat(s.time) * 1000).fromNow() + " | " + s.descendants + " comments"
                  + "\n     "
                  ;
                str = str.replace(/’/g, "").replace(/`/g, "").replace(/‘/g, "");
                console.log(str);
              }
              cb();
            } else {
              console.error("Error getting stories: " + err);
            }
          })
        } else {
          console.error("Error getting top stories: " + err);
        }
      });
    });

}

function getStory(id, rank, callback) {
  var url = "https://hacker-news.firebaseio.com/v0/item/" + id + ".json?";
  request.get(url, {json: true, body: {}}, function(err, res, body) {
    if (!err && res.statusCode === 200) {
      body.rank = rank;
      callback(void 0, body);
    } else {
      callback(true, 'Error getting story: ' + err);
    }
  });
}

function getStories(stories, callback) {
  var error = false;
  var results = [];
  var total = stories.length;
  var done = 0;

  function handler() {
    done++;
    if (total == done) {
      if (error !== false) {
        callback(true, error);
      } else {
        callback(void 0, results);
      }
    }
  }

  for (var i = 0; i < stories.length; ++i) {
    getStory(stories[i], (i+1), function(err, data) {
      if (err) {
        error = data;
      } else {
        results.push(data);
      }
      handler();
    });
  }
}

function getTopStories(amt, callback) {
  amt = amt || 5;
  var url = "https://hacker-news.firebaseio.com/v0/topstories.json?";
  request.get(url, {json: true, body: {}}, function(err, res, body) {
    if (!err && res.statusCode === 200) {
      var sliced = body.slice(0, amt);
      callback(void 0, sliced);
    } else {
      callback(true, 'Error getting top stories: ' + err);
    }
  });
}<commit_msg>fixed logging<commit_after>
/**
 * Vantage extension which exposes
 * the command `hacker-news`. This pulls
 * the top entries from hacker news.
 */

/**
 * Module dependencies.
 */

var colors = require('colors')
  , _ = require('lodash')
  , request = require('request')
  , moment = require("moment")
  ;

module.exports = function(vantage, options) {

  vantage
    .command("hacker-news", "Lists the top stories on hacker news.")
    .option("-l, --length [amt]", "Limits the list to a given length.")
    .action(function(args, cb){
      var self = this;
      var length = args.options.length;
      length = (isNaN(length)) ? 3 : length;
      self.log('\n  Pulling top ' + length + " stories on Hacker News:\n")
      getTopStories(length, function(err, data){
        if (!err) {
          getStories(data, function(err, data){
            if (!err) {
              var result = "";
              data = data.sort(function(a, b){
                return (a.rank > b.rank) ? 1 : -1;
              })
              for (var i = 0; i < data.length; ++i) {
                var s = data[i];
                var url = String(s.url).split('//');
                url = (url.length > 1) ? url[1] : s.url;
                url = String(url).split('/')[0];
                url = String(url).split('.');
                url.shift();
                url = url.join(".");
                var str = String("  " + (i+1) + ". ")
                  + String(s.title).white
                  + String(" (" + url + ")")
                  + "\n     "
                  + "" + s.score + " points by " + s.by + " " + moment(parseFloat(s.time) * 1000).fromNow() + " | " + s.descendants + " comments"
                  + "\n     "
                  ;
                str = str.replace(/’/g, "").replace(/`/g, "").replace(/‘/g, "");
                result = result + str + "\n";
                self.log(str);
              }
              cb(void 0, result);
            } else {
              console.error("Error getting stories: " + err);
              cb("Error getting stories: " + err);
            }
          })
        } else {
          console.error("Error getting top stories: " + err);
          cb("Error getting stories: " + err);
        }
      });
    });

}

function getStory(id, rank, callback) {
  var url = "https://hacker-news.firebaseio.com/v0/item/" + id + ".json?";
  request.get(url, {json: true, body: {}}, function(err, res, body) {
    if (!err && res.statusCode === 200) {
      body.rank = rank;
      callback(void 0, body);
    } else {
      callback(true, 'Error getting story: ' + err);
    }
  });
}

function getStories(stories, callback) {
  var error = false;
  var results = [];
  var total = stories.length;
  var done = 0;

  function handler() {
    done++;
    if (total == done) {
      if (error !== false) {
        callback(true, error);
      } else {
        callback(void 0, results);
      }
    }
  }

  for (var i = 0; i < stories.length; ++i) {
    getStory(stories[i], (i+1), function(err, data) {
      if (err) {
        error = data;
      } else {
        results.push(data);
      }
      handler();
    });
  }
}

function getTopStories(amt, callback) {
  amt = amt || 5;
  var url = "https://hacker-news.firebaseio.com/v0/topstories.json?";
  request.get(url, {json: true, body: {}}, function(err, res, body) {
    if (!err && res.statusCode === 200) {
      var sliced = body.slice(0, amt);
      callback(void 0, sliced);
    } else {
      callback(true, 'Error getting top stories: ' + err);
    }
  });
}<|endoftext|>


<commit_before>describe('sap.m.QuickView', function() {

	// initial loading
	it('should load test page', function () {
		expect(takeScreenshot()).toLookAs('0_initial');
	});

	// standard
	it('should visualize standard QuickView', function () {
		element(by.id('QVButton')).click();
		var qv1 = element(by.id('QV1-quickView-popover'));
		expect(takeScreenshot(qv1)).toLookAs('1_standard_QuickView');
		expect(takeScreenshot()).toLookAs('1_standard_entire_page');
	});

	// go to page 2
	it('should go to page 2', function () {
		element(by.id('__link2')).click();
		var qv1 = element(by.id('QV1-quickView-popover'));
		expect(takeScreenshot(qv1)).toLookAs('2_go_to_page_2');
	});

	// return to page 1
	it('should return to page 1', function () {
	 element(by.id('__button3-iconBtn')).click();
	 var qv1 = element(by.id('QV1-quickView-popover'));
	 expect(takeScreenshot(qv1)).toLookAs('3_return_to_page_1');
	 });

	// empty QuickView
	it('should open empty QuickView', function () {
		element(by.id('EmptyQVButton')).click();
		expect(takeScreenshot()).toLookAs('4_empty');
	});

	// single page
	it('should visualize QuickView with single page', function () {
		element(by.id('SinglePageQVButton')).click();
		var qv2 = element(by.id('QV2-quickView-popover'));
		expect(takeScreenshot(qv2)).toLookAs('5_single_page_QuickView');
		expect(takeScreenshot()).toLookAs('5_single_page_entire_page');
	});

});<commit_msg>[INTERNAL] QuickView: Deleted odd visual test<commit_after>describe('sap.m.QuickView', function() {

	// initial loading
	it('should load test page', function () {
		expect(takeScreenshot()).toLookAs('0_initial');
	});

	// standard
	it('should visualize standard QuickView', function () {
		element(by.id('QVButton')).click();
		var qv1 = element(by.id('QV1-quickView-popover'));
		expect(takeScreenshot(qv1)).toLookAs('1_standard_QuickView');
		expect(takeScreenshot()).toLookAs('1_standard_entire_page');
	});

	// go to page 2
	it('should go to page 2', function () {
		element(by.id('__link2')).click();
		var qv1 = element(by.id('QV1-quickView-popover'));
		expect(takeScreenshot(qv1)).toLookAs('2_go_to_page_2');
	});

	// return to page 1
	it('should return to page 1', function () {
		element(by.id('__button3-iconBtn')).click();
		var qv1 = element(by.id('QV1-quickView-popover'));
		expect(takeScreenshot(qv1)).toLookAs('3_return_to_page_1');
	 });

	// single page
	it('should visualize QuickView with single page', function () {
		element(by.id('SinglePageQVButton')).click();
		var qv2 = element(by.id('QV2-quickView-popover'));
		expect(takeScreenshot(qv2)).toLookAs('5_single_page_QuickView');
		expect(takeScreenshot()).toLookAs('5_single_page_entire_page');
	});

});<|endoftext|>


<commit_before>var del = require('del');
var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();
var runSequence = require('run-sequence');

/**
 * Paths
 */
var bowerFolder = "bower_components/";
var destFolder = "public/";
var srcFolder = "assets/";

/**
 * Clean all destination folders
 */
gulp.task('clean', function(cb) {
	return del([
		destFolder + '_js',
		destFolder + '_css',
		destFolder + '_img',
		destFolder + '_fonts',
		destFolder + '_ng-partials',
		destFolder + '_data'
	], cb)

	return gulp.pipe( plugins.if( isMac, plugins.notify('Clean task complete') ) );
});

/**
 * Clean destination folders during development.
 * This does not clean the vendor folder.
 */
gulp.task('clean-dev', function(cb) {
	return del([
		destFolder + '_js/site',
		destFolder + '_css',
		destFolder + '_img',
		destFolder + '_fonts',
		destFolder + '_ng-partials',
		destFolder + '_data'
	], cb)

	return gulp.pipe( plugins.if( isMac, plugins.notify('Clean (dev) task complete') ) );
});

/**
 * Install Bower components
 */
gulp.task('bower', function() {
  	return plugins.bower();
});

/**
 * Css generation
 */
gulp.task('styles', function() {
	return gulp
			.src(srcFolder + 'sass/style.scss')
			.pipe(plugins.sass({ errLogToConsole: true }))
			.pipe(plugins.plumber())
			.pipe(plugins.autoprefixer({
				browsers: ['last 2 versions', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4']
			}))
			.pipe(gulp.dest(destFolder + '_css/'))
			.pipe(plugins.minifyCss({ keepSpecialComments: 0 }))
			.pipe(plugins.rename({ extname: '.min.css' }))
			.pipe(gulp.dest(destFolder + '_css/'));
});

/**
 * Vendor scripts
 */
gulp.task('vendor-scripts', ['bower'], function() {
  return gulp
  			.src([
  				bowerFolder + 'angular/angular.min.js'
  			])
			.pipe(plugins.plumber())
			.pipe(plugins.concat('vendor.js'))
			.pipe(gulp.dest(destFolder + '_js/vendor/'))
			.pipe(plugins.uglify())
			.pipe(plugins.rename({suffix: '.min'}))
			.pipe(gulp.dest(destFolder + '_js/vendor/'));
});

/**
 * Main site scripts
 */
gulp.task('scripts', function() {
  return gulp
  			.src([
  				srcFolder + 'js/**/*.js'
  			])
			.pipe(plugins.plumber())
			.pipe(plugins.jshint())
			.pipe(plugins.jshint.reporter('default'))
			.pipe(plugins.concat('site.js'))
			.pipe(gulp.dest(destFolder + '_js/site/'))
			.pipe(plugins.uglify())
			.pipe(plugins.rename({suffix: '.min'}))
			.pipe(gulp.dest(destFolder + '_js/site/'));
});

/**
 * Copy images from src to dest
 */
gulp.task('copy-images', function() {
  return gulp
  			.src(srcFolder + 'img/**/*')
			.pipe(gulp.dest(destFolder + '_img'));
});

/**
 * Copy fonts from src to dest
 */
gulp.task('copy-fonts', function() {
  return gulp
  			.src(srcFolder + 'fonts/**/*')
			.pipe(gulp.dest(destFolder + '_fonts'));
});

/**
 * Copy angular partials from src to dest
 */
gulp.task('copy-ng-partials', function() {
	return gulp
			.src(srcFolder + 'ng-partials/**/*')
			.pipe(gulp.dest(destFolder + '_ng-partials'));
});

/**
 * Copy data files from src to dest
 */
gulp.task('copy-data', function() {
	return gulp
			.src(srcFolder + 'data/**/*')
			.pipe(gulp.dest(destFolder + '_data'));
});

/**
 * Watch various files and run appropriate task
 */
gulp.task('watch', function() {
	// Watch this file
	gulp.watch('gulpfile.js', ['dev']);

	// Watch .scss files
	gulp.watch(srcFolder + 'scss/**/*.scss', ['styles']);

	// Watch .js files
	gulp.watch(srcFolder + 'js/**/*.js', ['scripts']);

	// Watch Angular partials
	gulp.watch(srcFolder + 'ng-partials/**/*.html', ['copy-ng-partials']);

	// Watch image files
	gulp.watch(srcFolder + 'img/**/*', ['copy-images']);

	// Watch font files
	gulp.watch(srcFolder + 'fonts/**/*', ['copy-fonts']);

	// Watch data files
	gulp.watch(srcFolder + 'data/**/*', ['copy-data']);

	// Watch bower files
	gulp.watch('bower.json', ['vendor-scripts']);

});

/**
 * Default task. Runs all other tasks.
 */
gulp.task('default', ['clean'], function() {
	return runSequence('vendor-scripts', 'scripts', 'styles', 'copy-images', 'copy-fonts', 'copy-ng-partials', 'copy-data');
});

/**
 * Run this during development as does not run bower each time.
 * Requires 'vendor-scripts' task to have been run once first.
 */
gulp.task('dev', ['clean-dev'], function() {
	return runSequence('scripts', 'styles', 'copy-images', 'copy-fonts', 'copy-ng-partials', 'copy-data');
});
<commit_msg>style(gulp): convert tabs to spaces<commit_after>var del = require('del');
var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();
var runSequence = require('run-sequence');

/**
 * Paths
 */
var bowerFolder = "bower_components/";
var destFolder = "public/";
var srcFolder = "assets/";

/**
 * Clean all destination folders
 */
gulp.task('clean', function(cb) {
    return del([
        destFolder + '_js',
        destFolder + '_css',
        destFolder + '_img',
        destFolder + '_fonts',
        destFolder + '_ng-partials',
        destFolder + '_data'
    ], cb)

    return gulp.pipe( plugins.if( isMac, plugins.notify('Clean task complete') ) );
});

/**
 * Clean destination folders during development.
 * This does not clean the vendor folder.
 */
gulp.task('clean-dev', function(cb) {
    return del([
        destFolder + '_js/site',
        destFolder + '_css',
        destFolder + '_img',
        destFolder + '_fonts',
        destFolder + '_ng-partials',
        destFolder + '_data'
    ], cb)

    return gulp.pipe( plugins.if( isMac, plugins.notify('Clean (dev) task complete') ) );
});

/**
 * Install Bower components
 */
gulp.task('bower', function() {
    return plugins.bower();
});

/**
 * Css generation
 */
gulp.task('styles', function() {
    return gulp
            .src(srcFolder + 'sass/style.scss')
            .pipe(plugins.sass({ errLogToConsole: true }))
            .pipe(plugins.plumber())
            .pipe(plugins.autoprefixer({
                browsers: ['last 2 versions', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4']
            }))
            .pipe(gulp.dest(destFolder + '_css/'))
            .pipe(plugins.minifyCss({ keepSpecialComments: 0 }))
            .pipe(plugins.rename({ extname: '.min.css' }))
            .pipe(gulp.dest(destFolder + '_css/'));
});

/**
 * Vendor scripts
 */
gulp.task('vendor-scripts', ['bower'], function() {
  return gulp
            .src([
                bowerFolder + 'angular/angular.min.js'
            ])
            .pipe(plugins.plumber())
            .pipe(plugins.concat('vendor.js'))
            .pipe(gulp.dest(destFolder + '_js/vendor/'))
            .pipe(plugins.uglify())
            .pipe(plugins.rename({suffix: '.min'}))
            .pipe(gulp.dest(destFolder + '_js/vendor/'));
});

/**
 * Main site scripts
 */
gulp.task('scripts', function() {
  return gulp
            .src([
                srcFolder + 'js/**/*.js'
            ])
            .pipe(plugins.plumber())
            .pipe(plugins.jshint())
            .pipe(plugins.jshint.reporter('default'))
            .pipe(plugins.concat('site.js'))
            .pipe(gulp.dest(destFolder + '_js/site/'))
            .pipe(plugins.uglify())
            .pipe(plugins.rename({suffix: '.min'}))
            .pipe(gulp.dest(destFolder + '_js/site/'));
});

/**
 * Copy images from src to dest
 */
gulp.task('copy-images', function() {
  return gulp
            .src(srcFolder + 'img/**/*')
            .pipe(gulp.dest(destFolder + '_img'));
});

/**
 * Copy fonts from src to dest
 */
gulp.task('copy-fonts', function() {
  return gulp
            .src(srcFolder + 'fonts/**/*')
            .pipe(gulp.dest(destFolder + '_fonts'));
});

/**
 * Copy angular partials from src to dest
 */
gulp.task('copy-ng-partials', function() {
    return gulp
            .src(srcFolder + 'ng-partials/**/*')
            .pipe(gulp.dest(destFolder + '_ng-partials'));
});

/**
 * Copy data files from src to dest
 */
gulp.task('copy-data', function() {
    return gulp
            .src(srcFolder + 'data/**/*')
            .pipe(gulp.dest(destFolder + '_data'));
});

/**
 * Watch various files and run appropriate task
 */
gulp.task('watch', function() {
    // Watch this file
    gulp.watch('gulpfile.js', ['dev']);

    // Watch .scss files
    gulp.watch(srcFolder + 'scss/**/*.scss', ['styles']);

    // Watch .js files
    gulp.watch(srcFolder + 'js/**/*.js', ['scripts']);

    // Watch Angular partials
    gulp.watch(srcFolder + 'ng-partials/**/*.html', ['copy-ng-partials']);

    // Watch image files
    gulp.watch(srcFolder + 'img/**/*', ['copy-images']);

    // Watch font files
    gulp.watch(srcFolder + 'fonts/**/*', ['copy-fonts']);

    // Watch data files
    gulp.watch(srcFolder + 'data/**/*', ['copy-data']);

    // Watch bower files
    gulp.watch('bower.json', ['vendor-scripts']);

});

/**
 * Default task. Runs all other tasks.
 */
gulp.task('default', ['clean'], function() {
    return runSequence('vendor-scripts', 'scripts', 'styles', 'copy-images', 'copy-fonts', 'copy-ng-partials', 'copy-data');
});

/**
 * Run this during development as does not run bower each time.
 * Requires 'vendor-scripts' task to have been run once first.
 */
gulp.task('dev', ['clean-dev'], function() {
    return runSequence('scripts', 'styles', 'copy-images', 'copy-fonts', 'copy-ng-partials', 'copy-data');
});
<|endoftext|>


<commit_before>var bodyParser = require('body-parser');
var normalize = require('path').normalize;
var spawn = require('child_process').spawn;
var express = require('express');

module.exports = function (ref, action) {

  // create express instance
  var hookshot = express();

  // middleware
  hookshot.use(bodyParser.urlencoded({ extended: false }));
  hookshot.use(bodyParser.json());

  // main POST handler
  hookshot.post('/', function (req, res, next) {
    var payload = req.body;
    if (typeof payload.payload != 'undefined') {
      payload = JSON.parse(payload.payload);
    }
    // GitHub send an initial ping on webhook creation, detect it by looking for `hook_id`
    // Send a 200 response and stop further execution of this script.
    if (typeof payload.hook_id == 'number') {
      res.send(200, 'OK');
      return false;
    }
    if (typeof payload.ref != 'string') {
      throw new Error('payload.ref is not string. It is:', payload.ref);
    }
    if (payload.created) {
      hookshot.emit('create', payload);
    } else if (payload.deleted) {
      hookshot.emit('delete', payload);
    } else {
      hookshot.emit('push', payload);
    }
    hookshot.emit('hook', payload);
    hookshot.emit(payload.ref, payload);
    res.send(202, 'Accepted\n');
  });

  if (arguments.length == 1) {
    action = ref;
    ref = 'hook';
  }

  if (typeof action == 'string') {
    var shell = process.env.SHELL;
    var args = ['-c', action];
    var opts = { stdio: 'inherit' };
    if (shell && isCygwin()) {
      shell = cygpath(shell);
    } else if (isWin()) {
      shell = process.env.ComSpec;
      args = ['/s', '/c', '"' + action + '"'];
      opts.windowsVerbatimArguments = true;
    }

    hookshot.on(ref, function(payload) {
      // shell command
      spawn(shell, args, opts);
    });
  } else if (typeof action == 'function') {
    hookshot.on(ref, action);
  }

  return hookshot;
};

/**
 * Returns `true` if node is currently running on Windows, `false` otherwise.
 *
 * @return {Boolean}
 * @api private
 */

function isWin () {
  return 'win32' == process.platform;
}

/**
 * Returns `true` if node is currently running from within a "cygwin" environment.
 * Returns `false` otherwise.
 *
 * @return {Boolean}
 * @api private
 */

function isCygwin () {
  // TODO: implement a more reliable check here...
  return isWin() && /cygwin/i.test(process.env.HOME);
}

/**
 * Convert a Unix-style Cygwin path (i.e. "/bin/bash") to a Windows-style path
 * (i.e. "C:\cygwin\bin\bash").
 *
 * @param {String} path
 * @return {String}
 * @api private
 */

function cygpath (path) {
  path = normalize(path);
  if (path[0] == '\\') {
    // TODO: implement better cygwin root detection...
    path = 'C:\\cygwin' + path;
  }
  return path;
}
<commit_msg>Better error reporting<commit_after>var bodyParser = require('body-parser');
var normalize = require('path').normalize;
var spawn = require('child_process').spawn;
var express = require('express');

module.exports = function (ref, action) {

  // create express instance
  var hookshot = express();

  // middleware
  hookshot.use(bodyParser.urlencoded({ extended: false }));
  hookshot.use(bodyParser.json());

  // main POST handler
  hookshot.post('/', function (req, res, next) {
    var payload = req.body;
    if (typeof payload.payload != 'undefined') {
      payload = JSON.parse(payload.payload);
    }
    // GitHub send an initial ping on webhook creation, detect it by looking for `hook_id`
    // Send a 200 response and stop further execution of this script.
    if (typeof payload.hook_id == 'number') {
      res.send(200, 'OK');
      return false;
    }
    if (typeof payload.ref != 'string') {
      console.log('payload.ref error:', payload.ref)
      throw new Error('payload.ref is not string.');
    }
    if (payload.created) {
      hookshot.emit('create', payload);
    } else if (payload.deleted) {
      hookshot.emit('delete', payload);
    } else {
      hookshot.emit('push', payload);
    }
    hookshot.emit('hook', payload);
    hookshot.emit(payload.ref, payload);
    res.send(202, 'Accepted\n');
  });

  if (arguments.length == 1) {
    action = ref;
    ref = 'hook';
  }

  if (typeof action == 'string') {
    var shell = process.env.SHELL;
    var args = ['-c', action];
    var opts = { stdio: 'inherit' };
    if (shell && isCygwin()) {
      shell = cygpath(shell);
    } else if (isWin()) {
      shell = process.env.ComSpec;
      args = ['/s', '/c', '"' + action + '"'];
      opts.windowsVerbatimArguments = true;
    }

    hookshot.on(ref, function(payload) {
      // shell command
      spawn(shell, args, opts);
    });
  } else if (typeof action == 'function') {
    hookshot.on(ref, action);
  }

  return hookshot;
};

/**
 * Returns `true` if node is currently running on Windows, `false` otherwise.
 *
 * @return {Boolean}
 * @api private
 */

function isWin () {
  return 'win32' == process.platform;
}

/**
 * Returns `true` if node is currently running from within a "cygwin" environment.
 * Returns `false` otherwise.
 *
 * @return {Boolean}
 * @api private
 */

function isCygwin () {
  // TODO: implement a more reliable check here...
  return isWin() && /cygwin/i.test(process.env.HOME);
}

/**
 * Convert a Unix-style Cygwin path (i.e. "/bin/bash") to a Windows-style path
 * (i.e. "C:\cygwin\bin\bash").
 *
 * @param {String} path
 * @return {String}
 * @api private
 */

function cygpath (path) {
  path = normalize(path);
  if (path[0] == '\\') {
    // TODO: implement better cygwin root detection...
    path = 'C:\\cygwin' + path;
  }
  return path;
}
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');

var libpath = process.env.TEST_COV ? '../lib-cov/' : '../lib/';
var detector = require(libpath + 'detector');

var handlers = {};
['png', 'gif', 'bmp', 'psd', 'jpg', 'webp'].forEach(function (type) {
  handlers[type] = require(libpath + 'types/' + type);
});

function lookup (buffer) {
  // detect the file type.. don't rely on the extension
  var type = detector(buffer);

  if (type in handlers) {
    return handlers[type](buffer);
  } else {
    throw new TypeError('unsupported file type');
  }
}

/**
 * @params filepath - relative/absolute path of the image file
 * @params callback - optional function for async detection
 */
module.exports = function (filepath, callback) {

  // resolve the file path
  filepath = path.resolve(filepath);

  // create a buffer to read data in
  var buffer = new Buffer(1024);

  if (typeof callback === 'function') {
    // read first 1KB from the file, asynchronously
    fs.open(filepath, 'r', function (err, descriptor) {

      if (err) {
        return callback(err);
      }

      fs.read(descriptor, buffer, 0, 1024, 0, function (err) {
        if (err) {
          return callback(err);
        }

        // return the dimensions
        var dimensions = lookup(buffer);
        callback(null, dimensions);
      });
    });
  } else {
    // read first 1KB from the file, synchronously
    var descriptor = fs.openSync(filepath, 'r');
    fs.readSync(descriptor, buffer, 0, 1024, 0);

    // return the dimensions
    return lookup(buffer);
  }
};
<commit_msg>ADDED: buffer size is now based on constant kBufferSize<commit_after>var fs = require('fs');
var path = require('path');

var libpath = process.env.TEST_COV ? '../lib-cov/' : '../lib/';
var detector = require(libpath + 'detector');

var handlers = {};
['png', 'gif', 'bmp', 'psd', 'jpg', 'webp'].forEach(function (type) {
  handlers[type] = require(libpath + 'types/' + type);
});

var kBufferSize = 4096; /**< MADE: maximum buffer size, with a default of 4096 bytes. */

function lookup (buffer) {
  // detect the file type.. don't rely on the extension
  var type = detector(buffer);

  if (type in handlers) {
    return handlers[type](buffer);
  } else {
    throw new TypeError('unsupported file type');
  }
}

/**
 * @params filepath - relative/absolute path of the image file
 * @params callback - optional function for async detection
 */
module.exports = function (filepath, callback) {

  // resolve the file path
  filepath = path.resolve(filepath);

  // create a buffer to read data in
  var buffer = new Buffer(kBufferSize);

  if (typeof callback === 'function') {
    // read first buffer block from the file, asynchronously
    fs.open(filepath, 'r', function (err, descriptor) {

      if (err) {
        return callback(err);
      }

      fs.read(descriptor, buffer, 0, kBufferSize, 0, function (err) {
        if (err) {
          return callback(err);
        }

        // return the dimensions
        var dimensions = lookup(buffer);
        callback(null, dimensions);
      });
    });
  } else {
    // read first 1KB from the file, synchronously
    var descriptor = fs.openSync(filepath, 'r');
    fs.readSync(descriptor, buffer, 0, kBufferSize, 0);

    // return the dimensions
    return lookup(buffer);
  }
};
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var Sails = require('./app');

// Instantiate and expose a Sails singleton
// (maintains legacy support)
module.exports = new Sails();

// Expose constructor for convenience/tests
module.exports.Sails = Sails;

// To access the Sails app constructor, do:
// var Sails = require('sails').constructor;
// var newApp = new Sails();

// Or to get a factory method which generates new instances:
// var Sails = require('sails/lib/app');
// var newApp = Sails();
<commit_msg>Clarify that constructor usage should be used (rather than factory) in inline comments.  Accompanies https://github.com/balderdashy/sails-docs/commit/1c16ca7f01a79fd3b16bfeff92c8bb479b5c1803<commit_after>/**
 * Module dependencies
 */

var Sails = require('./app');

// Instantiate and expose a Sails singleton
// (maintains legacy support)
module.exports = new Sails();

// Expose constructor for convenience/tests
module.exports.Sails = Sails;

// To access the Sails app constructor, do:
// var Sails = require('sails').constructor;
// or:
// var Sails = require('sails').Sails;
//
// Then:
// var newApp = new Sails();
<|endoftext|>


<commit_before>const gulp = require('gulp');
const scgulp = require('showcar-gulp')(gulp);

// Don't put in separate task. Runs async on each gulp task
const pkg = require('showcar-gulp/package.json');
const updateNotifier = require('update-notifier');
updateNotifier({
    pkg,
    updateCheckInterval: 1 //check each time
}).notify({ defer: false, isGlobal: false });

gulp.task('js', ['eslint'], scgulp.js({
    entry: 'src/showcar-ui.js',
    out: 'dist/showcar-ui.js',
}));

gulp.task('icons', ['eslint'], scgulp.js({
    entry: 'src/js/showcar-icons.js',
    out: 'dist/showcar-icons.js',
}));

gulp.task('tracking', ['eslint'], scgulp.js({
    entry: 'src/js/showcar-tracking.js',
    out: 'dist/showcar-tracking.js',
}));

gulp.task('eslint', scgulp.eslint({
    files: 'src/**/*.js'
}));

gulp.task('stylelint', scgulp.stylelint({
    files: 'src/**/*.scss'
}));

gulp.task('scss', ['stylelint'], scgulp.scss({
    entry: 'src/showcar-ui.scss',
    out: 'dist/showcar-ui.css',
}));

gulp.task('clean', scgulp.clean({
    files: ['dist/**/*']
}));

gulp.task('serve', scgulp.serve({
    dir: 'dist'
}));

gulp.task('copy:fragments', () => {
    gulp.src('src/html/showcar-ui-fragment.html').pipe(gulp.dest('dist/'));
    gulp.src('src/html/showcar-ui-standalone-fragment.html').pipe(gulp.dest('dist/'));
    gulp.src('src/html/showcar-ui-toggled-fragment.html').pipe(gulp.dest('dist/'));
});

const fs = require('fs');
const UglifyJS = require('uglify-js');
const readFile = filename => fs.readFileSync(filename, 'utf-8');
const readJsFile = filename => UglifyJS.minify(readFile(filename), { fromString: true }).code;
const stringReplace = require('gulp-string-replace');
var replaceOptions = {
    logs: {
        enabled: false
    }
};
gulp.task('replace', function () {
    gulp.src(['src/html/index.html', 'src/html/index-standalone.html', 'docs/helpers/polyfills.js'])
        .pipe(stringReplace('@@POLYFILL_DOCUMENT_REGISTER_ELEMENT', readFile('node_modules/document-register-element/build/document-register-element.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_DOM4', readFile('node_modules/dom4/build/dom4.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_ARRAY', readJsFile('src/js/polyfills/array.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_OBJECT', readJsFile('src/js/polyfills/object.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_PROMISE', readJsFile('node_modules/promiz/promiz.min.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_FETCH', readJsFile('node_modules/whatwg-fetch/fetch.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_ES6_COLLECTIONS', readJsFile('node_modules/es6-collections/es6-collections.js'), replaceOptions))
        .pipe(stringReplace('@@SCRIPT_ERROR_COLLECTOR', readJsFile('src/js/inline-js/js-error-collector.js'), replaceOptions))
        .pipe(stringReplace('@@SCRIPT_FONT_LOADER', readJsFile('src/js/inline-js/font-loader.js'), replaceOptions))
        .pipe(gulp.dest('dist/'));
});

gulp.task('set-dev', () => {
    scgulp.config.devmode = true;
});

gulp.task('docs:generate', () => {
    require('./docs/tasks/generateJson')();
    require('./docs/tasks/generateHtml')();
});

const serveDocs = require('./docs/tasks/docs');

gulp.task('docs:serve', () => {serveDocs(gulp);});
gulp.task('docs:edit', ['build'], () => {serveDocs(gulp);});
gulp.task('docs:watch', ['build'], () => {serveDocs(gulp);});

gulp.task('build', ['js', 'icons', 'tracking', 'scss', 'copy:fragments', 'replace']);
gulp.task('default', ['docs:watch']);

const testingParams = {
    files: ['.quixoteconf.js'],
    preprocessors: {
        '.quixoteconf.js': ['webpack', 'sourcemap']
    },
    proxies: {
        '/': 'http://localhost:3000/',
    }
};

gulp.task('test', ['docs:serve'], scgulp.karma(
    Object.assign({}, testingParams, {
        browsers: ['Firefox', 'Chrome', 'Safari']
    }))
);

gulp.task('test:fast', ['docs:serve'], scgulp.karma(
    Object.assign({}, testingParams, {
        browsers: ['Chrome']
    }))
);

gulp.task('test:bs', ['docs:serve'], scgulp.karma(
    Object.assign({}, testingParams, {
        browserStack: {
            build: new Date().toLocaleString('de-DE', {
                hour12: false,
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit'
            }),
            project: 'Showcar-ui',
        },
        browsers: ['bs_safari_mac', 'bs_chrome_win', 'bs_firefox_win', 'bs_edge_win', 'bs_ie11_win', 'bs_iphone6s', 'bs_iphone7'],
    }))
);

gulp.task('test:travis', ['docs:serve'], scgulp.karma(
    Object.assign({}, testingParams, {
        browserStack: {
            project: 'Showcar-ui',
        },
        // browsers: ['bs_safari_mac', 'bs_chrome_win', 'bs_firefox_win', 'bs_edge_win', 'bs_ie11_win', 'bs_iphone6s', 'bs_iphone7'],
        // temporary removed iphones
        // browsers: ['bs_safari_mac', 'bs_chrome_win', 'bs_firefox_win', 'bs_edge_win', 'bs_ie11_win'],
        browsers: ['bs_chrome_win', 'bs_firefox_win', 'bs_edge_win', 'bs_ie11_win'],  //temporary remove safari
    }))
);
<commit_msg>only test on chrome<commit_after>const gulp = require('gulp');
const scgulp = require('showcar-gulp')(gulp);

// Don't put in separate task. Runs async on each gulp task
const pkg = require('showcar-gulp/package.json');
const updateNotifier = require('update-notifier');
updateNotifier({
    pkg,
    updateCheckInterval: 1 //check each time
}).notify({ defer: false, isGlobal: false });

gulp.task('js', ['eslint'], scgulp.js({
    entry: 'src/showcar-ui.js',
    out: 'dist/showcar-ui.js',
}));

gulp.task('icons', ['eslint'], scgulp.js({
    entry: 'src/js/showcar-icons.js',
    out: 'dist/showcar-icons.js',
}));

gulp.task('tracking', ['eslint'], scgulp.js({
    entry: 'src/js/showcar-tracking.js',
    out: 'dist/showcar-tracking.js',
}));

gulp.task('eslint', scgulp.eslint({
    files: 'src/**/*.js'
}));

gulp.task('stylelint', scgulp.stylelint({
    files: 'src/**/*.scss'
}));

gulp.task('scss', ['stylelint'], scgulp.scss({
    entry: 'src/showcar-ui.scss',
    out: 'dist/showcar-ui.css',
}));

gulp.task('clean', scgulp.clean({
    files: ['dist/**/*']
}));

gulp.task('serve', scgulp.serve({
    dir: 'dist'
}));

gulp.task('copy:fragments', () => {
    gulp.src('src/html/showcar-ui-fragment.html').pipe(gulp.dest('dist/'));
    gulp.src('src/html/showcar-ui-standalone-fragment.html').pipe(gulp.dest('dist/'));
    gulp.src('src/html/showcar-ui-toggled-fragment.html').pipe(gulp.dest('dist/'));
});

const fs = require('fs');
const UglifyJS = require('uglify-js');
const readFile = filename => fs.readFileSync(filename, 'utf-8');
const readJsFile = filename => UglifyJS.minify(readFile(filename), { fromString: true }).code;
const stringReplace = require('gulp-string-replace');
var replaceOptions = {
    logs: {
        enabled: false
    }
};
gulp.task('replace', function () {
    gulp.src(['src/html/index.html', 'src/html/index-standalone.html', 'docs/helpers/polyfills.js'])
        .pipe(stringReplace('@@POLYFILL_DOCUMENT_REGISTER_ELEMENT', readFile('node_modules/document-register-element/build/document-register-element.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_DOM4', readFile('node_modules/dom4/build/dom4.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_ARRAY', readJsFile('src/js/polyfills/array.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_OBJECT', readJsFile('src/js/polyfills/object.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_PROMISE', readJsFile('node_modules/promiz/promiz.min.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_FETCH', readJsFile('node_modules/whatwg-fetch/fetch.js'), replaceOptions))
        .pipe(stringReplace('@@POLYFILL_ES6_COLLECTIONS', readJsFile('node_modules/es6-collections/es6-collections.js'), replaceOptions))
        .pipe(stringReplace('@@SCRIPT_ERROR_COLLECTOR', readJsFile('src/js/inline-js/js-error-collector.js'), replaceOptions))
        .pipe(stringReplace('@@SCRIPT_FONT_LOADER', readJsFile('src/js/inline-js/font-loader.js'), replaceOptions))
        .pipe(gulp.dest('dist/'));
});

gulp.task('set-dev', () => {
    scgulp.config.devmode = true;
});

gulp.task('docs:generate', () => {
    require('./docs/tasks/generateJson')();
    require('./docs/tasks/generateHtml')();
});

const serveDocs = require('./docs/tasks/docs');

gulp.task('docs:serve', () => {serveDocs(gulp);});
gulp.task('docs:edit', ['build'], () => {serveDocs(gulp);});
gulp.task('docs:watch', ['build'], () => {serveDocs(gulp);});

gulp.task('build', ['js', 'icons', 'tracking', 'scss', 'copy:fragments', 'replace']);
gulp.task('default', ['docs:watch']);

const testingParams = {
    files: ['.quixoteconf.js'],
    preprocessors: {
        '.quixoteconf.js': ['webpack', 'sourcemap']
    },
    proxies: {
        '/': 'http://localhost:3000/',
    }
};

gulp.task('test', ['docs:serve'], scgulp.karma(
    Object.assign({}, testingParams, {
        browsers: ['Firefox', 'Chrome', 'Safari']
    }))
);

gulp.task('test:fast', ['docs:serve'], scgulp.karma(
    Object.assign({}, testingParams, {
        browsers: ['Chrome']
    }))
);

gulp.task('test:bs', ['docs:serve'], scgulp.karma(
    Object.assign({}, testingParams, {
        browserStack: {
            build: new Date().toLocaleString('de-DE', {
                hour12: false,
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit'
            }),
            project: 'Showcar-ui',
        },
        browsers: ['bs_safari_mac', 'bs_chrome_win', 'bs_firefox_win', 'bs_edge_win', 'bs_ie11_win', 'bs_iphone6s', 'bs_iphone7'],
    }))
);

gulp.task('test:travis', ['docs:serve'], scgulp.karma(
    Object.assign({}, testingParams, {
        browserStack: {
            project: 'Showcar-ui',
        },
        // browsers: ['bs_safari_mac', 'bs_chrome_win', 'bs_firefox_win', 'bs_edge_win', 'bs_ie11_win', 'bs_iphone6s', 'bs_iphone7'],
        // temporary removed iphones
        // browsers: ['bs_safari_mac', 'bs_chrome_win', 'bs_firefox_win', 'bs_edge_win', 'bs_ie11_win'],
        // browsers: ['bs_chrome_win', 'bs_firefox_win', 'bs_edge_win', 'bs_ie11_win'],  //temporary remove safari
        browsers: ['bs_chrome_win'], //only test on chrome
    }))
);
<|endoftext|>


<commit_before>const http = require('http');
const https = require('https');
const qs = require('qs');
const url = require('url');
const objectMerge = require('object-merge');

module.exports = function (baseUrl, mainOptions) {
	mainOptions = objectMerge({
		headers: { Accept: 'application/json' },
	}, mainOptions || {});

	return function (method, path, params, body, options) {
		const query = params ? '?' + qs.stringify(params) : '';
		const resolved = url.resolve(baseUrl, path + query);

		options = objectMerge(mainOptions, options || {});

		return makeRequest(method, resolved, body, options);
	};
};

function makeRequest(method, fullUrl, body, options) {
	const urlObj = url.parse(fullUrl);
	const headers = {};

	if (typeof body === 'object') {
		body = JSON.stringify(body);
		headers['Content-Type'] = 'application/json';
	}

	if (body)
		headers['Content-Length'] = Buffer.byteLength(body, 'utf8');

	options = objectMerge(options, {
		method: method,
		path: urlObj.path,
		hostname: urlObj.hostname,
		port: urlObj.port || (urlObj.protocol.startsWith('https') ? 443 : 80),
		headers: headers,
	});

	const proto = urlObj.protocol.startsWith('https') ? https : http;

	return new Promise(function (resolve, reject) {
		const request = proto.request(options);
		request.on('error', reject);

		if (body)
			request.end(body, 'utf8');
		else
			request.end();

		request.on('response', function (response) {
			var data = '';
			response.setEncoding('utf8');

			response.on('data', function (chunk) {
				data += chunk;
			});

			response.on('end', function () {
				var error;
				const code = response.statusCode;
				const codeFriendly = http.STATUS_CODES[code] || 'Unknown';
				const codeStr = codeFriendly.toLowerCase().replace(/\s+/g, '_');

				// do we need to catch 1xx codes?

				// 2xx - success
				if (code < 300) {
					if (!data || !data.length) {
						resolve(null);
						return;
					}

					try {
						data = JSON.parse(data);
					} catch (e) {
						error = new Error('invalid json');
						error.code = 'invalid_json';
						error.statusCode = code;
						error.meta = { httpStatus: code, data: data };
						reject(error);
						return;
					}

					resolve(data);
					return;
				}

				// 3xx - redirection
				// assumes that infinite loops won't happen
				if (code < 400) {
					switch (code) {
						case 304: // not modified
						case 305: // use proxy (not supported)
						case 306: // switch proxy (not supported)
							error = new Error('HTTP ' + code + ': ' + codeFriendly);
							error.code = codeStr;
							error.statusCode = code;
							error.meta = { httpStatus: code, data: data };
							reject(error);
							return;

						case 307: // temporary redirect - maintain method
						case 308: // permanent redirect - maintain method
							const newUrl = url.resolve(fullUrl, response.headers.location);
							makeRequest(method, newUrl, null, body, options)
							.then(resolve, reject);
							return;

						default: // redirect - change method to GET
							const newUrl = url.resolve(fullUrl, response.headers.location);
							makeRequest('get', newUrl, null, null, options)
							.then(resolve, reject);
							return;
					}
				}

				// 4xx 5xx - failure
				error = new Error('HTTP ' + code + ': ' + codeFriendly);
				error.code = codeStr;
				error.statusCode = code;
				error.meta = { httpStatus: code, data: data };

				try {
					const json = JSON.parse(data);

					if (typeof json !== 'object' || Array.isArray(json))
						throw new Error();

					if (typeof json.code === 'string') {
						Object.keys(json).forEach(function (key) {
							error[key] = json[key];
						});
					} else {
						error.meta = json;
					}
				} catch (e) {}

				reject(error);
			});
		});
	});
}
<commit_msg>Better use of promises<commit_after>const http = require('http');
const https = require('https');
const qs = require('qs');
const url = require('url');
const objectMerge = require('object-merge');

module.exports = function (baseUrl, mainOptions) {
	mainOptions = objectMerge({
		headers: { Accept: 'application/json' },
	}, mainOptions || {});

	return function (method, path, params, body, options) {
		const query = params ? '?' + qs.stringify(params) : '';
		const resolved = url.resolve(baseUrl, path + query);

		options = objectMerge(mainOptions, options || {});

		return makeRequest(method, resolved, body, options);
	};
};

function makeRequest(method, fullUrl, body, options) {
	const urlObj = url.parse(fullUrl);
	const headers = {};

	if (typeof body === 'object') {
		body = JSON.stringify(body);
		headers['Content-Type'] = 'application/json';
	}

	if (body)
		headers['Content-Length'] = Buffer.byteLength(body, 'utf8');

	options = objectMerge(options, {
		method: method,
		path: urlObj.path,
		hostname: urlObj.hostname,
		port: urlObj.port || (urlObj.protocol.startsWith('https') ? 443 : 80),
		headers: headers,
	});

	const proto = urlObj.protocol.startsWith('https') ? https : http;

	return new Promise(function (resolve, reject) {
		const request = proto.request(options);
		request.on('error', reject);

		if (body)
			request.end(body, 'utf8');
		else
			request.end();

		request.on('response', function (response) {
			var data = '';
			response.setEncoding('utf8');

			response.on('data', function (chunk) {
				data += chunk;
			});

			response.on('end', function () {
				response.body = data;
				resolve(response);
			});
		});
	})
	.then(function (response) {
		const data = response.data;
		const code = response.statusCode;

		const codeFriendly = http.STATUS_CODES[code] || 'Unknown';
		const codeStr = codeFriendly.toLowerCase().replace(/\s+/g, '_');

		// do we need to catch 1xx codes?

		// 2xx - success
		if (code < 300) {
			if (!data || !data.length)
				return null;

			try {
				return JSON.parse(data);
			} catch (e) {
				const error = new Error('invalid json');
				error.code = 'invalid_json';
				error.statusCode = code;
				error.meta = { httpStatus: code, data: data };
				throw error;
			}
		}

		// 3xx - redirection
		// assumes that infinite loops won't happen
		if (code < 400) {
			var newUrl;

			switch (code) {
				case 304: // not modified
				case 305: // use proxy (not supported)
				case 306: // switch proxy (not supported)
					const error = new Error('HTTP ' + code + ': ' + codeFriendly);
					error.code = codeStr;
					error.statusCode = code;
					error.meta = { httpStatus: code, data: data };
					throw error;

				case 307: // temporary redirect - maintain method
				case 308: // permanent redirect - maintain method
					newUrl = url.resolve(fullUrl, response.headers.location);
					return makeRequest(method, newUrl, null, body, options);

				default: // redirect - change method to GET
					newUrl = url.resolve(fullUrl, response.headers.location);
					return makeRequest('get', newUrl, null, null, options);
			}
		}

		// 4xx 5xx - failure
		const error = new Error('HTTP ' + code + ': ' + codeFriendly);
		error.code = codeStr;
		error.statusCode = code;
		error.meta = { httpStatus: code, data: data };

		try {
			const json = JSON.parse(data);

			if (typeof json !== 'object' || Array.isArray(json))
				throw new Error();

			if (typeof json.code === 'string') {
				Object.keys(json).forEach(function (key) {
					error[key] = json[key];
				});
			} else {
				error.meta = json;
			}
		} catch (e) {}

		throw error;
	});
}
<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.forceCheck = exports.lazyload = undefined;

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _event = require('./utils/event');

var _scrollParent = require('./utils/scrollParent');

var _scrollParent2 = _interopRequireDefault(_scrollParent);

var _debounce = require('./utils/debounce');

var _debounce2 = _interopRequireDefault(_debounce);

var _throttle = require('./utils/throttle');

var _throttle2 = _interopRequireDefault(_throttle);

var _decorator = require('./decorator');

var _decorator2 = _interopRequireDefault(_decorator);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
                                                                                * react-lazyload
                                                                                */

var defaultBoundingClientRect = { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 };
var LISTEN_FLAG = 'data-lazyload-listened';
var listeners = [];
var pending = [];

// try to handle passive events
var passiveEventSupported = false;
try {
  var opts = Object.defineProperty({}, 'passive', {
    get: function get() {
      passiveEventSupported = true;
    }
  });
  window.addEventListener('test', null, opts);
} catch (e) {}
// if they are supported, setup the optional params
// IMPORTANT: FALSE doubles as the default CAPTURE value!
var passiveEvent = passiveEventSupported ? { capture: false, passive: true } : false;

/**
 * Check if `component` is visible in overflow container `parent`
 * @param  {node} component React component
 * @param  {node} parent    component's scroll parent
 * @return {bool}
 */
var checkOverflowVisible = function checkOverflowVisible(component, parent) {
  var node = _reactDom2.default.findDOMNode(component);

  var parentTop = void 0;
  var parentHeight = void 0;

  try {
    var _parent$getBoundingCl = parent.getBoundingClientRect();

    parentTop = _parent$getBoundingCl.top;
    parentHeight = _parent$getBoundingCl.height;
  } catch (e) {
    parentTop = defaultBoundingClientRect.top;
    parentHeight = defaultBoundingClientRect.height;
  }

  var windowInnerHeight = window.innerHeight || document.documentElement.clientHeight;

  // calculate top and height of the intersection of the element's scrollParent and viewport
  var intersectionTop = Math.max(parentTop, 0); // intersection's top relative to viewport
  var intersectionHeight = Math.min(windowInnerHeight, parentTop + parentHeight) - intersectionTop; // height

  // check whether the element is visible in the intersection
  var top = void 0;
  var height = void 0;

  try {
    var _node$getBoundingClie = node.getBoundingClientRect();

    top = _node$getBoundingClie.top;
    height = _node$getBoundingClie.height;
  } catch (e) {
    top = defaultBoundingClientRect.top;
    height = defaultBoundingClientRect.height;
  }

  var offsetTop = top - intersectionTop; // element's top relative to intersection

  var offsets = Array.isArray(component.props.offset) ? component.props.offset : [component.props.offset, component.props.offset]; // Be compatible with previous API

  return offsetTop - offsets[0] <= intersectionHeight && offsetTop + height + offsets[1] >= 0;
};

/**
 * Check if `component` is visible in document
 * @param  {node} component React component
 * @return {bool}
 */
var checkNormalVisible = function checkNormalVisible(component) {
  var node = _reactDom2.default.findDOMNode(component);

  // If this element is hidden by css rules somehow, it's definitely invisible
  if (!(node.offsetWidth || node.offsetHeight || node.getClientRects().length)) return false;

  var top = void 0;
  var elementHeight = void 0;

  try {
    var _node$getBoundingClie2 = node.getBoundingClientRect();

    top = _node$getBoundingClie2.top;
    elementHeight = _node$getBoundingClie2.height;
  } catch (e) {
    top = defaultBoundingClientRect.top;
    elementHeight = defaultBoundingClientRect.height;
  }

  var windowInnerHeight = window.innerHeight || document.documentElement.clientHeight;

  var offsets = Array.isArray(component.props.offset) ? component.props.offset : [component.props.offset, component.props.offset]; // Be compatible with previous API

  return top - offsets[0] <= windowInnerHeight && top + elementHeight + offsets[1] >= 0;
};

/**
 * Detect if element is visible in viewport, if so, set `visible` state to true.
 * If `once` prop is provided true, remove component as listener after checkVisible
 *
 * @param  {React} component   React component that respond to scroll and resize
 */
var checkVisible = function checkVisible(component) {
  var node = _reactDom2.default.findDOMNode(component);
  if (!node) {
    return;
  }

  var parent = (0, _scrollParent2.default)(node);
  var isOverflow = component.props.overflow && parent !== node.ownerDocument && parent !== document && parent !== document.documentElement;
  var visible = isOverflow ? checkOverflowVisible(component, parent) : checkNormalVisible(component);
  if (visible) {
    // Avoid extra render if previously is visible
    if (!component.visible) {
      if (component.props.once) {
        pending.push(component);
      }

      component.visible = true;
      component.forceUpdate();
    }
  } else if (!(component.props.once && component.visible)) {
    component.visible = false;
    if (component.props.unmountIfInvisible) {
      component.forceUpdate();
    }
  }
};

var purgePending = function purgePending() {
  pending.forEach(function (component) {
    var index = listeners.indexOf(component);
    if (index !== -1) {
      listeners.splice(index, 1);
    }
  });

  pending = [];
};

var lazyLoadHandler = function lazyLoadHandler() {
  for (var i = 0; i < listeners.length; ++i) {
    var listener = listeners[i];
    checkVisible(listener);
  }
  // Remove `once` component in listeners
  purgePending();
};

// Depending on component's props
var delayType = void 0;
var finalLazyLoadHandler = null;

var LazyLoad = function (_Component) {
  _inherits(LazyLoad, _Component);

  function LazyLoad(props) {
    _classCallCheck(this, LazyLoad);

    var _this = _possibleConstructorReturn(this, (LazyLoad.__proto__ || Object.getPrototypeOf(LazyLoad)).call(this, props));

    _this.visible = false;
    return _this;
  }

  _createClass(LazyLoad, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production') {
        if (_react2.default.Children.count(this.props.children) > 1) {
          console.warn('[react-lazyload] Only one child is allowed to be passed to `LazyLoad`.');
        }

        if (this.props.wheel) {
          // eslint-disable-line
          console.warn('[react-lazyload] Props `wheel` is not supported anymore, try set `overflow` for lazy loading in overflow containers.');
        }

        // Warn the user if placeholder and height is not specified and the rendered height is 0
        if (!this.props.placeholder && this.props.height === undefined && _reactDom2.default.findDOMNode(this).offsetHeight === 0) {
          console.warn('[react-lazyload] Please add `height` props to <LazyLoad> for better performance.');
        }
      }

      // It's unlikely to change delay type on the fly, this is mainly
      // designed for tests
      var needResetFinalLazyLoadHandler = false;
      if (this.props.debounce !== undefined && delayType === 'throttle') {
        console.warn('[react-lazyload] Previous delay function is `throttle`, now switching to `debounce`, try setting them unanimously');
        needResetFinalLazyLoadHandler = true;
      } else if (delayType === 'debounce' && this.props.debounce === undefined) {
        console.warn('[react-lazyload] Previous delay function is `debounce`, now switching to `throttle`, try setting them unanimously');
        needResetFinalLazyLoadHandler = true;
      }

      if (needResetFinalLazyLoadHandler) {
        (0, _event.off)(window, 'scroll', finalLazyLoadHandler, passiveEvent);
        (0, _event.off)(window, 'resize', finalLazyLoadHandler, passiveEvent);
        finalLazyLoadHandler = null;
      }

      if (!finalLazyLoadHandler) {
        if (this.props.debounce !== undefined) {
          finalLazyLoadHandler = (0, _debounce2.default)(lazyLoadHandler, typeof this.props.debounce === 'number' ? this.props.debounce : 300);
          delayType = 'debounce';
        } else if (this.props.throttle !== undefined) {
          finalLazyLoadHandler = (0, _throttle2.default)(lazyLoadHandler, typeof this.props.throttle === 'number' ? this.props.throttle : 300);
          delayType = 'throttle';
        } else {
          finalLazyLoadHandler = lazyLoadHandler;
        }
      }

      if (this.props.overflow) {
        var parent = (0, _scrollParent2.default)(_reactDom2.default.findDOMNode(this));
        if (parent && typeof parent.getAttribute === 'function') {
          var listenerCount = 1 + +parent.getAttribute(LISTEN_FLAG);
          if (listenerCount === 1) {
            parent.addEventListener('scroll', finalLazyLoadHandler, passiveEvent);
          }
          parent.setAttribute(LISTEN_FLAG, listenerCount);
        }
      } else if (listeners.length === 0 || needResetFinalLazyLoadHandler) {
        var _props = this.props,
            scroll = _props.scroll,
            resize = _props.resize;

        if (scroll) {
          (0, _event.on)(window, 'scroll', finalLazyLoadHandler, passiveEvent);
        }

        if (resize) {
          (0, _event.on)(window, 'resize', finalLazyLoadHandler, passiveEvent);
        }
      }

      listeners.push(this);
      checkVisible(this);
    }
  }, {
    key: 'shouldComponentUpdate',
    value: function shouldComponentUpdate() {
      return this.visible;
    }
  }, {
    key: 'componentWillUnmount',
    value: function componentWillUnmount() {
      if (this.props.overflow) {
        var parent = (0, _scrollParent2.default)(_reactDom2.default.findDOMNode(this));
        if (parent && typeof parent.getAttribute === 'function') {
          var listenerCount = +parent.getAttribute(LISTEN_FLAG) - 1;
          if (listenerCount === 0) {
            parent.removeEventListener('scroll', finalLazyLoadHandler, passiveEvent);
            parent.removeAttribute(LISTEN_FLAG);
          } else {
            parent.setAttribute(LISTEN_FLAG, listenerCount);
          }
        }
      }

      var index = listeners.indexOf(this);
      if (index !== -1) {
        listeners.splice(index, 1);
      }

      if (listeners.length === 0) {
        (0, _event.off)(window, 'resize', finalLazyLoadHandler, passiveEvent);
        (0, _event.off)(window, 'scroll', finalLazyLoadHandler, passiveEvent);
      }
    }
  }, {
    key: 'render',
    value: function render() {
      return this.visible ? this.props.children : this.props.placeholder ? this.props.placeholder : _react2.default.createElement('div', { style: { height: this.props.height }, className: 'lazyload-placeholder' });
    }
  }]);

  return LazyLoad;
}(_react.Component);

LazyLoad.propTypes = {
  once: _propTypes2.default.bool,
  height: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.string]),
  offset: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.arrayOf(_propTypes2.default.number)]),
  overflow: _propTypes2.default.bool,
  resize: _propTypes2.default.bool,
  scroll: _propTypes2.default.bool,
  children: _propTypes2.default.node,
  throttle: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.bool]),
  debounce: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.bool]),
  placeholder: _propTypes2.default.node,
  unmountIfInvisible: _propTypes2.default.bool
};

LazyLoad.defaultProps = {
  once: false,
  offset: 0,
  overflow: false,
  resize: false,
  scroll: true,
  unmountIfInvisible: false
};

var lazyload = exports.lazyload = _decorator2.default;
exports.default = LazyLoad;
exports.forceCheck = lazyLoadHandler;<commit_msg>updated lib/index<commit_after>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.forceCheck = exports.lazyload = undefined;

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _event = require('./utils/event');

var _scrollParent = require('./utils/scrollParent');

var _scrollParent2 = _interopRequireDefault(_scrollParent);

var _debounce = require('./utils/debounce');

var _debounce2 = _interopRequireDefault(_debounce);

var _throttle = require('./utils/throttle');

var _throttle2 = _interopRequireDefault(_throttle);

var _decorator = require('./decorator');

var _decorator2 = _interopRequireDefault(_decorator);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
                                                                                * react-lazyload
                                                                                */

var defaultBoundingClientRect = { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 };
var LISTEN_FLAG = 'data-lazyload-listened';
var listeners = [];
var pending = [];

// try to handle passive events
var passiveEventSupported = false;
try {
  var opts = Object.defineProperty({}, 'passive', {
    get: function get() {
      passiveEventSupported = true;
    }
  });
  window.addEventListener('test', null, opts);
} catch (e) {}
// if they are supported, setup the optional params
// IMPORTANT: FALSE doubles as the default CAPTURE value!
var passiveEvent = passiveEventSupported ? { capture: false, passive: true } : false;

/**
 * Check if `component` is visible in overflow container `parent`
 * @param  {node} component React component
 * @param  {node} parent    component's scroll parent
 * @return {bool}
 */
var checkOverflowVisible = function checkOverflowVisible(component, parent) {
  var node = _reactDom2.default.findDOMNode(component);

  var parentTop = void 0;
  var parentHeight = void 0;

  try {
    var _parent$getBoundingCl = parent.getBoundingClientRect();

    parentTop = _parent$getBoundingCl.top;
    parentHeight = _parent$getBoundingCl.height;
  } catch (e) {
    parentTop = defaultBoundingClientRect.top;
    parentHeight = defaultBoundingClientRect.height;
  }

  var windowInnerHeight = window.innerHeight || document.documentElement.clientHeight;

  // calculate top and height of the intersection of the element's scrollParent and viewport
  var intersectionTop = Math.max(parentTop, 0); // intersection's top relative to viewport
  var intersectionHeight = Math.min(windowInnerHeight, parentTop + parentHeight) - intersectionTop; // height

  // check whether the element is visible in the intersection
  var top = void 0;
  var height = void 0;

  try {
    var _node$getBoundingClie = node.getBoundingClientRect();

    top = _node$getBoundingClie.top;
    height = _node$getBoundingClie.height;
  } catch (e) {
    top = defaultBoundingClientRect.top;
    height = defaultBoundingClientRect.height;
  }

  var offsetTop = top - intersectionTop; // element's top relative to intersection

  var offsets = Array.isArray(component.props.offset) ? component.props.offset : [component.props.offset, component.props.offset]; // Be compatible with previous API

  return offsetTop - offsets[0] <= intersectionHeight && offsetTop + height + offsets[1] >= 0;
};

/**
 * Check if `component` is visible in document
 * @param  {node} component React component
 * @return {bool}
 */
var checkNormalVisible = function checkNormalVisible(component) {
  var node = _reactDom2.default.findDOMNode(component);

  // If this element is hidden by css rules somehow, it's definitely invisible
  if (!(node.offsetWidth || node.offsetHeight || node.getClientRects().length)) return false;

  var top = void 0;
  var elementHeight = void 0;

  try {
    var _node$getBoundingClie2 = node.getBoundingClientRect();

    top = _node$getBoundingClie2.top;
    elementHeight = _node$getBoundingClie2.height;
  } catch (e) {
    top = defaultBoundingClientRect.top;
    elementHeight = defaultBoundingClientRect.height;
  }

  var windowInnerHeight = window.innerHeight || document.documentElement.clientHeight;

  var offsets = Array.isArray(component.props.offset) ? component.props.offset : [component.props.offset, component.props.offset]; // Be compatible with previous API

  return top - offsets[0] <= windowInnerHeight && top + elementHeight + offsets[1] >= 0;
};

/**
 * Detect if element is visible in viewport, if so, set `visible` state to true.
 * If `once` prop is provided true, remove component as listener after checkVisible
 *
 * @param  {React} component   React component that respond to scroll and resize
 */
var checkVisible = function checkVisible(component) {
  var node = _reactDom2.default.findDOMNode(component);
  if (!node) {
    return;
  }

  var parent = (0, _scrollParent2.default)(node);
  var isOverflow = component.props.overflow && parent !== node.ownerDocument && parent !== document && parent !== document.documentElement;
  var visible = isOverflow ? checkOverflowVisible(component, parent) : checkNormalVisible(component);
  if (visible) {
    // Avoid extra render if previously is visible
    if (!component.visible) {
      if (component.props.once) {
        pending.push(component);
      }

      component.visible = true;
      component.forceUpdate();
    }
  } else if (!(component.props.once && component.visible)) {
    component.visible = false;
    if (component.props.unmountIfInvisible) {
      component.forceUpdate();
    }
  }
};

var purgePending = function purgePending() {
  pending.forEach(function (component) {
    var index = listeners.indexOf(component);
    if (index !== -1) {
      listeners.splice(index, 1);
    }
  });

  pending = [];
};

var lazyLoadHandler = function lazyLoadHandler() {
  for (var i = 0; i < listeners.length; ++i) {
    var listener = listeners[i];
    checkVisible(listener);
  }
  // Remove `once` component in listeners
  purgePending();
};

// Depending on component's props
var delayType = void 0;
var finalLazyLoadHandler = null;

var isString = function isString(string) {
  return typeof string === 'string';
};

var LazyLoad = function (_Component) {
  _inherits(LazyLoad, _Component);

  function LazyLoad(props) {
    _classCallCheck(this, LazyLoad);

    var _this = _possibleConstructorReturn(this, (LazyLoad.__proto__ || Object.getPrototypeOf(LazyLoad)).call(this, props));

    _this.visible = false;
    return _this;
  }

  _createClass(LazyLoad, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      // It's unlikely to change delay type on the fly, this is mainly
      // designed for tests
      var scrollport = window;
      var scrollContainer = this.props.scrollContainer;

      if (scrollContainer) {
        if (isString(scrollContainer)) {
          scrollport = scrollport.document.querySelector(scrollContainer);
        }
      }
      var needResetFinalLazyLoadHandler = this.props.debounce !== undefined && delayType === 'throttle' || delayType === 'debounce' && this.props.debounce === undefined;

      if (needResetFinalLazyLoadHandler) {
        (0, _event.off)(scrollport, 'scroll', finalLazyLoadHandler, passiveEvent);
        (0, _event.off)(window, 'resize', finalLazyLoadHandler, passiveEvent);
        finalLazyLoadHandler = null;
      }

      if (!finalLazyLoadHandler) {
        if (this.props.debounce !== undefined) {
          finalLazyLoadHandler = (0, _debounce2.default)(lazyLoadHandler, typeof this.props.debounce === 'number' ? this.props.debounce : 300);
          delayType = 'debounce';
        } else if (this.props.throttle !== undefined) {
          finalLazyLoadHandler = (0, _throttle2.default)(lazyLoadHandler, typeof this.props.throttle === 'number' ? this.props.throttle : 300);
          delayType = 'throttle';
        } else {
          finalLazyLoadHandler = lazyLoadHandler;
        }
      }

      if (this.props.overflow) {
        var parent = (0, _scrollParent2.default)(_reactDom2.default.findDOMNode(this));
        if (parent && typeof parent.getAttribute === 'function') {
          var listenerCount = 1 + +parent.getAttribute(LISTEN_FLAG);
          if (listenerCount === 1) {
            parent.addEventListener('scroll', finalLazyLoadHandler, passiveEvent);
          }
          parent.setAttribute(LISTEN_FLAG, listenerCount);
        }
      } else if (listeners.length === 0 || needResetFinalLazyLoadHandler) {
        var _props = this.props,
            scroll = _props.scroll,
            resize = _props.resize;

        if (scroll) {
          (0, _event.on)(scrollport, 'scroll', finalLazyLoadHandler, passiveEvent);
        }

        if (resize) {
          (0, _event.on)(window, 'resize', finalLazyLoadHandler, passiveEvent);
        }
      }

      listeners.push(this);
      checkVisible(this);
    }
  }, {
    key: 'shouldComponentUpdate',
    value: function shouldComponentUpdate() {
      return this.visible;
    }
  }, {
    key: 'componentWillUnmount',
    value: function componentWillUnmount() {
      if (this.props.overflow) {
        var parent = (0, _scrollParent2.default)(_reactDom2.default.findDOMNode(this));
        if (parent && typeof parent.getAttribute === 'function') {
          var listenerCount = +parent.getAttribute(LISTEN_FLAG) - 1;
          if (listenerCount === 0) {
            parent.removeEventListener('scroll', finalLazyLoadHandler, passiveEvent);
            parent.removeAttribute(LISTEN_FLAG);
          } else {
            parent.setAttribute(LISTEN_FLAG, listenerCount);
          }
        }
      }

      var index = listeners.indexOf(this);
      if (index !== -1) {
        listeners.splice(index, 1);
      }

      if (listeners.length === 0) {
        (0, _event.off)(window, 'resize', finalLazyLoadHandler, passiveEvent);
        (0, _event.off)(window, 'scroll', finalLazyLoadHandler, passiveEvent);
      }
    }
  }, {
    key: 'render',
    value: function render() {
      return this.visible ? this.props.children : this.props.placeholder ? this.props.placeholder : _react2.default.createElement('div', { style: { height: this.props.height }, className: 'lazyload-placeholder' });
    }
  }]);

  return LazyLoad;
}(_react.Component);

LazyLoad.propTypes = {
  once: _propTypes2.default.bool,
  height: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.string]),
  offset: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.arrayOf(_propTypes2.default.number)]),
  overflow: _propTypes2.default.bool,
  resize: _propTypes2.default.bool,
  scroll: _propTypes2.default.bool,
  children: _propTypes2.default.node,
  throttle: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.bool]),
  debounce: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.bool]),
  placeholder: _propTypes2.default.node,
  scrollContainer: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.object]),
  unmountIfInvisible: _propTypes2.default.bool
};

LazyLoad.defaultProps = {
  once: false,
  offset: 0,
  overflow: false,
  resize: false,
  scroll: true,
  unmountIfInvisible: false
};

var lazyload = exports.lazyload = _decorator2.default;
exports.default = LazyLoad;
exports.forceCheck = lazyLoadHandler;<|endoftext|>


<commit_before>'use strict';

var browserify = require('browserify');
var gulp = require('gulp');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var less = require('gulp-less');
var concat = require('gulp-concat');

gulp.task('default', ['javascript', 'less']);

gulp.task('watch', function() {
    gulp.watch('source/js/*.js', ['javascript']);
    gulp.watch('source/js/events/*.js', ['javascript']);
    gulp.watch('source/js/highlighters/*.js', ['javascript']);
    gulp.watch('source/js/highlighters/syntax/*.js', ['javascript']);
    gulp.watch('source/js/renderers/*.js', ['javascript']);
    gulp.watch('source/js/styles/*.js', ['javascript']);
    gulp.watch('source/less/*.less', ['less']);
});

gulp.task('components', function() {
    return gulp.src([
        './source/components/prism/components/prism-core.js',
        './source/components/prism/components/prism-markup.js',
        './source/components/prism/components/prism-clike.js',

        './source/components/prism/components/prism-apacheconf.js',
        //'./source/components/prism/components/prism-css-extras.js',
        './source/components/prism/components/prism-java.js',
        './source/components/prism/components/prism-python.js',
        './source/components/prism/components/prism-aspnet.js',
        './source/components/prism/components/prism-css.js',
        './source/components/prism/components/prism-javascript.js',
        './source/components/prism/components/prism-rip.js',
        './source/components/prism/components/prism-autohotkey.js',
        './source/components/prism/components/prism-gherkin.js',
        './source/components/prism/components/prism-latex.js',
        './source/components/prism/components/prism-ruby.js',
        './source/components/prism/components/prism-bash.js',
        './source/components/prism/components/prism-git.js',
        './source/components/prism/components/prism-markup.js',
        './source/components/prism/components/prism-scala.js',
        './source/components/prism/components/prism-c.js',
        './source/components/prism/components/prism-go.js',
        './source/components/prism/components/prism-nasm.js',
        './source/components/prism/components/prism-scheme.js',
        './source/components/prism/components/prism-clike.js',
        './source/components/prism/components/prism-groovy.js',
        './source/components/prism/components/prism-nsis.js',
        './source/components/prism/components/prism-scss.js',
        './source/components/prism/components/prism-coffeescript.js',
        './source/components/prism/components/prism-handlebars.js',
        './source/components/prism/components/prism-objectivec.js',
        './source/components/prism/components/prism-sql.js',
        './source/components/prism/components/prism-core.js',
        './source/components/prism/components/prism-haskell.js',
        './source/components/prism/components/prism-perl.js',
        './source/components/prism/components/prism-swift.js',
        './source/components/prism/components/prism-cpp.js',
        './source/components/prism/components/prism-http.js',
        './source/components/prism/components/prism-php-extras.js',
        './source/components/prism/components/prism-twig.js',
        './source/components/prism/components/prism-csharp.js',
        './source/components/prism/components/prism-ini.js',
        './source/components/prism/components/prism-php.js',
        ]).pipe(concat('prism.js'))
        .pipe(gulp.dest('./source/components/'));
});

gulp.task('javascript', ['components'], function() {
    return browserify({
            entries: ['./source/js/poster.js'],
            debug: true,
            standalone: 'poster',
        })
        .bundle()
        .pipe(source('poster.js'))
        .pipe(buffer())
        .pipe(gulp.dest('./build/'));
        // Add transformation tasks to the pipeline here.
        // This will minify and rename to foo.min.js
        // .pipe(sourcemaps.init({loadMaps: true}))
        // .pipe(uglify())
        // .pipe(sourcemaps.write('./'));
});

gulp.task('less', function() {
    gulp.src('source/less/poster.less')
        .pipe(less())
        .pipe(gulp.dest('./build/'));
});
<commit_msg>Watch the plugins<commit_after>'use strict';

var browserify = require('browserify');
var gulp = require('gulp');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var less = require('gulp-less');
var concat = require('gulp-concat');

gulp.task('default', ['javascript', 'less']);

gulp.task('watch', function() {
    gulp.watch('source/js/*.js', ['javascript']);
    gulp.watch('source/js/events/*.js', ['javascript']);
    gulp.watch('source/js/highlighters/*.js', ['javascript']);
    gulp.watch('source/js/highlighters/syntax/*.js', ['javascript']);
    gulp.watch('source/js/plugins/*.js', ['javascript']);
    gulp.watch('source/js/plugins/gutter/*.js', ['javascript']);
    gulp.watch('source/js/plugins/linenumbers/*.js', ['javascript']);
    gulp.watch('source/js/renderers/*.js', ['javascript']);
    gulp.watch('source/js/styles/*.js', ['javascript']);
    gulp.watch('source/less/*.less', ['less']);
});

gulp.task('components', function() {
    return gulp.src([
        './source/components/prism/components/prism-core.js',
        './source/components/prism/components/prism-markup.js',
        './source/components/prism/components/prism-clike.js',

        './source/components/prism/components/prism-apacheconf.js',
        //'./source/components/prism/components/prism-css-extras.js',
        './source/components/prism/components/prism-java.js',
        './source/components/prism/components/prism-python.js',
        './source/components/prism/components/prism-aspnet.js',
        './source/components/prism/components/prism-css.js',
        './source/components/prism/components/prism-javascript.js',
        './source/components/prism/components/prism-rip.js',
        './source/components/prism/components/prism-autohotkey.js',
        './source/components/prism/components/prism-gherkin.js',
        './source/components/prism/components/prism-latex.js',
        './source/components/prism/components/prism-ruby.js',
        './source/components/prism/components/prism-bash.js',
        './source/components/prism/components/prism-git.js',
        './source/components/prism/components/prism-markup.js',
        './source/components/prism/components/prism-scala.js',
        './source/components/prism/components/prism-c.js',
        './source/components/prism/components/prism-go.js',
        './source/components/prism/components/prism-nasm.js',
        './source/components/prism/components/prism-scheme.js',
        './source/components/prism/components/prism-clike.js',
        './source/components/prism/components/prism-groovy.js',
        './source/components/prism/components/prism-nsis.js',
        './source/components/prism/components/prism-scss.js',
        './source/components/prism/components/prism-coffeescript.js',
        './source/components/prism/components/prism-handlebars.js',
        './source/components/prism/components/prism-objectivec.js',
        './source/components/prism/components/prism-sql.js',
        './source/components/prism/components/prism-core.js',
        './source/components/prism/components/prism-haskell.js',
        './source/components/prism/components/prism-perl.js',
        './source/components/prism/components/prism-swift.js',
        './source/components/prism/components/prism-cpp.js',
        './source/components/prism/components/prism-http.js',
        './source/components/prism/components/prism-php-extras.js',
        './source/components/prism/components/prism-twig.js',
        './source/components/prism/components/prism-csharp.js',
        './source/components/prism/components/prism-ini.js',
        './source/components/prism/components/prism-php.js',
        ]).pipe(concat('prism.js'))
        .pipe(gulp.dest('./source/components/'));
});

gulp.task('javascript', ['components'], function() {
    return browserify({
            entries: ['./source/js/poster.js'],
            debug: true,
            standalone: 'poster',
        })
        .bundle()
        .pipe(source('poster.js'))
        .pipe(buffer())
        .pipe(gulp.dest('./build/'));
        // Add transformation tasks to the pipeline here.
        // This will minify and rename to foo.min.js
        // .pipe(sourcemaps.init({loadMaps: true}))
        // .pipe(uglify())
        // .pipe(sourcemaps.write('./'));
});

gulp.task('less', function() {
    gulp.src('source/less/poster.less')
        .pipe(less())
        .pipe(gulp.dest('./build/'));
});
<|endoftext|>