<commit_before>const assert = require('assert');
const mocha = require('mocha');
const Try = require('../dist');

mocha.describe('Success', () => {

    mocha.describe('.filter()', () => {

        mocha.it('should return success when filter predicate matches', () => {
            let success = Try.success(100)
                .filter(value => value > 50);
            assert(success.isSuccess());
        });

        mocha.it('should return failure when predicate does not match', () => {
            let success = Try.success(100)
                .filter(value => value > 500);
            assert(success.isFailure());
        });

        mocha.it('should throw error when function argument is not present', () => {
            let success = Try.success(100);
            assert.throws(() => success.filter());
        });

        mocha.it('should throw error when function argument is not a function', () => {
            let success = Try.success(100);
            assert.throws(() => success.filter({}), Error);
        });
    });

    mocha.describe('.flapMap()', () => {

        mocha.it('should flat map success try value', () => {
            let success = Try.success(100)
                .flatMap(value => Try.success(value + 10));
            assert(success.isSuccess());
            assert.equal(success.value, 110);
        });

        mocha.it('should not flat map failure try value', () => {
            let failure = Try.success(100)
                .flatMap(value => Try.failure('Something went wrong'));
            assert(failure.isFailure());
            assert.equal(failure.err, 'Something went wrong');
        });

        mocha.it('should throw error when function argument is not present', () => {
            let success = Try.success(100);
            assert.throws(() => success.flatMap());
        });

        mocha.it('should throw error when function argument is not a function', () => {
            let success = Try.success(100);
            assert.throws(() => success.flatMap({}));
        });
    });

    mocha.describe('.getOrElse()', () => {

        mocha.it('should get alternative value upon failure', () => {
            let failure = Try.failure('Boom!');
            assert.equal(failure.getOrElse('foobar'), 'foobar');
        });
    });

    mocha.describe('.isFailure()', () => {

        mocha.it('should indicate that a failure is a failure', () => {
            let failure = Try.failure('Oh no!');
            assert(failure.isFailure());
        });

        mocha.it('should indicate that a success is not a failure', () => {
            let success = Try.success(100);
            assert(!success.isFailure());
        });
    });

    mocha.describe('.isSuccess()', () => {

        mocha.it('should indicate that a success is a success', () => {
            let success = Try.success(100);
            assert(success.isSuccess());
        });

        mocha.it('should indicate that a failure is not a success', () => {
            let failure = Try.failure('Hmpf!');
            assert(!failure.isSuccess());
        });
    });

    mocha.describe('.map()', () => {

        mocha.it('should map a success value', () => {
            let value = Try.success(100)
                .map(value => value + 10)
                .get();

            assert.equal(value, 110);
        });
    });
});
<commit_msg>Add tests for map, onFailure and onSuccess.<commit_after>const assert = require('assert');
const mocha = require('mocha');
const Try = require('../dist');

mocha.describe('Success', () => {

    mocha.describe('.filter()', () => {

        mocha.it('should return success when filter predicate matches', () => {
            let success = Try.success(100)
                .filter(value => value > 50);
            assert(success.isSuccess());
        });

        mocha.it('should return failure when predicate does not match', () => {
            let success = Try.success(100)
                .filter(value => value > 500);
            assert(success.isFailure());
        });

        mocha.it('should throw error when function argument is not present', () => {
            let success = Try.success(100);
            assert.throws(() => success.filter());
        });

        mocha.it('should throw error when function argument is not a function', () => {
            let success = Try.success(100);
            assert.throws(() => success.filter({}), Error);
        });
    });

    mocha.describe('.flapMap()', () => {

        mocha.it('should flat map success try value', () => {
            let success = Try.success(100)
                .flatMap(value => Try.success(value + 10));
            assert(success.isSuccess());
            assert.equal(success.value, 110);
        });

        mocha.it('should not flat map failure try value', () => {
            let failure = Try.success(100)
                .flatMap(value => Try.failure('Something went wrong'));
            assert(failure.isFailure());
            assert.equal(failure.err, 'Something went wrong');
        });

        mocha.it('should throw error when function argument is not present', () => {
            let success = Try.success(100);
            assert.throws(() => success.flatMap());
        });

        mocha.it('should throw error when function argument is not a function', () => {
            let success = Try.success(100);
            assert.throws(() => success.flatMap({}));
        });
    });

    mocha.describe('.getOrElse()', () => {

        mocha.it('should get alternative value upon failure', () => {
            let failure = Try.failure('Boom!');
            assert.equal(failure.getOrElse('foobar'), 'foobar');
        });
    });

    mocha.describe('.isFailure()', () => {

        mocha.it('should indicate that a failure is a failure', () => {
            let failure = Try.failure('Oh no!');
            assert(failure.isFailure());
        });

        mocha.it('should indicate that a success is not a failure', () => {
            let success = Try.success(100);
            assert(!success.isFailure());
        });
    });

    mocha.describe('.isSuccess()', () => {

        mocha.it('should indicate that a success is a success', () => {
            let success = Try.success(100);
            assert(success.isSuccess());
        });

        mocha.it('should indicate that a failure is not a success', () => {
            let failure = Try.failure('Hmpf!');
            assert(!failure.isSuccess());
        });
    });

    mocha.describe('.map()', () => {

        mocha.it('should map a success value', () => {
            let value = Try.success(100)
                .map(value => value + 10)
                .get();

            assert.equal(value, 110);
        });

        mocha.it('should not map a failure value', () => {
            let failure = Try.failure('Nope')
                .map(value => {
                    assert.fail(null, null, 'should not be called: value ' + value, null);
                    throw new Error('Not happening');
                });
        });
    });

    mocha.describe('.onFailure()', () => {

        mocha.it('should trigger on a failure', () => {
            let hasBeenInvoked = false;
            Try.failure('No')
                .onFailure(err => hasBeenInvoked = true);
            assert(hasBeenInvoked);
        });

        mocha.it('should not trigger on a success', () => {
            let hasBeenIvoked = false;
            Try.success(100)
                .onFailure(err => hasBeenIvoked = true);
            assert(!hasBeenIvoked);
        });
    });

    mocha.describe('.onSuccess', () => {

        mocha.it('should trigger on a success', () => {
            let hasBeenInvoked = false;
            Try.success(100)
                .onSuccess(value => hasBeenInvoked = true);
            assert(hasBeenInvoked);
        });

        mocha.it('should not trigger on a failure', () => {
            let hasBeenInvoked = false;
            Try.failure('Args!')
                .onSuccess(value => hasBeenInvoked = true);
            assert(!hasBeenInvoked);
        });
    });
});
<|endoftext|>


<commit_before>var IndexController = Ember.ObjectController.extend({
  actions: {
    sayHi: function() {
      alert(this.get('name') + ' says hi!');
    }
  }
});

export default = IndexController;
<commit_msg>Update index.js.es6<commit_after>export default = Ember.ObjectController.extend({
  actions: {
    sayHi: function() {
      alert(this.get('name') + ' says hi!');
    }
  }
});
<|endoftext|>


<commit_before>'use strict';

var when = require('when');
var request = require('request');
var querystring = require('querystring');
var cheerio = require('cheerio');

var weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

var Skip = {};

Skip.search = function(name) {
  return when.promise(function(resolve, reject) {
    var url = 'http://www.skip.at/suche/?q=' + querystring.escape(name) + '&models=movies.movie';
    request(url, function(error, response, body) {
      if (error || response.statusCode !== 200) {
        resolve(null);
        return;
      }

      var skipId = getSkipMovieIdFromBody(body);
      if (!skipId) {
        resolve(null);
        return;
      }

      // Fetch showtimes for the next 7 days
      var showtimePromises = [];
      var date = new Date();
      for (var i = 0; i < 7; i++) {
        showtimePromises.push(findShowtimes(skipId, new Date(date.getTime() + i * 86400000)));
      }

      when.all(showtimePromises).then(function(showtimes) {
        resolve(showtimes);
      });
    });
  });
};

function getSkipMovieIdFromBody(body) {
  var $ = cheerio.load(body);
  var link = $('.box.listing ul h2 a').first().attr('href');
  var m = (link ? link.match(/\/film\/(\d+)\/?/) : null);
  return (m && m.length >= 2 ? m[1] : null);
}

function findShowtimes(skipId, date) {
  return when.promise(function(resolve, reject) {
    var dateStr = date.toISOString().substr(0, 10);
    var url = 'http://www.skip.at/kinoprogramm/wien/filme/?filter=OF&film=' + skipId + '&datum=' + dateStr;
    request(url, function(error, response, body) {
      var data = {
        date: weekdays[date.getDay()] + ', ' + date.toISOString().substr(5, 5),
        cinemas: []
      };

      if (error || response.statusCode !== 200) {
        resolve(data);
        return;
      }

      var $ = cheerio.load(body);
      $('ul.schedule-listing li').each(function(idx, el) {
        var cinemaLink = $(this).find('h4 a').attr('href');
        var m = (cinemaLink ? cinemaLink.match(/\/kino\/(\d+)\/?/) : null);
        var cinemaId = (m && m.length >= 2 ? m[1] : null);
        var entry = {
          cinema: $(this).find('h4 a').text(),
          url: 'http://www.skip.at/kinoprogramm/wien/kinos/?filter=OF&kino=' + cinemaId + '&datum=' + dateStr,
          showtimes: []
        };
        $(this).find('div.times div.time').each(function(idx2, el2) {
          var meta = [];
          $(this).find('span.additional').each(function(idx3, el3) {
            meta.push($(this).text());
            $(this).text('');
          });
          var showtime = $(this).text().trim().replace('.', ':') + (meta.length ? ' (' + meta.join(' ') + ')' : '');
          entry.showtimes.push(showtime);
        });
        data.cinemas.push(entry);
      });

      resolve(data);
    });
  });
}

module.exports = Skip;<commit_msg>Cleanup<commit_after>'use strict';

var when = require('when');
var request = require('request');
var querystring = require('querystring');
var cheerio = require('cheerio');

var weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

var Skip = {};

Skip.search = function(name) {
  return when.promise(function(resolve, reject) {
    var url = 'http://www.skip.at/suche/?q=' + querystring.escape(name) + '&models=movies.movie';
    request(url, function(error, response, body) {
      if (error || response.statusCode !== 200) {
        resolve(null);
        return;
      }

      var skipId = getMovieIdFromBody(body);
      if (!skipId) {
        resolve(null);
        return;
      }

      // Fetch showtimes for the next 7 days
      var showtimePromises = [];
      var date = new Date();
      for (var i = 0; i < 7; i++) {
        showtimePromises.push(findShowtimes(skipId, new Date(date.getTime() + i * 86400000)));
      }

      when.all(showtimePromises).then(function(showtimes) {
        resolve(showtimes);
      });
    });
  });
};

function getMovieIdFromBody(body) {
  var $ = cheerio.load(body);
  var link = $('.box.listing ul h2 a').first().attr('href');
  var m = (link ? link.match(/\/film\/(\d+)\/?/) : null);
  return (m && m.length >= 2 ? m[1] : null);
}

function findShowtimes(skipId, date) {
  return when.promise(function(resolve, reject) {
    var dateStr = date.toISOString().substr(0, 10);
    var url = 'http://www.skip.at/kinoprogramm/wien/filme/?filter=OF&film=' + skipId + '&datum=' + dateStr;
    request(url, function(error, response, body) {
      var data = {
        date: weekdays[date.getDay()] + ', ' + date.toISOString().substr(5, 5),
        cinemas: []
      };

      if (error || response.statusCode !== 200) {
        resolve(data);
        return;
      }

      var $ = cheerio.load(body);
      $('ul.schedule-listing li').each(function(idx, el) {
        var cinemaId = getCinemaIdFromElement($(this));
        var entry = {
          cinema: $(this).find('h4 a').text(),
          url: 'http://www.skip.at/kinoprogramm/wien/kinos/?filter=OF&kino=' + cinemaId + '&datum=' + dateStr,
          showtimes: []
        };
        $(this).find('div.times div.time').each(function(idx2, el2) {
          entry.showtimes.push(getShowtimeFromElement($(this), $));
        });
        data.cinemas.push(entry);
      });

      resolve(data);
    });
  });
}

function getCinemaIdFromElement(el) {
  var cinemaLink = el.find('h4 a').attr('href');
  var m = (cinemaLink ? cinemaLink.match(/\/kino\/(\d+)\/?/) : null);
  return (m && m.length >= 2 ? m[1] : null);
}

function getShowtimeFromElement(el, $) {
  var meta = [];
  el.find('span.additional').each(function(idx, el) {
    meta.push($(this).text());
    $(this).text('');
  });
  return el.text().trim().replace('.', ':') + (meta.length ? ' (' + meta.join(' ') + ')' : '');
}

module.exports = Skip;<|endoftext|>


<commit_before>var naturalSort = require('natural-sort'),
  classes = require('classes'),
  events = require('events'),
  getByClass = require('get-by-class'),
  getAttribute = require('get-attribute');

module.exports = function(list) {
  list.sortFunction = list.sortFunction || function(itemA, itemB, options) {
    options.desc = options.order == "desc" ? true : false; // Natural sort uses this format
    return naturalSort(itemA.values()[options.valueName], itemB.values()[options.valueName], options);
  };

  var buttons = {
    els: undefined,
    clear: function() {
      for (var i = 0, il = buttons.els.length; i < il; i++) {
        classes(buttons.els[i]).remove('asc');
        classes(buttons.els[i]).remove('desc');
      }
    },
    getOrder: function(btn) {
      var predefinedOrder = getAttribute(btn, 'data-order');
      if (predefinedOrder == "asc" || predefinedOrder == "desc") {
        return predefinedOrder;
      } else if (classes(btn).has('desc')) {
        return "asc";
      } else if (classes(btn).has('asc')) {
        return "desc";
      } else {
        return "asc";
      }
    },
    getInSensitive: function(btn, options) {
      var insensitive = getAttribute(btn, 'data-insensitive');
      if (insensitive === "true") {
        options.insensitive = true;
      } else {
        options.insensitive = false;
      }
    },
    setOrder: function(options) {
      for (var i = 0, il = buttons.els.length; i < il; i++) {
        var btn = buttons.els[i];
        if (getAttribute(btn, 'data-sort') !== options.valueName) {
          continue;
        }
        var predefinedOrder = getAttribute(btn, 'data-order');
        if (predefinedOrder == "asc" || predefinedOrder == "desc") {
          if (predefinedOrder == options.order) {
            classes(btn).add(options.order);
          }
        } else {
          classes(btn).add(options.order);
        }
      }
    }
  };
  var sort = function() {
    list.trigger('sortStart');
    options = {};

    var target = arguments[0].currentTarget || arguments[0].srcElement || undefined;

    if (target) {
      options.valueName = getAttribute(target, 'data-sort');
      buttons.getInSensitive(target, options);
      options.order = buttons.getOrder(target);
    } else {
      options = arguments[1] || options;
      options.valueName = arguments[0];
      options.order = options.order || "asc";
      options.insensitive = (typeof options.insensitive == "undefined") ? true : options.insensitive;
    }
    buttons.clear();
    buttons.setOrder(options);

    options.sortFunction = options.sortFunction || list.sortFunction;
    list.items.sort(function(a, b) {
      return options.sortFunction(a, b, options);
    });
    list.update();
    list.trigger('sortComplete');
  };

  // Add handlers
  list.handlers.sortStart = list.handlers.sortStart || [];
  list.handlers.sortComplete = list.handlers.sortComplete || [];

  buttons.els = getByClass(list.listContainer, list.sortClass);
  events.bind(buttons.els, 'click', sort);
  list.on('searchStart', buttons.clear);
  list.on('filterStart', buttons.clear);

  // Helpers
  list.helpers.classes = classes;
  list.helpers.naturalSort = naturalSort;
  list.helpers.events = events;
  list.helpers.getAttribute = getAttribute;

  return sort;
};
<commit_msg>Avoid leaking to global scope<commit_after>var naturalSort = require('natural-sort'),
  classes = require('classes'),
  events = require('events'),
  getByClass = require('get-by-class'),
  getAttribute = require('get-attribute');

module.exports = function(list) {
  list.sortFunction = list.sortFunction || function(itemA, itemB, options) {
    options.desc = options.order == "desc" ? true : false; // Natural sort uses this format
    return naturalSort(itemA.values()[options.valueName], itemB.values()[options.valueName], options);
  };

  var buttons = {
    els: undefined,
    clear: function() {
      for (var i = 0, il = buttons.els.length; i < il; i++) {
        classes(buttons.els[i]).remove('asc');
        classes(buttons.els[i]).remove('desc');
      }
    },
    getOrder: function(btn) {
      var predefinedOrder = getAttribute(btn, 'data-order');
      if (predefinedOrder == "asc" || predefinedOrder == "desc") {
        return predefinedOrder;
      } else if (classes(btn).has('desc')) {
        return "asc";
      } else if (classes(btn).has('asc')) {
        return "desc";
      } else {
        return "asc";
      }
    },
    getInSensitive: function(btn, options) {
      var insensitive = getAttribute(btn, 'data-insensitive');
      if (insensitive === "true") {
        options.insensitive = true;
      } else {
        options.insensitive = false;
      }
    },
    setOrder: function(options) {
      for (var i = 0, il = buttons.els.length; i < il; i++) {
        var btn = buttons.els[i];
        if (getAttribute(btn, 'data-sort') !== options.valueName) {
          continue;
        }
        var predefinedOrder = getAttribute(btn, 'data-order');
        if (predefinedOrder == "asc" || predefinedOrder == "desc") {
          if (predefinedOrder == options.order) {
            classes(btn).add(options.order);
          }
        } else {
          classes(btn).add(options.order);
        }
      }
    }
  };
  var sort = function() {
    list.trigger('sortStart');
    var options = {};

    var target = arguments[0].currentTarget || arguments[0].srcElement || undefined;

    if (target) {
      options.valueName = getAttribute(target, 'data-sort');
      buttons.getInSensitive(target, options);
      options.order = buttons.getOrder(target);
    } else {
      options = arguments[1] || options;
      options.valueName = arguments[0];
      options.order = options.order || "asc";
      options.insensitive = (typeof options.insensitive == "undefined") ? true : options.insensitive;
    }
    buttons.clear();
    buttons.setOrder(options);

    options.sortFunction = options.sortFunction || list.sortFunction;
    list.items.sort(function(a, b) {
      return options.sortFunction(a, b, options);
    });
    list.update();
    list.trigger('sortComplete');
  };

  // Add handlers
  list.handlers.sortStart = list.handlers.sortStart || [];
  list.handlers.sortComplete = list.handlers.sortComplete || [];

  buttons.els = getByClass(list.listContainer, list.sortClass);
  events.bind(buttons.els, 'click', sort);
  list.on('searchStart', buttons.clear);
  list.on('filterStart', buttons.clear);

  // Helpers
  list.helpers.classes = classes;
  list.helpers.naturalSort = naturalSort;
  list.helpers.events = events;
  list.helpers.getAttribute = getAttribute;

  return sort;
};
<|endoftext|>


<commit_before>Ext.namespace('Vpc.ListSwitch');

Vpc.ListSwitch.View = function(componentWrapper) {
    this.componentWrapper = Ext.get(componentWrapper);
    this.init();
};

Vpc.ListSwitch.View.prototype = {
    previewElements: [],
    activePreviewLink: null,

    init: function() {
        this.previousEl = this.componentWrapper.down('.listSwitchLargeWrapper a.listSwitchPrevious');
        this.nextEl = this.componentWrapper.down('.listSwitchLargeWrapper a.listSwitchNext');

        this.previousEl.on('click', this.showPrevious, this);
        this.nextEl.on('click', this.showNext, this);

        var switchItems = Ext.DomQuery.select(
            'div.listSwitchItem',
            this.componentWrapper.down('.listSwitchPreviewWrapper').dom
        );
        Ext.each(switchItems, function(si) {
            var previewLink = Ext.get(si).down('a.previewLink');
            previewLink.largeContent = Ext.get(si).down('.largeContent').dom.innerHTML;
            previewLink.switchIndex = this.previewElements.length;
            previewLink.on('click', function(ev, el, cfg) {
                this.setLarge(cfg.linkEl);
                ev.stopEvent();
            }, this, { linkEl: previewLink });
            this.previewElements.push(previewLink);
        }, this);

        this.setLarge(this.previewElements[0]);
    },

    setLarge: function(previewEl) {
        this.componentWrapper.down('.listSwitchLargeWrapper .listSwitchLargeContent').dom.innerHTML =
            previewEl.largeContent;
        if (this.activePreviewLink) {
            this.activePreviewLink.removeClass('active');
        }
        this.activePreviewLink = previewEl;
        this.activePreviewLink.addClass('active');

        this.previousEl.setDisplayed(this.activePreviewLink.switchIndex == 0 ? false : true);
        this.nextEl.setDisplayed(
            this.activePreviewLink.switchIndex >= (this.previewElements.length -1) ? false : true
        );
    },

    showNext: function(ev) {
        if (this.previewElements[this.activePreviewLink.switchIndex+1]) {
            this.setLarge(this.previewElements[this.activePreviewLink.switchIndex+1]);
        }
        ev.stopEvent();
    },

    showPrevious: function(ev) {
        if (this.activePreviewLink.switchIndex >= 1) {
            this.setLarge(this.previewElements[this.activePreviewLink.switchIndex-1]);
        }
        ev.stopEvent();
    }
};

Vps.onContentReady(function() {
    var switches = Ext.DomQuery.select('div.vpsListSwitch');
    Ext.each(switches, function(sw) {
        var list = new Vpc.ListSwitch.View(sw);
    });
});

<commit_msg>nicht innerHTML kopieren sondern den node selbst damit keine event-handler veloren gehen<commit_after>Ext.namespace('Vpc.ListSwitch');

Vpc.ListSwitch.View = function(componentWrapper) {
    this.componentWrapper = Ext.get(componentWrapper);
    this.init();
};

Vpc.ListSwitch.View.prototype = {
    previewElements: [],
    activePreviewLink: null,

    init: function() {
        this.previousEl = this.componentWrapper.down('.listSwitchLargeWrapper a.listSwitchPrevious');
        this.nextEl = this.componentWrapper.down('.listSwitchLargeWrapper a.listSwitchNext');

        this.previousEl.on('click', this.showPrevious, this);
        this.nextEl.on('click', this.showNext, this);

        var switchItems = Ext.DomQuery.select(
            'div.listSwitchItem',
            this.componentWrapper.down('.listSwitchPreviewWrapper').dom
        );
        Ext.each(switchItems, function(si) {
            var previewLink = Ext.get(si).down('a.previewLink');
            previewLink.largeContent = Ext.get(si).down('.largeContent').dom;
            previewLink.switchIndex = this.previewElements.length;
            previewLink.on('click', function(ev, el, cfg) {
                this.setLarge(cfg.linkEl);
                ev.stopEvent();
            }, this, { linkEl: previewLink });
            this.previewElements.push(previewLink);
        }, this);

        this.setLarge(this.previewElements[0]);
    },

    setLarge: function(previewEl) {
        previewEl.largeContent.style.display = 'block';
        this.componentWrapper.down('.listSwitchLargeWrapper .listSwitchLargeContent').dom.innerHTML = '';
        this.componentWrapper.down('.listSwitchLargeWrapper .listSwitchLargeContent').dom.appendChild(previewEl.largeContent);
        if (this.activePreviewLink) {
            this.activePreviewLink.removeClass('active');
        }
        this.activePreviewLink = previewEl;
        this.activePreviewLink.addClass('active');

        this.previousEl.setDisplayed(this.activePreviewLink.switchIndex == 0 ? false : true);
        this.nextEl.setDisplayed(
            this.activePreviewLink.switchIndex >= (this.previewElements.length -1) ? false : true
        );
    },

    showNext: function(ev) {
        if (this.previewElements[this.activePreviewLink.switchIndex+1]) {
            this.setLarge(this.previewElements[this.activePreviewLink.switchIndex+1]);
        }
        ev.stopEvent();
    },

    showPrevious: function(ev) {
        if (this.activePreviewLink.switchIndex >= 1) {
            this.setLarge(this.previewElements[this.activePreviewLink.switchIndex-1]);
        }
        ev.stopEvent();
    }
};

Vps.onContentReady(function() {
    var switches = Ext.DomQuery.select('div.vpsListSwitch');
    Ext.each(switches, function(sw) {
        var list = new Vpc.ListSwitch.View(sw);
    });
});

<|endoftext|>


<commit_before>'use strict';

const spawn = require('../../index');

function isForceShell(method) {
    return /-force-shell$/.test(method);
}

function isMethodSync(method) {
    return /^sync(-|$)/.test(method);
}

function resolveRun(exitCode, stdout, stderr) {
    stdout = stdout && stdout.toString();
    stderr = stderr && stderr.toString();

    if (exitCode !== 0) {
        return Object.assign(new Error(`Command failed, exited with code #${exitCode}`), {
            exitCode,
            stdout,
            stderr,
        });
    }

    return {
        stdout,
        stderr,
    };
}

function runSync(command, args, options) {
    const { error, status, stdout, stderr } = spawn.sync(command, args, options);

    if (error) {
        throw error;
    }

    const resolved = resolveRun(status, stdout, stderr);

    if (resolved instanceof Error) {
        throw resolved;
    }

    return resolved;
}

function runAsync(command, args, options) {
    const cp = spawn(command, args, options);

    const promise = new Promise((resolve, reject) => {
        let stdout = null;
        let stderr = null;

        cp.stdout && cp.stdout.on('data', (data) => {
            stdout = stdout || new Buffer('');
            stdout = Buffer.concat([stdout, data]);
        });

        cp.stderr && cp.stderr.on('data', (data) => {
            stderr = stderr || new Buffer('');
            stderr = Buffer.concat([stderr, data]);
        });

        const cleanupListeners = () => {
            cp.removeListener('error', onError);
            cp.removeListener('close', onClose);
        };

        const onError = (err) => {
            cleanupListeners();
            reject(err);
        };

        const onClose = (code) => {
            cleanupListeners();

            const resolved = resolveRun(code, stdout, stderr);

            if (resolved instanceof Error) {
                reject(resolved);
            } else {
                resolve(resolved);
            }
        };

        cp
        .on('error', onError)
        .on('close', onClose);
    });

    promise.cp = cp;

    return promise;
}

function run(method, command, args, options) {
    // Are we forcing the shell?
    if (isForceShell(method)) {
        if (args && !Array.isArray(args)) {
            options = args;
            args = null;
        }

        method = method.replace(/-force-shell$/, '');
        options = Object.assign({ forceShell: true }, options);
    }

    // Run sync version
    return method === 'sync' ?
        runSync(command, args, options) :
        runAsync(command, args, options);
}

module.exports = run;
module.exports.methods = ['spawn-force-shell', 'spawn', 'sync-force-shell', 'sync'];
module.exports.isMethodSync = isMethodSync;
module.exports.isForceShell = isForceShell;
<commit_msg>chore: fix some more linting errors<commit_after>'use strict';

const spawn = require('../../index');

function isForceShell(method) {
    return /-force-shell$/.test(method);
}

function isMethodSync(method) {
    return /^sync(-|$)/.test(method);
}

function resolveRun(exitCode, stdout, stderr) {
    stdout = stdout && stdout.toString();
    stderr = stderr && stderr.toString();

    if (exitCode !== 0) {
        return Object.assign(new Error(`Command failed, exited with code #${exitCode}`), {
            exitCode,
            stdout,
            stderr,
        });
    }

    return {
        stdout,
        stderr,
    };
}

function runSync(command, args, options) {
    const { error, status, stdout, stderr } = spawn.sync(command, args, options);

    if (error) {
        throw error;
    }

    const resolved = resolveRun(status, stdout, stderr);

    if (resolved instanceof Error) {
        throw resolved;
    }

    return resolved;
}

function runAsync(command, args, options) {
    const cp = spawn(command, args, options);

    const promise = new Promise((resolve, reject) => {
        let stdout = null;
        let stderr = null;

        cp.stdout && cp.stdout.on('data', (data) => {
            stdout = stdout || new Buffer('');
            stdout = Buffer.concat([stdout, data]);
        });

        cp.stderr && cp.stderr.on('data', (data) => {
            stderr = stderr || new Buffer('');
            stderr = Buffer.concat([stderr, data]);
        });

        const cleanupListeners = () => {
            cp.removeListener('error', onError);
            cp.removeListener('close', onClose);
        };

        const onError = (err) => {
            cleanupListeners();
            reject(err);
        };

        const onClose = (code) => {
            cleanupListeners();

            const resolved = resolveRun(code, stdout, stderr);

            if (resolved instanceof Error) {
                reject(resolved);
            } else {
                resolve(resolved);
            }
        };

        cp
        .on('error', onError)
        .on('close', onClose);
    });

    promise.cp = cp;

    return promise;
}

function run(method, command, args, options) {
    // Are we forcing the shell?
    if (isForceShell(method)) {
        if (args && !Array.isArray(args)) {
            options = args;
            args = null;
        }

        method = method.replace(/-force-shell$/, '');
        options = { forceShell: true, ...options };
    }

    // Run sync version
    return method === 'sync' ?
        runSync(command, args, options) :
        runAsync(command, args, options);
}

module.exports = run;
module.exports.methods = ['spawn-force-shell', 'spawn', 'sync-force-shell', 'sync'];
module.exports.isMethodSync = isMethodSync;
module.exports.isForceShell = isForceShell;
<|endoftext|>


<commit_before>
// SmoothScroll v0.9.1
// Licensed under the terms of the MIT license.

// People involved
// - Balazs Galambosi: maintainer (CHANGELOG.txt)
// - Patrick Brunner (patrickb1991@gmail.com)
// - Michael Herf: Pulse Algorithm
// - Frank Yan: Direction Switching Fixes
// - Ismael Barros: Keyboard Fixes

// Frame Variables
var frame         = false;
var noscrollframe = false;

// Scroll Variables (tweakable)
var framerate = 50;  // [Hz]
var animtime  = 400; // [px]
var stepsize  = 120; // [px]

// Pulse (less tweakable)
// ratio of 'tail' to 'acceleration'
var pulseAlgorithm = true;
var pulseScale     = 8;
var pulseNormalize = 1;

// Keyboard Settings
var keyboardsupport = true;
var disableKeyboard = false;
var arrowscroll     = 50; // [px]

// Excluded pages
var exclude = "";

// Arrays of timeouts
var up   = [];
var down = [];

// Other Variables
var scrolls;
var deltaX = 0;
var deltaY = 0;
var initdone = false;
var activeElement;

var key = { up: 38, down: 40, spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36 };

/***********************************************
 * SETTINGS
 ***********************************************/

chrome.extension.connect({ name: "smoothscroll" }).
onMessage.addListener(function (settings) {

    // NOTE: + converts to {Number}
    framerate = +settings.framerate;
    animtime  = +settings.animtime;
    stepsize  = +settings.scrollsz;
    exclude   = settings.exclude;
    pulseAlgorithm  = (settings.pulseAlgorithm == "true");
    pulseScale      = +settings.pulseScale;
    keyboardsupport = (settings.keyboardsupport == "true");
    arrowscroll     = +settings.arrscroll;

    scrolls = setupScrolls();
    computePulseScale();

    // it seems that sometimes settings come late
    // and we need to test again for excluded pages
    initTest();

    if (keyboardsupport && !disableKeyboard) {
        addEvent("keydown", keydown, true);
    }

    // If extension settings were deleted somehow
    if (!framerate) {
        alert("SmoothScroll: Please restart Chrome");
    }
});

/***********************************************
 * INITIALIZE
 ***********************************************/

/**
 * Tests if smooth scrolling is allowed. Shuts down everything if not.
 */
function initTest() {

    // disable keys for google reader (spacebar conflict)
    if (document.URL.indexOf("google.com/reader/view") > -1) {
        disableKeyboard = true;
    }

    // disable everything if the page is blacklisted
    if (exclude) {
        var domains = exclude.split(/[,\n] ?/);
        for (var i = domains.length; i--;) {
            if (document.URL.indexOf(domains[i]) > -1) {
                removeEvent("mousewheel", wheel);
                disableKeyboard = true;
                break;
            }
        }
    }

    // disable keyboard support if anything above requested it
    if (disableKeyboard) {
        removeEvent("keydown", keydown, true);
    }
}

/**
 * Fills up the scrolls array with easing values.
 * Uses pulse to make it smooth.
 */
function setupScrolls() {

    scrolls = [];

    var last = 0;
    var frames = Math.floor(framerate * animtime / 1000);

    for (var i = 0; i < frames; i++) {
        // scroll is [0, 1]
        var scroll = (i + 1) / frames;
        // transform [0, 1] -> [0, 1]:
        if (pulseAlgorithm) {
           scroll = pulse(scroll);
        }

        // scale and quantize to int so our pixel difference works:
        var iscroll = Math.floor(stepsize * scroll + 0.99);
        scrolls.push(iscroll - last);
        last = iscroll;
    }

    return scrolls;
}

/**
 * Sets up scrolls array, determines if frames are involved.
 */
function init() {

    var body = document.body;
    activeElement = body;

    initTest();

    if (!scrolls) {
      scrolls = setupScrolls();
    }

    // Checks if this script is running in a frame
    if (top != self) {
        frame = true;
        // document.documentElement ?
        if (body.scrollHeight <= body.clientHeight + 10) {
            noscrollframe = true;
        }
    }

    /**
     * This fixes a bug where the areas left and right
     * to the content does not trigger the onmousewheel
     * event on some pages. Acid3 test is excluded.
     */
    if (document.URL !== "http://acid3.acidtests.org/") {
        var underlay = document.createElement('div');
        underlay.setAttribute( "style",
            "z-index: -1; position:absolute; top:0; left: 0; " +
            "width: 100%; height: " + body.scrollHeight + "px;" );
        body.appendChild(underlay);
    }
    initdone = true;
}

/************************************************
 * SCROLLING
 ************************************************/

/**
 * Pushes scroll actions to a given direction Array.
 */
function scrollArray(elem, dir, multiplyX, multiplyY, delay) {

    delay || (delay = 1000);
    clearTimeouts(dir === up ? down : up);

    function step() {

        var scale = scrolls[i++]; // linear or with easing

        // scroll left
        if (multiplyX && scale) {
            var lastLeft = elem.scrollLeft;
            elem.scrollLeft += multiplyX * scale;

            // scroll left failed (edge)
            if (elem.scrollLeft === lastLeft) {
                multiplyX = 0;
            }
        }

        // scroll top
        if (multiplyY && scale) {
            var lastTop = elem.scrollTop;
            elem.scrollTop += multiplyY * scale;

            // scroll top failed (edge)
            if (elem.scrollTop === lastTop) {
                multiplyY = 0;
            }
        }

        // clean up if there's nothing left to do
        if (!multiplyX && !multiplyY) {
            clearTimeouts(dir);
        }
    }

    // populate directions array
    for (var i = scrolls.length; i--;) {
        dir.push(setTimeout(step, i * delay / framerate + 1));
    }
    i = 0; // reset so that step() can increment again
}

/***********************************************
 * EVENTS
 ***********************************************/

/**
 * Mouse wheel handler.
 * NOTE: function logic should be decomposed.
 * @param {Object} event
 */
function wheel(event) {

    if (!initdone) {
        init();
    }

    activeElement = event.target;

    // use default if there's no overflowing
    // element or the target is an <embed>
    var elem = overflowingAncestor(event.target);
    if (!elem || (frame && noscrollframe) ||
        isNodeName(event.target, "embed")) {
        return true;
    }

    deltaX = event.wheelDeltaX || 0;
    deltaY = event.wheelDeltaY || 0;

    // normalize deltas
    deltaX /= 120;
    deltaY /= 120;

    // synaptics seems to send 1 sometimes,
    // and 120 other times (fix)
    if (Math.abs(deltaX) < 0.01) {
        deltaX *= 120;
    }
    if (Math.abs(deltaY) < 0.01) {
        deltaY *= 120;
    }

    var dir = (deltaY > 0) ? up : down;
    scrollArray(elem, dir, -deltaX, -deltaY);
    event.preventDefault();
}

/**
 * Keydown event handler.
 * @param {Object} event
 */
function keydown(event) {

    var target   = event.target;
    var modifier = event.ctrlKey || event.altKey || event.metaKey;

    // do nothing if user is editing text
    // or using a modifier key (except shift)
    if ( /input|textarea|embed/i.test(target.nodeName) ||
         target.isContentEditable ||
         modifier ) {
      return true;
    }
    // spacebar should trigger button press
    if (isNodeName(target, "button") &&
        event.keyCode === key.spacebar) {
      return true;
    }

    var scale, dir, shift;
    var elem = overflowingAncestor(activeElement);
    var clientHeight = elem.clientHeight;

    if (elem == document.body) {
        clientHeight = window.innerHeight;
    }

    switch (event.keyCode) {
        case key.up:
            scale = -arrowscroll;
            dir = up;
            break;
        case key.down:
            scale = arrowscroll;
            dir = down;
            break;
        case key.spacebar: // (+ shift)
            shift = event.shiftKey ? 1 : -1;
            scale = -shift * clientHeight * 0.9;
            dir = (shift > 0) ? up : down;
            break;
        case key.pageup:
            scale = -clientHeight * 0.9;
            dir = up;
            break;
        case key.pagedown:
            scale = clientHeight * 0.9;
            dir = down;
            break;
        case key.home:
            scale = -elem.scrollTop;
            dir = up;
            break;
        case key.end:
            var damt = elem.scrollHeight - elem.scrollTop - clientHeight;
            scale = (damt > 0) ? damt : 0;
            dir = down;
            break;
        default:
            return true; // a key we don't care about
    }
    scale /= stepsize;
    scale = (scale > 0) ? Math.ceil(scale) : Math.floor(scale);
    scrollArray(elem, dir, 0, scale);
    event.preventDefault();
}

/***********************************************
 * HELPERS
 ***********************************************/

function addEvent(type, fn, bubble) {
    window.addEventListener(type, fn, (bubble||false));
}

function removeEvent(type, fn, bubble) {
    window.removeEventListener(type, fn, (bubble||false));
}

function isNodeName(el, tag) {
    return el.nodeName.toLowerCase() === tag.toLowerCase();
}

function clearTimeouts(array) {
    while (array.length) {
        clearTimeout(array.pop());
    }
}

function overflowingAncestor(el) {
    var bodyScrollHeight = document.body.scrollHeight;
    do {
        if (bodyScrollHeight === el.scrollHeight) {
            return document.body;
        }
        else if (el.clientHeight + 10 < el.scrollHeight) {
            overflow = getComputedStyle(el, "").getPropertyValue("overflow");
            if (overflow === "scroll" || overflow === "auto") {
                return el;
            }
        }
    } while (el = el.parentNode);
}

/***********************************************
 * PULSE
 ***********************************************/

/**
 * Viscous fluid with a pulse for part and decay for the rest.
 * - Applies a fixed force over an interval (a damped acceleration), and
 * - Lets the exponential bleed away the velocity over a longer interval
 * - Michael Herf, http://stereopsis.com/stopping/
 */
function pulse_(x) {
    var val, start, expx;
    // test
    x = x * pulseScale;
    if (x < 1) { // acceleartion
        val = x - (1 - Math.exp(-x));
    } else {     // tail
        // the previous animation ended here:
        start = Math.exp(-1);
        // simple viscous drag
        x -= 1;
        expx = 1 - Math.exp(-x);
        val = start + (expx * (1 - start));
    }
    return val * pulseNormalize;
}

function computePulseScale() {
    pulseNormalize = 1 / pulse_(1);
}

/**
 * Viscous fluid with a pulse for part and decay for the rest
 */
function pulse(x) {
    if (x >= 1) return 1;
    if (x <= 0) return 0;

    if (pulseNormalize == 1) {
        computePulseScale();
    }
    return pulse_(x);
}

/**
 * Mousedown event only for updating activeElement
 */
function mousedown(event) {
    activeElement = event.target;
}

addEvent("mousedown", mousedown);
addEvent("mousewheel", wheel);
addEvent("DOMContentLoaded", init);
<commit_msg>removed default action for <embed>. We listen for e.defaultPrevented instead. Key handling stays the same.<commit_after>
// SmoothScroll v0.9.1
// Licensed under the terms of the MIT license.

// People involved
// - Balazs Galambosi: maintainer (CHANGELOG.txt)
// - Patrick Brunner (patrickb1991@gmail.com)
// - Michael Herf: Pulse Algorithm
// - Frank Yan: Direction Switching Fixes
// - Ismael Barros: Keyboard Fixes

// Frame Variables
var frame         = false;
var noscrollframe = false;

// Scroll Variables (tweakable)
var framerate = 50;  // [Hz]
var animtime  = 400; // [px]
var stepsize  = 120; // [px]

// Pulse (less tweakable)
// ratio of 'tail' to 'acceleration'
var pulseAlgorithm = true;
var pulseScale     = 8;
var pulseNormalize = 1;

// Keyboard Settings
var keyboardsupport = true;
var disableKeyboard = false;
var arrowscroll     = 50; // [px]

// Excluded pages
var exclude = "";

// Arrays of timeouts
var up   = [];
var down = [];

// Other Variables
var scrolls;
var deltaX = 0;
var deltaY = 0;
var initdone = false;
var activeElement;

var key = { up: 38, down: 40, spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36 };

/***********************************************
 * SETTINGS
 ***********************************************/

chrome.extension.connect({ name: "smoothscroll" }).
onMessage.addListener(function (settings) {

    // NOTE: + converts to {Number}
    framerate = +settings.framerate;
    animtime  = +settings.animtime;
    stepsize  = +settings.scrollsz;
    exclude   = settings.exclude;
    pulseAlgorithm  = (settings.pulseAlgorithm == "true");
    pulseScale      = +settings.pulseScale;
    keyboardsupport = (settings.keyboardsupport == "true");
    arrowscroll     = +settings.arrscroll;

    scrolls = setupScrolls();
    computePulseScale();

    // it seems that sometimes settings come late
    // and we need to test again for excluded pages
    initTest();

    if (keyboardsupport && !disableKeyboard) {
        addEvent("keydown", keydown, true);
    }

    // If extension settings were deleted somehow
    if (!framerate) {
        alert("SmoothScroll: Please restart Chrome");
    }
});

/***********************************************
 * INITIALIZE
 ***********************************************/

/**
 * Tests if smooth scrolling is allowed. Shuts down everything if not.
 */
function initTest() {

    // disable keys for google reader (spacebar conflict)
    if (document.URL.indexOf("google.com/reader/view") > -1) {
        disableKeyboard = true;
    }

    // disable everything if the page is blacklisted
    if (exclude) {
        var domains = exclude.split(/[,\n] ?/);
        for (var i = domains.length; i--;) {
            if (document.URL.indexOf(domains[i]) > -1) {
                removeEvent("mousewheel", wheel);
                disableKeyboard = true;
                break;
            }
        }
    }

    // disable keyboard support if anything above requested it
    if (disableKeyboard) {
        removeEvent("keydown", keydown, true);
    }
}

/**
 * Fills up the scrolls array with easing values.
 * Uses pulse to make it smooth.
 */
function setupScrolls() {

    scrolls = [];

    var last = 0;
    var frames = Math.floor(framerate * animtime / 1000);

    for (var i = 0; i < frames; i++) {
        // scroll is [0, 1]
        var scroll = (i + 1) / frames;
        // transform [0, 1] -> [0, 1]:
        if (pulseAlgorithm) {
           scroll = pulse(scroll);
        }

        // scale and quantize to int so our pixel difference works:
        var iscroll = Math.floor(stepsize * scroll + 0.99);
        scrolls.push(iscroll - last);
        last = iscroll;
    }

    return scrolls;
}

/**
 * Sets up scrolls array, determines if frames are involved.
 */
function init() {

    var body = document.body;
    activeElement = body;

    initTest();

    if (!scrolls) {
      scrolls = setupScrolls();
    }

    // Checks if this script is running in a frame
    if (top != self) {
        frame = true;
        // document.documentElement ?
        if (body.scrollHeight <= body.clientHeight + 10) {
            noscrollframe = true;
        }
    }

    /**
     * This fixes a bug where the areas left and right
     * to the content does not trigger the onmousewheel
     * event on some pages. Acid3 test is excluded.
     */
    if (document.URL !== "http://acid3.acidtests.org/") {
        var underlay = document.createElement('div');
        underlay.setAttribute( "style",
            "z-index: -1; position:absolute; top:0; left: 0; " +
            "width: 100%; height: " + body.scrollHeight + "px;" );
        body.appendChild(underlay);
    }
    initdone = true;
}

/************************************************
 * SCROLLING
 ************************************************/

/**
 * Pushes scroll actions to a given direction Array.
 */
function scrollArray(elem, dir, multiplyX, multiplyY, delay) {

    delay || (delay = 1000);
    clearTimeouts(dir === up ? down : up);

    function step() {

        var scale = scrolls[i++]; // linear or with easing

        // scroll left
        if (multiplyX && scale) {
            var lastLeft = elem.scrollLeft;
            elem.scrollLeft += multiplyX * scale;

            // scroll left failed (edge)
            if (elem.scrollLeft === lastLeft) {
                multiplyX = 0;
            }
        }

        // scroll top
        if (multiplyY && scale) {
            var lastTop = elem.scrollTop;
            elem.scrollTop += multiplyY * scale;

            // scroll top failed (edge)
            if (elem.scrollTop === lastTop) {
                multiplyY = 0;
            }
        }

        // clean up if there's nothing left to do
        if (!multiplyX && !multiplyY) {
            clearTimeouts(dir);
        }
    }

    // populate directions array
    for (var i = scrolls.length; i--;) {
        dir.push(setTimeout(step, i * delay / framerate + 1));
    }
    i = 0; // reset so that step() can increment again
}

/***********************************************
 * EVENTS
 ***********************************************/

/**
 * Mouse wheel handler.
 * NOTE: function logic should be decomposed.
 * @param {Object} event
 */
function wheel(event) {

    if (!initdone) {
        init();
    }

    activeElement = event.target;

    // use default if there's no overflowing
    // element or the target is an <embed>
    var elem = overflowingAncestor(event.target);
    if (!elem || (frame && noscrollframe) ||
        event.defaultPrevented) {
        return true;
    }

    deltaX = event.wheelDeltaX || 0;
    deltaY = event.wheelDeltaY || 0;

    // normalize deltas
    deltaX /= 120;
    deltaY /= 120;

    // synaptics seems to send 1 sometimes,
    // and 120 other times (fix)
    if (Math.abs(deltaX) < 0.01) {
        deltaX *= 120;
    }
    if (Math.abs(deltaY) < 0.01) {
        deltaY *= 120;
    }

    var dir = (deltaY > 0) ? up : down;
    scrollArray(elem, dir, -deltaX, -deltaY);
    event.preventDefault();
}

/**
 * Keydown event handler.
 * @param {Object} event
 */
function keydown(event) {

    var target   = event.target;
    var modifier = event.ctrlKey || event.altKey || event.metaKey;

    // do nothing if user is editing text
    // or using a modifier key (except shift)
    if ( /input|textarea|embed/i.test(target.nodeName) ||
         target.isContentEditable ||
         event.defaultPrevented   ||
         modifier ) {
      return true;
    }
    // spacebar should trigger button press
    if (isNodeName(target, "button") &&
        event.keyCode === key.spacebar) {
      return true;
    }

    var scale, dir, shift;
    var elem = overflowingAncestor(activeElement);
    var clientHeight = elem.clientHeight;

    if (elem == document.body) {
        clientHeight = window.innerHeight;
    }

    switch (event.keyCode) {
        case key.up:
            scale = -arrowscroll;
            dir = up;
            break;
        case key.down:
            scale = arrowscroll;
            dir = down;
            break;
        case key.spacebar: // (+ shift)
            shift = event.shiftKey ? 1 : -1;
            scale = -shift * clientHeight * 0.9;
            dir = (shift > 0) ? up : down;
            break;
        case key.pageup:
            scale = -clientHeight * 0.9;
            dir = up;
            break;
        case key.pagedown:
            scale = clientHeight * 0.9;
            dir = down;
            break;
        case key.home:
            scale = -elem.scrollTop;
            dir = up;
            break;
        case key.end:
            var damt = elem.scrollHeight - elem.scrollTop - clientHeight;
            scale = (damt > 0) ? damt : 0;
            dir = down;
            break;
        default:
            return true; // a key we don't care about
    }
    scale /= stepsize;
    scale = (scale > 0) ? Math.ceil(scale) : Math.floor(scale);
    scrollArray(elem, dir, 0, scale);
    event.preventDefault();
}

/***********************************************
 * HELPERS
 ***********************************************/

function addEvent(type, fn, bubble) {
    window.addEventListener(type, fn, (bubble||false));
}

function removeEvent(type, fn, bubble) {
    window.removeEventListener(type, fn, (bubble||false));
}

function isNodeName(el, tag) {
    return el.nodeName.toLowerCase() === tag.toLowerCase();
}

function clearTimeouts(array) {
    while (array.length) {
        clearTimeout(array.pop());
    }
}

function overflowingAncestor(el) {
    var bodyScrollHeight = document.body.scrollHeight;
    do {
        if (bodyScrollHeight === el.scrollHeight) {
            return document.body;
        }
        else if (el.clientHeight + 10 < el.scrollHeight) {
            overflow = getComputedStyle(el, "").getPropertyValue("overflow");
            if (overflow === "scroll" || overflow === "auto") {
                return el;
            }
        }
    } while (el = el.parentNode);
}

/***********************************************
 * PULSE
 ***********************************************/

/**
 * Viscous fluid with a pulse for part and decay for the rest.
 * - Applies a fixed force over an interval (a damped acceleration), and
 * - Lets the exponential bleed away the velocity over a longer interval
 * - Michael Herf, http://stereopsis.com/stopping/
 */
function pulse_(x) {
    var val, start, expx;
    // test
    x = x * pulseScale;
    if (x < 1) { // acceleartion
        val = x - (1 - Math.exp(-x));
    } else {     // tail
        // the previous animation ended here:
        start = Math.exp(-1);
        // simple viscous drag
        x -= 1;
        expx = 1 - Math.exp(-x);
        val = start + (expx * (1 - start));
    }
    return val * pulseNormalize;
}

function computePulseScale() {
    pulseNormalize = 1 / pulse_(1);
}

/**
 * Viscous fluid with a pulse for part and decay for the rest
 */
function pulse(x) {
    if (x >= 1) return 1;
    if (x <= 0) return 0;

    if (pulseNormalize == 1) {
        computePulseScale();
    }
    return pulse_(x);
}

/**
 * Mousedown event only for updating activeElement
 */
function mousedown(event) {
    activeElement = event.target;
}

addEvent("mousedown", mousedown);
addEvent("mousewheel", wheel);
addEvent("DOMContentLoaded", init);
<|endoftext|>


<commit_before>(function () {
    "use strict";

    function FactoryHolder(name) {
        this.name = name;
        this.defer = Q.defer();
        this.promise = this.defer.promise;
    }

    FactoryHolder.prototype.resolve = function (factory) {
        this.defer.resolve(factory);
        this.resolved = true;
    };

    function getDependenciesFromSignature(func) {
        var m = /function(\s+\w+)?\s*\((\s*\w+\s*(,\s*\w+\s*)*)\)/i.exec(func.toString());
        if(m && m[2]) {
            return m[2].split(',').map(function (name) {
                return name.trim();
            });
        } else {
            return [];
        }
    }

    function ObjectManager() {
        this.objects = {};
        this.factories = {};
        this.stack = []; // TODO track resolution stack to give better errors
    }

    /**
     * Maps object names to URLs. This default implementation just appends '.js' to the object name. Please override this to customize.
     * @param name object name
     * @returns {string} url
     */
    ObjectManager.prototype.resolveUrl = function (name) {
        return name + '.js';
    };

    /**
     * Define a new object
     * @param name optional name for the object; defaults to the name of the file from which this function is called
     * @param deps optional dependencies: array of object names as string
     * @param func required factory function that will be called once to create an instance (singleton)
     */
    ObjectManager.prototype.define = function () {
        var name, deps, func;

        try {
            if(arguments.length >= 3) {
                name = arguments[0];
                deps = arguments[1];
                func = arguments[2];
                if(arguments.length > 3) {
                    console.warn('define has more than 3 arguments; they will be ignored!');
                }
                checkName();
                checkDeps();
                checkFunc();
            } else if(arguments.length == 2) {
                name = arguments[0];
                func = arguments[1];
                checkName();
                checkFunc();
                deps = getDependenciesFromSignature(func);
            } else if(arguments.length == 1) {
                func = arguments[0];
                checkFunc();
                if(!this.expectedName) {
                    throw "can't guess name";
                }
                name = this.expectedName;
                deps = getDependenciesFromSignature(func);
            } else {
                throw 'define should have 1 to 3 arguments';
            }

            this.defineInternal(name, deps, func);

            return true;
        } catch (msg) {
            console.error(msg + " - url: " + (this.currentUrl || 'unknown'));
            return false;
        }

        function checkName() {
            if(typeof name !== 'string') {
                throw 'name should be a string';
            }
        }

        function checkDeps() {
            if(!Array.isArray(deps)) {
                throw 'dependencies should be an array of strings';
            }
        }

        function checkFunc() {
            if(typeof func !== 'function') {
                throw 'factory function should be a function';
            }
        }
    };

    ObjectManager.prototype.defineInternal = function (name, deps, func) {
        if(this.factories[name]) {
            console.warn('overriding factory "' + name + '"');
        }
        var factory = new ObjectFactory(name, deps, func);

        var holder = this.factories[name];
        if(!holder) {
            holder = this.factories[name] = new FactoryHolder(name);
        }
        holder.resolve(factory);
    };

    /**
     * Register an existing object instance
     * @param name
     * @param object
     */
    ObjectManager.prototype.put = function (name, object) {
        this.objects[name] = Q(object);
    };

    /**
     * Get an object instance
     * @param name
     * @returns {*}
     */
    ObjectManager.prototype.get = function (name) {
        var promise = this.objects[name];
        if(!promise) {
            var mgr = this;
            promise = this.objects[name] = this.getFactory(name)
                .then(function (fact) {
                    return fact.create(mgr);
                });
        }
        return promise;
    };

    ObjectManager.prototype.getFactory = function (name) {
        var holder = this.factories[name];
        if(holder) {
            return holder.promise;
        } else {
            return this.loadFactory(name);
        }
    };

    ObjectManager.prototype.loadFactory = function (name) {
        var mgr = this;
        var holder = this.factories[name] = new FactoryHolder(name);
        var url = mgr.resolveUrl(name);
        ajaxGet(url)
            .then(function (code) {
                mgr.expectedName = name;
                mgr.currentUrl = url;
                eval('(function () {"use strict";' + code + '})();');
                mgr.expectedName = undefined;
                mgr.currentUrl = undefined;
                if(!holder.resolved) {
                    console.error('No object "' + name + '" defined in "' + url + '"');
                    holder.defer.reject();
                }
            })
            .catch(function () {
                console.error('Can\'t load "' + url + '"');
                holder.defer.reject();
            });
        return holder.promise;
    };

    function ObjectFactory(name, deps, func) {
        this.name = name;
        this.deps = deps;
        this.func = func;
    }

    ObjectFactory.prototype.create = function (mgr) {
        var func = this.func;
        var depObjsPromises = this.deps.map(function (name) {
            return mgr.get(name);
        });
        return Q.all(depObjsPromises).then(function (depObjs) {
            return func.apply(mgr, depObjs);
        });
    };

    /**
     * Perform an ajax GET request to fetch text.
     * This is a stripped version of Zepto's ajax function
     * @param url
     * @return {promise}
     */
    function ajaxGet(url){
        var def = Q.defer();
        var protocol = /^([\w-]+:)\/\//.test(url) ? RegExp.$1 : window.location.protocol;
        var xhr = new window.XMLHttpRequest();

        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                xhr.onreadystatechange = null;
                clearTimeout(abortTimeout);
                if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status === 0 && protocol == 'file:')) {
                    def.resolve(xhr.responseText);
                } else {
                    def.reject(xhr.statusText || 'abort');
                }
            }
        };

        xhr.open('GET', url);

        xhr.setRequestHeader('Accept', 'text/plain');

        var abortTimeout = setTimeout(function () {
            xhr.onreadystatechange = null;
            xhr.abort();
            def.reject('timeout');
        }, 5000);

        xhr.send();

        return def.promise;
    }

    window.objects = new ObjectManager();

})();<commit_msg>small improvements<commit_after>(function () {
    "use strict";

    function FactoryHolder(name) {
        this.name = name;
        this.defer = Q.defer();
        this.promise = this.defer.promise;
    }

    FactoryHolder.prototype.resolve = function (factory) {
        this.defer.resolve(factory);
        this.resolved = true;
    };

    function getDependenciesFromSignature(func) {
        var m = /function(\s+\w+)?\s*\((\s*\w+\s*(,\s*\w+\s*)*)\)/i.exec(func.toString());
        if(m && m[2]) {
            return m[2].split(',').map(function (name) {
                return name.trim();
            });
        } else {
            return [];
        }
    }

    function ObjectManager() {
        this.objects = {};
        this.factories = {};
    }

    /**
     * Maps object names to URLs. This default implementation just appends '.js' to the object name. Please override this to customize.
     * @param name object name
     * @returns {string} url
     */
    ObjectManager.prototype.resolveUrl = function (name) {
        return name + '.js';
    };

    /**
     * Define a new object
     * @param name optional name for the object; defaults to the name of the file from which this function is called
     * @param deps optional dependencies: array of object names as string
     * @param func required factory function that will be called once to create an instance (singleton)
     */
    ObjectManager.prototype.define = function () {
        var name, deps, func;

        try {
            if(arguments.length >= 3) {
                name = arguments[0];
                deps = arguments[1];
                func = arguments[2];
                if(arguments.length > 3) {
                    console.warn('define has more than 3 arguments; they will be ignored!');
                }
                checkName();
                checkDeps();
                checkFunc();
            } else if(arguments.length == 2) {
                name = arguments[0];
                func = arguments[1];
                checkName();
                checkFunc();
                deps = getDependenciesFromSignature(func);
            } else if(arguments.length == 1) {
                func = arguments[0];
                checkFunc();
                if(!this.expectedName) {
                    throw "can't guess name";
                }
                name = this.expectedName;
                deps = getDependenciesFromSignature(func);
            } else {
                throw 'define should have 1 to 3 arguments';
            }

            this.defineInternal(name, deps, func);

            return true;
        } catch (msg) {
            console.error(msg + " - url: " + (this.currentUrl || 'unknown'));
            return false;
        }

        function checkName() {
            if(typeof name !== 'string') {
                throw 'name should be a string';
            }
        }

        function checkDeps() {
            var msg = 'dependencies should be an array of strings';
            if(!Array.isArray(deps)) {
                throw msg;
            }
            deps.each(function (dep) {
                if(typeof dep !== 'string') {
                    throw msg;
                }
            });
        }

        function checkFunc() {
            if(typeof func !== 'function') {
                throw 'factory function should be a function';
            }
        }
    };

    ObjectManager.prototype.defineInternal = function (name, deps, func) {
        if(this.factories[name]) {
            console.warn('overriding factory "' + name + '"');
        }
        var factory = new ObjectFactory(name, deps, func);

        var holder = this.factories[name];
        if(!holder) {
            holder = this.factories[name] = new FactoryHolder(name);
        }
        holder.resolve(factory);
    };

    /**
     * Register an existing object instance
     * @param name
     * @param object
     */
    ObjectManager.prototype.put = function (name, object) {
        this.objects[name] = Q(object);
    };

    /**
     * Get an object instance
     * @param name
     * @returns {*}
     */
    ObjectManager.prototype.get = function (name) {
        var promise = this.objects[name];
        if(!promise) {
            var mgr = this;
            promise = this.objects[name] = this.getFactory(name)
                .then(function (fact) {
                    return fact.create(mgr);
                });
        }
        return promise;
    };

    ObjectManager.prototype.getFactory = function (name) {
        var holder = this.factories[name];
        if(holder) {
            return holder.promise;
        } else {
            return this.loadFactory(name);
        }
    };

    ObjectManager.prototype.loadFactory = function (name) {
        var mgr = this;
        var holder = this.factories[name] = new FactoryHolder(name);
        var url = mgr.resolveUrl(name);
        ajaxGet(url)
            .then(function (code) {
                mgr.expectedName = name;
                mgr.currentUrl = url;
                eval('(function () {"use strict";' + code + '})();');
                mgr.expectedName = undefined;
                mgr.currentUrl = undefined;
                if(!holder.resolved) {
                    console.error('No object "' + name + '" defined in "' + url + '"');
                    holder.defer.reject();
                }
            })
            .catch(function () {
                console.error('Can\'t load "' + url + '"');
                holder.defer.reject();
            });
        return holder.promise;
    };

    function ObjectFactory(name, deps, func) {
        this.name = name;
        this.deps = deps;
        this.func = func;
    }

    ObjectFactory.prototype.create = function (mgr) {
        var func = this.func;
        var depObjsPromises = this.deps.map(function (name) {
            return mgr.get(name);
        });
        return Q.all(depObjsPromises).then(function (depObjs) {
            return func.apply(mgr, depObjs);
        });
    };

    /**
     * Perform an ajax GET request to fetch text.
     * This is a stripped version of Zepto's ajax function
     * @param url
     * @return {promise}
     */
    function ajaxGet(url){
        var def = Q.defer();
        var protocol = /^([\w-]+:)\/\//.test(url) ? RegExp.$1 : window.location.protocol;
        var xhr = new window.XMLHttpRequest();

        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                xhr.onreadystatechange = null;
                clearTimeout(abortTimeout);
                if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status === 0 && protocol == 'file:')) {
                    def.resolve(xhr.responseText);
                } else {
                    def.reject(xhr.statusText || 'abort');
                }
            }
        };

        xhr.open('GET', url);

        xhr.setRequestHeader('Accept', 'text/plain');

        var abortTimeout = setTimeout(function () {
            xhr.onreadystatechange = null;
            xhr.abort();
            def.reject('timeout');
        }, 5000);

        xhr.send();

        return def.promise;
    }

    window.objects = new ObjectManager();

})();<|endoftext|>


<commit_before>  // Used to sync models to the server, it can be overriden to support, for example, HTML5 localStorage
  // Requires two parameters:
  //
  // - a method (fetch, create, update or destroy)
  //
  // - a model or a collection
  //
  // Using the third, optional, parameter you can pass options to it (in that case options for the Ajax call)
  KnockoutApp.Sync = function(method, model, _options){

    // Ensure jQuery is loaded
    if(typeof $ === 'undefined') throw "jQuery is necessary to make Ajax calls";

    var params = {},
        options = _options || {};

    params.dataType = 'json';

    params.error = function(){
      Utils.wrapError(arguments);
    };

    //Get the url of the model/collection (model.url or model.url())
    params.url = Utils.unwrapValue(model, 'url');

    switch(method){
      case 'fetch':
        params.type = 'GET';
        break;
      case 'create':
        params.type = 'POST';
        if(model.name){
          params.data = {};
          params.data[model.name] = model.toJSON();
        }else{
          params.data = model.toJSON();
        }
        break;
      case 'update':
        params.type = 'PUT';
        if(model.name){
          params.data = {};
          params.data[model.name] = model.toJSON();
        }else{
          params.data = model.toJSON();
        }
        break;
      case 'destroy':
        params.type = 'DELETE';
        break;
    }

    // Make and return an Ajax call merging the *options* object passed as the third parameter with the *params* object
    return $.ajax(ko.utils.extend(params, options));
  };
<commit_msg>error if missing url, comments rewritten<commit_after>  // Used to sync models to the server, it can be overriden to support, for example, HTML5 localStorage
  // Requires two parameters:
  //
  // - a method (fetch, create, update or destroy)
  //
  // - a model or a collection
  //
  // You can pass options to it using the third parameter (in that case the options will be passed to the ajax call)
  KnockoutApp.Sync = function(method, model, _options){

    // Ensure jQuery is loaded
    if(typeof $ === 'undefined') throw "jQuery is necessary to make Ajax calls";

    var params = {},
        options = _options || {};

    params.dataType = 'json';

    // On error response calls KnockoutApp.Utils.wrapError
    params.error = function(){
      KnockoutApp.Utils.wrapError(arguments);
    };

    //Get the url of the model/collection (model.url or model.url())
    params.url = Utils.unwrapValue(model, 'url');

    // If params.url isn't defined throw an error
    if(!params.url) throw "Url property must be defined in model/collection when using KnockoutApp.Sync";

    switch(method){
      case 'fetch':
        params.type = 'GET';
        break;
      case 'create':
        params.type = 'POST';
        if(model.name){
          params.data = {};
          // If model.name property is set wrap model.toJSON() in an object model.name
          params.data[model.name] = model.toJSON();
        }else{
          params.data = model.toJSON();
        }
        break;
      case 'update':
        params.type = 'PUT';
        if(model.name){
          params.data = {};
          // If model.name property is set wrap model.toJSON() in an object model.name
          params.data[model.name] = model.toJSON();
        }else{
          params.data = model.toJSON();
        }
        break;
      case 'destroy':
        params.type = 'DELETE';
        break;
    }

    // Make and return an Ajax call merging the options object passed as the third parameter with the *params* object
    return $.ajax(ko.utils.extend(params, options));
  };
<|endoftext|>


<commit_before>{
options:
{
  attribution: 'ベクトルタイル',maxNativeZoom: 2
},
geojsonOptions:
{
   pointToLayer: function (feature, latlng) {
    var s = {};
    for(name in feature.properties) {
     if(name.match(/^_/) && !name.match(/_markerType/)){
      if( feature.properties['_markerType']=='Circle' && name =='_radius'){continue;}
      s[name.substr(1)]=feature.properties[name];
     }
    }
    if(feature.properties['_markerType']=='Icon'){
         var myIcon = L.icon(s);
         return L.marker(latlng, {icon: myIcon});
    }
    if(feature.properties['_markerType']=='DivIcon'){
         var myIcon = L.divIcon(s);
         return L.marker(latlng, {icon: myIcon});
    }
    if(feature.properties['_markerType']=='Circle'){
        return L.circle(latlng,feature.properties['_radius'],s);
    }
    if(feature.properties['_markerType']=='CircleMarker'){
        return L.circleMarker(latlng,s);
    }
   },
   style: function (feature) {
     if(!feature.properties['_markerType']){
       var s = {};
       for(name in feature.properties) {
        if(name.match(/^_/) && !name.match(/_markerType/)){
         if( feature.properties['_markerType']=='Circle' && name =='_radius'){continue;}
         s[name.substr(1)]=feature.properties[name];
        }
       }
       return s;
     }
   },
   onEachFeature: function (feature, layer) {
    var s = ''
    for(name in feature.properties) {
     if(!name.match(/^_/)){
      if(name=="name"){
       s += "" + feature.properties[name] + "
";
      }else{
       s += "" + name + "：" + feature.properties[name] + "
";
      }
     }
   }

    layer.on('click', function(e) {
      $.ajax({
           //crossDomain: true,
           type: "POST",
           //cache: false,
           //contentType:'application/json',
           url: "https://qrb5uht5ta.execute-api.ap-northeast-1.amazonaws.com/prod/s3iot2",
           data: JSON.stringify({"key1":"oppai"}),
           //dataType: 'json',
           success: function(ret){

               console.log(JSON.stringify(ret));
               var pop = layer.bindPopup('something else');
               pop.openPopup();
           }
       });
    });
    //layer.bindPopup(s);
   }
}
}
<commit_msg>change<commit_after>{
options:
{
  attribution: 'ベクトルタイル',maxNativeZoom: 2
},
geojsonOptions:
{
   pointToLayer: function (feature, latlng) {
    var s = {};
    for(name in feature.properties) {
     if(name.match(/^_/) && !name.match(/_markerType/)){
      if( feature.properties['_markerType']=='Circle' && name =='_radius'){continue;}
      s[name.substr(1)]=feature.properties[name];
     }
    }
    if(feature.properties['_markerType']=='Icon'){
         var myIcon = L.icon(s);
         return L.marker(latlng, {icon: myIcon});
    }
    if(feature.properties['_markerType']=='DivIcon'){
         var myIcon = L.divIcon(s);
         return L.marker(latlng, {icon: myIcon});
    }
    if(feature.properties['_markerType']=='Circle'){
        return L.circle(latlng,feature.properties['_radius'],s);
    }
    if(feature.properties['_markerType']=='CircleMarker'){
        return L.circleMarker(latlng,s);
    }
   },
   style: function (feature) {
     if(!feature.properties['_markerType']){
       var s = {};
       for(name in feature.properties) {
        if(name.match(/^_/) && !name.match(/_markerType/)){
         if( feature.properties['_markerType']=='Circle' && name =='_radius'){continue;}
         s[name.substr(1)]=feature.properties[name];
        }
       }
       return s;
     }
   },
   onEachFeature: function (feature, layer) {
    var s = ''
    for(name in feature.properties) {
     if(!name.match(/^_/)){
      if(name=="name"){
       s += "" + feature.properties[name] + "
";
      }else{
       s += "" + name + "：" + feature.properties[name] + "
";
      }
     }
   }

    layer.on('click', function(e) {
      $.ajax({
           //crossDomain: true,
           type: "POST",
           //cache: false,
           //contentType:'application/json',
           url: "https://qrb5uht5ta.execute-api.ap-northeast-1.amazonaws.com/prod/s3iot2",
           data: JSON.stringify({"key1":"oppai"}),
           //dataType: 'json',
           success: function(ret){

               console.log(JSON.stringify(ret));
               var pop = layer.bindPopup(JSON.stringify(ret));
               pop.openPopup();
           }
       });
    });
    //layer.bindPopup(s);
   }
}
}
<|endoftext|>


<commit_before>
var filteredWordsContainer = document.getElementById("filtered-words");
var addWordBtn = document.getElementById("add-word");
var newWord = document.getElementById("new-word");
var searchInput = document.getElementById("search");
var loadedData = [""];

// loading saved data
load();
addWordBtn.addEventListener("click", addSpecifiedWord);

// triggered when search value's changed
searchInput.addEventListener("input", search);

document.onkeydown = processKeys;

/**
 * adds a new word
 * specified in the input field
 */
function addSpecifiedWord()
{
	var text = newWord.value;
	if (text == "")
	{
		alert("Cannot add an empty value!");
		return;
	}
	addWord(text, loadedData.length);
	loadedData.push(text);
	save(text);
	newWord.value = "";
}

/**
 * saves the filtered word list content
 * and reloads the word list on the other files
 */
function save()
{
	chrome.storage.sync.set({
		"filter": loadedData
	});

	// background.js
	chrome.runtime.sendMessage({
		"action": "reload-data"
	});
}

/**
 * deletes the specified word form
 * the list
 */
function deleteWord()
{
	var entryContainer = this.parentElement;
	var index = getIndexInParent(entryContainer);

	// deleting data entry
	loadedData.splice(index, 1);

	// deleting the visual element for the entry
	entryContainer.remove();

	save();
}

/**
 * takes the element's parent
 * and finds at which index it is located inside it
 */
function getIndexInParent(element)
{
	var parent = element.parentElement;
	for (let i = 0; i < parent.childNodes.length; i++)
	{
		if (parent.childNodes[i] == element)
			return i;
	}
	return -1;
}

/*
 * creates an entry for the word
 * container, delete button, text field and stuff
 */
function addWord(text, index)
{
	var container = document.createElement("div");
	container.dataset.index = index;

	var input = document.createElement("input");
	input.type = "text";
	input.readOnly = true;
	input.value = text;

	var deleteBtn = document.createElement("button");
	var textNode = document.createTextNode("Delete");
	deleteBtn.appendChild(textNode);
	deleteBtn.className = "opt-btn";
	deleteBtn.addEventListener("click", deleteWord);

	container.appendChild(input);
	container.appendChild(deleteBtn);
	filteredWordsContainer.appendChild(container);

}

function load()
{
	chrome.storage.sync.get("filter", update);
}

function update(data)
{
	loadedData = data.filter;
	for (let i = 0; i < loadedData.length; i++)
		addWord(loadedData[i], i);
}

function processKeys(e)
{
	if (e.keyCode == 13)
		addSpecifiedWord();
}

/**
 * searches for words that contain
 * the search input's value
 */
function search()
{
	var searchText = searchInput.value;

	// if input's empty
	// displaying everything
	if (searchText == "")
	{
		showAllFilteredWordEntries();
		return;
	}

	// hiding everything except the matched words
	for (let i = 0; i < loadedData.length; i++)
	{
		let entry = getFilteredWordEntry(i);
		var regx = new RegExp(searchText);
		if (regx.test(loadedData[i]))
			entry.hidden = false;
		else
			entry.hidden = true;
	}
}

/**
 * goes through filtered word list
 * and finds the one with the specified index
 */
function getFilteredWordEntry(index)
{
	var nodes = filteredWordsContainer.childNodes;
	for (let i = 0; i < nodes.length; i++)
	{
		if (nodes[i].dataset.index == index)
			return nodes[i];
	}
}

function showAllFilteredWordEntries()
{
	var nodes = filteredWordsContainer.childNodes;
	for (let i = 0; i < nodes.length; i++)
		nodes[i].hidden = false;
}

<commit_msg>fixed minor bug which caused newly added word to not get filtered from search on some occasions<commit_after>
var filteredWordsContainer = document.getElementById("filtered-words");
var addWordBtn = document.getElementById("add-word");
var newWord = document.getElementById("new-word");
var searchInput = document.getElementById("search");
var loadedData = [""];

// loading saved data
load();
addWordBtn.addEventListener("click", addSpecifiedWord);

// triggered when search value's changed
searchInput.addEventListener("input", search);

document.onkeydown = processKeys;

/**
 * adds a new word
 * specified in the input field
 */
function addSpecifiedWord()
{
	var text = newWord.value;
	if (text == "")
	{
		alert("Cannot add an empty value!");
		return;
	}
	addWord(text, loadedData.length);
	loadedData.push(text);
	save(text);
	newWord.value = "";

	// necessary to filter out added word
	// if necessary
	search();
}

/**
 * saves the filtered word list content
 * and reloads the word list on the other files
 */
function save()
{
	chrome.storage.sync.set({
		"filter": loadedData
	});

	// background.js
	chrome.runtime.sendMessage({
		"action": "reload-data"
	});
}

/**
 * deletes the specified word form
 * the list
 */
function deleteWord()
{
	var entryContainer = this.parentElement;
	var index = getIndexInParent(entryContainer);

	// deleting data entry
	loadedData.splice(index, 1);

	// deleting the visual element for the entry
	entryContainer.remove();

	save();
}

/**
 * takes the element's parent
 * and finds at which index it is located inside it
 */
function getIndexInParent(element)
{
	var parent = element.parentElement;
	for (let i = 0; i < parent.childNodes.length; i++)
	{
		if (parent.childNodes[i] == element)
			return i;
	}
	return -1;
}

/*
 * creates an entry for the word
 * container, delete button, text field and stuff
 */
function addWord(text, index)
{
	var container = document.createElement("div");
	container.dataset.index = index;

	var input = document.createElement("input");
	input.type = "text";
	input.readOnly = true;
	input.value = text;

	var deleteBtn = document.createElement("button");
	var textNode = document.createTextNode("Delete");
	deleteBtn.appendChild(textNode);
	deleteBtn.className = "opt-btn";
	deleteBtn.addEventListener("click", deleteWord);

	container.appendChild(input);
	container.appendChild(deleteBtn);
	filteredWordsContainer.appendChild(container);

}

function load()
{
	chrome.storage.sync.get("filter", update);
}

function update(data)
{
	loadedData = data.filter;
	for (let i = 0; i < loadedData.length; i++)
		addWord(loadedData[i], i);
}

function processKeys(e)
{
	if (e.keyCode == 13)
		addSpecifiedWord();
}

/**
 * searches for words that contain
 * the search input's value
 */
function search()
{
	var searchText = searchInput.value;

	// if input's empty
	// displaying everything
	if (searchText == "")
	{
		showAllFilteredWordEntries();
		return;
	}

	// hiding everything except the matched words
	for (let i = 0; i < loadedData.length; i++)
	{
		let entry = getFilteredWordEntry(i);
		var regx = new RegExp(searchText);
		if (regx.test(loadedData[i]))
			entry.hidden = false;
		else
			entry.hidden = true;
	}
}

/**
 * goes through filtered word list
 * and finds the one with the specified index
 */
function getFilteredWordEntry(index)
{
	var nodes = filteredWordsContainer.childNodes;
	for (let i = 0; i < nodes.length; i++)
	{
		if (nodes[i].dataset.index == index)
			return nodes[i];
	}
}

function showAllFilteredWordEntries()
{
	var nodes = filteredWordsContainer.childNodes;
	for (let i = 0; i < nodes.length; i++)
		nodes[i].hidden = false;
}

<|endoftext|>


<commit_before>// conf.js
exports.config = {
  framework: 'jasmine',
  seleniumAddress: 'http://localhost:4444/wd/hub',
  capatibilities: {
    browserName: 'chrome',
    chromeOptions: {
      args: [
        '--window-workspace=3',
      ],
    },
  },
  specs: ['*.ls'],
};
<commit_msg>just some fixes<commit_after>// conf.js
exports.config = {
  framework: 'jasmine',
  seleniumAddress: 'http://localhost:4444/wd/hub',
  capabilities: {
    browserName: process.env.TEST_BROWSER || 'chrome',
    chromeOptions: {
      args: [
        '--window-workspace=3',
      ],
    },
  },
  specs: ['*.ls'],
};
<|endoftext|>


<commit_before>export var text = document.createTextNode.bind(document);
<commit_msg>Allow V8 to inline code here.<commit_after>export function text (content) {
  return document.createTextNode(content);
}
<|endoftext|>


<commit_before>/*global Tile */
import {Geo} from './geo';

export default class Tile {

    constructor(spec = {}) {
        Object.assign(this, {
            coords: {
                x: null,
                y: null,
                z: null
            },
            debug: {},
            loading: false,
            loaded: false,
            error: null
        }, spec);
    }

    static create(spec) { return new Tile(spec); }

    freeResources() {
        if (this != null && this.gl_geometry != null) {
            for (var p in this.gl_geometry) {
                this.gl_geometry[p].destroy();
            }
            this.gl_geometry = null;
        }
    }

    destroy() {
        this.freeResources();
        this.worker = null;
    }

    buildAsMessage() {
        return {
            key: this.key,
            coords: this.coords,
            min: this.min,
            max: this.max,
            debug: this.debug
        };
    }

    build(scene) {
        scene.trackTileBuildStart(this.key);
        scene.workerPostMessageForTile(this, {
            type: 'buildTile',
            tile: this.buildAsMessage(),
            tile_source: this.tile_source.buildAsMessage(),
            layers: scene.layers_serialized,
            styles: scene.styles_serialized
        });
    }

    remove(scene) {
        scene.workerPostMessageForTile(this, {
            type: 'removeTile',
            key: this.key
        });
    }

    /**
       Called on main thread when a web worker completes processing
       for a single tile.
    */
    buildGLGeometry(modes) {
        var vertex_data = this.vertex_data;
        // Cleanup existing GL geometry objects
        this.freeResources();
        this.gl_geometry = {};

        // Create GL geometry objects
        for (var s in vertex_data) {
            this.gl_geometry[s] = modes[s].makeGLGeometry(vertex_data[s]);
        }

        this.debug.geometries = 0;
        this.debug.buffer_size = 0;
        for (var p in this.gl_geometry) {
            this.debug.geometries += this.gl_geometry[p].geometry_count;
            this.debug.buffer_size += this.gl_geometry[p].vertex_data.byteLength;
        }
        this.debug.geom_ratio = (this.debug.geometries / this.debug.features).toFixed(1);

        delete this.vertex_data; // TODO: might want to preserve this for rebuilding geometries when styles/etc. change?
    }

    showDebug(div) {
        var debug_overlay = document.createElement('div');
        debug_overlay.textContent = this.key;
        debug_overlay.style.position = 'absolute';
        debug_overlay.style.left = 0;
        debug_overlay.style.top = 0;
        debug_overlay.style.color = 'white';
        debug_overlay.style.fontSize = '16px';
        debug_overlay.style.textOutline = '1px #000000';
        div.appendChild(debug_overlay);
        div.style.borderStyle = 'solid';
        div.style.borderColor = 'white';
        div.style.borderWidth = '1px';
        return debug_overlay;
    }

    updateElement(div, scene) {

        div.setAttribute('data-tile-key', this.key);

        div.style = {
            width: '256px',
            height: '256px'
        };

        if (scene.debug) {
            this.showDebug(div);
        }
    }

    // TODO: pass bounds only, rest of scene isn't needed
    updateVisibility(scene) {
        var visible = this.visible;
        this.visible = this.isInZoom(scene) && Geo.boxIntersect(this.bounds, scene.bounds_meters_buffered);
        this.center_dist = Math.abs(scene.center_meters.x - this.min.x) + Math.abs(scene.center_meters.y - this.min.y);
        return (visible !== this.visible);
    }

    // TODO: pass zoom only?
    isInZoom(scene) {
        return (Math.min(this.coords.z, this.tile_source.max_zoom || this.coords.z)) === scene.capped_zoom;
    }

    get key () {
        var {x, y, z} = this.tile_source.calculateOverZoom(this.coords);
        this.coords = {x, y, z};
        return [x, y, z].join('/');
    }

    load(scene, coords, div, cb) {

        scene.trackTileSetLoadStart();
        Object.assign(this, {
            coords: coords,
            min: Geo.metersForTile(coords),
            max: Geo.metersForTile({x: coords.x + 1, y: coords.y + 1, z: coords.z }),
            loading: true
        });

        this.span = { x: (this.max.x - this.min.x), y: (this.max.y - this.min.y) };
        this.bounds = { sw: { x: this.min.x, y: this.max.y }, ne: { x: this.max.x, y: this.min.y } };
        this.build(scene);
        this.updateElement(div, scene);
        this.updateVisibility(scene);

        if (cb) { cb(null, div); }
    }

    merge(other) {
        for (var key in other) {
            if (key !== 'key') {
                this[key] = other[key];
            }
        }
        return this;
    }

}
<commit_msg>safari (6) doesn't like assigning style property to new object<commit_after>/*global Tile */
import {Geo} from './geo';

export default class Tile {

    constructor(spec = {}) {
        Object.assign(this, {
            coords: {
                x: null,
                y: null,
                z: null
            },
            debug: {},
            loading: false,
            loaded: false,
            error: null
        }, spec);
    }

    static create(spec) { return new Tile(spec); }

    freeResources() {
        if (this != null && this.gl_geometry != null) {
            for (var p in this.gl_geometry) {
                this.gl_geometry[p].destroy();
            }
            this.gl_geometry = null;
        }
    }

    destroy() {
        this.freeResources();
        this.worker = null;
    }

    buildAsMessage() {
        return {
            key: this.key,
            coords: this.coords,
            min: this.min,
            max: this.max,
            debug: this.debug
        };
    }

    build(scene) {
        scene.trackTileBuildStart(this.key);
        scene.workerPostMessageForTile(this, {
            type: 'buildTile',
            tile: this.buildAsMessage(),
            tile_source: this.tile_source.buildAsMessage(),
            layers: scene.layers_serialized,
            styles: scene.styles_serialized
        });
    }

    remove(scene) {
        scene.workerPostMessageForTile(this, {
            type: 'removeTile',
            key: this.key
        });
    }

    /**
       Called on main thread when a web worker completes processing
       for a single tile.
    */
    buildGLGeometry(modes) {
        var vertex_data = this.vertex_data;
        // Cleanup existing GL geometry objects
        this.freeResources();
        this.gl_geometry = {};

        // Create GL geometry objects
        for (var s in vertex_data) {
            this.gl_geometry[s] = modes[s].makeGLGeometry(vertex_data[s]);
        }

        this.debug.geometries = 0;
        this.debug.buffer_size = 0;
        for (var p in this.gl_geometry) {
            this.debug.geometries += this.gl_geometry[p].geometry_count;
            this.debug.buffer_size += this.gl_geometry[p].vertex_data.byteLength;
        }
        this.debug.geom_ratio = (this.debug.geometries / this.debug.features).toFixed(1);

        delete this.vertex_data; // TODO: might want to preserve this for rebuilding geometries when styles/etc. change?
    }

    showDebug(div) {
        var debug_overlay = document.createElement('div');
        debug_overlay.textContent = this.key;
        debug_overlay.style.position = 'absolute';
        debug_overlay.style.left = 0;
        debug_overlay.style.top = 0;
        debug_overlay.style.color = 'white';
        debug_overlay.style.fontSize = '16px';
        debug_overlay.style.textOutline = '1px #000000';
        div.appendChild(debug_overlay);
        div.style.borderStyle = 'solid';
        div.style.borderColor = 'white';
        div.style.borderWidth = '1px';
        return debug_overlay;
    }

    updateElement(div, scene) {

        div.setAttribute('data-tile-key', this.key);

        div.style.width = '256px';
        div.style.height = '256px';

        if (scene.debug) {
            this.showDebug(div);
        }
    }

    // TODO: pass bounds only, rest of scene isn't needed
    updateVisibility(scene) {
        var visible = this.visible;
        this.visible = this.isInZoom(scene) && Geo.boxIntersect(this.bounds, scene.bounds_meters_buffered);
        this.center_dist = Math.abs(scene.center_meters.x - this.min.x) + Math.abs(scene.center_meters.y - this.min.y);
        return (visible !== this.visible);
    }

    // TODO: pass zoom only?
    isInZoom(scene) {
        return (Math.min(this.coords.z, this.tile_source.max_zoom || this.coords.z)) === scene.capped_zoom;
    }

    get key () {
        var {x, y, z} = this.tile_source.calculateOverZoom(this.coords);
        this.coords = {x, y, z};
        return [x, y, z].join('/');
    }

    load(scene, coords, div, cb) {

        scene.trackTileSetLoadStart();
        Object.assign(this, {
            coords: coords,
            min: Geo.metersForTile(coords),
            max: Geo.metersForTile({x: coords.x + 1, y: coords.y + 1, z: coords.z }),
            loading: true
        });

        this.span = { x: (this.max.x - this.min.x), y: (this.max.y - this.min.y) };
        this.bounds = { sw: { x: this.min.x, y: this.max.y }, ne: { x: this.max.x, y: this.min.y } };
        this.build(scene);
        this.updateElement(div, scene);
        this.updateVisibility(scene);

        if (cb) { cb(null, div); }
    }

    merge(other) {
        for (var key in other) {
            if (key !== 'key') {
                this[key] = other[key];
            }
        }
        return this;
    }

}
<|endoftext|>