<commit_before>var srcPath = __dirname + "./../../../lib/";

describe("webview", function () {

    var WebView,
        events = require(srcPath + "events"),
        chrome = require(srcPath + "chrome"),
        mockedQnx;

    beforeEach(function () {
        mockedQnx = {callExtensionMethod : jasmine.createSpy().andReturn(42)};
        GLOBAL.qnx = mockedQnx;
        WebView = require(srcPath + "WebView");
    });

    it("can create a webview instance", function () {
        var webview = new WebView();
        expect(webview.id).toEqual(jasmine.any(Number));
        expect(webview.windowGroup).toEqual(jasmine.any(Number));
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.applicationWindowGroup", chrome.id);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.create", jasmine.any(Number), "InProcess");
    });

    it("can create a webview with a specific id", function () {
        var options = {webviewId : 42},
            webview = new WebView(options);
        expect(webview.id).toEqual(42);
    });

    it("can create a webview instance that can be destroyed", function () {
        var webview = new WebView(),
            webviewId = webview.id;
        spyOn(events, "clear");
        webview.destroy();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.destroy", webview.id);
        expect(events.clear).toHaveBeenCalledWith(webviewId);
    });

    it("can create a webview instance that can set a url", function () {
        var webview = new WebView(),
            url = "http://www.google.com";
        webview.url = url;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.loadURL", jasmine.any(Number), url);
    });

    it("can create a webview instance that can get a URL", function () {
        var webview = new WebView();
        expect(webview.url).toBeDefined();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.location", webview.id);
    });

    it("has a READ ONLY originalLocation property", function () {
        var webview = new WebView(),
            originalLocation;
        expect(webview.originalLocation).toBeDefined();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.originalLocation", webview.id);
        originalLocation = webview.originalLocation;
        webview.originalLocation = "http://www.google.com";
        expect(webview.originalLocation).toEqual(originalLocation);
    });

    it("can create a webview instance that can execute javascript", function () {
        var webview = new WebView(),
            jsExpression = "var a = 'awesome';";
        webview.executeJavaScript(jsExpression);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.executeJavaScript", jasmine.any(Number), jsExpression, false);
    });

    it("can create a webview instance that can retrieve its visibility", function () {
        var webview = new WebView();
        expect(webview.visible).toBeDefined();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.isVisible", webview.id);
    });

    it("can create a webview instance that can have its visibility changed", function () {
        var webview = new WebView();
        webview.visible = true;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setVisible", webview.id, true);
        webview.visible = false;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setVisible", webview.id, false);
    });

    it("can create a webview instance that can retrieve its activity", function () {
        var webview = new WebView();
        expect(webview.active).toBeDefined();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.isActive", webview.id);
    });

    it("can create a webview instance that can have its activity changed", function () {
        var webview = new WebView();
        webview.active = true;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setActive", webview.id, true);
        webview.active = false;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setActive", webview.id, false);
    });

    it("can create a webview instance that can retrieve its zOrder", function () {
        var webview = new WebView();
        expect(webview.zOrder).toBeDefined();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.zOrder", webview.id);
    });

    it("can create a webview instance that can have it's zOrder changed", function () {
        var webview = new WebView();
        webview.zOrder = 0;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setZOrder", webview.id, 0);
        webview.zOrder = -99;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setZOrder", webview.id, -99);
    });

    it("can create a webview instance that can have its geometry set", function () {
        var webview = new WebView();
        webview.setGeometry(0, 0, 0, 0);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setGeometry", webview.id, 0, 0, 0, 0);
    });

    it("can create a webview instance that can have its background color set", function () {
        var webview = new WebView();
        webview.setBackgroundColor("0x00FFFF00");
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setBackgroundColor", webview.id, "0x00FFFF00");
    });

    it("can create a webview instance that can listen to events", function () {
        var webview = new WebView(),
            callback = function () {};
        spyOn(events, "on");
        webview.addEventListener("Created", callback);
        expect(events.on).toHaveBeenCalledWith(webview.id, "Created", callback);
    });

    it("can create a webview instance that can dispatch events", function () {
        var webview = new WebView(),
            callback = jasmine.createSpy(),
            args = ["one", "two", "many"];
        spyOn(events, "on").andCallThrough();
        webview.addEventListener("Created", callback);
        expect(events.on).toHaveBeenCalledWith(
            webview.id, "Created", callback);

        spyOn(events, "emit").andCallThrough();
        webview.dispatchEvent("Created", args);
        expect(events.emit).toHaveBeenCalledWith(
            webview.id, "Created", args);

        waits(1);
        runs(function () {
            expect(callback).toHaveBeenCalledWith(args[0], args[1], args[2]);
        });
    });

    it("can create a webview instance that can remove a single event listener", function () {
        var webview = new WebView(),
            eventType = "Created",
            callback = jasmine.createSpy();
        spyOn(events, "removeEventListener");
        webview.removeEventListener(eventType, callback);
        expect(events.removeEventListener).toHaveBeenCalledWith(webview.id, eventType, callback);
    });

    it("can create a webview instance that can have webinspector enabled", function () {
        var webview = new WebView();
        webview.enableWebInspector(true);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setEnableWebInspector", webview.id, true);
        webview.enableWebInspector(false);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setEnableWebInspector", webview.id, false);
    });

    it("can create a webview instance that can have crossSite XHR enabled", function () {
        var webview = new WebView();
        webview.enableCrossSiteXHR(true);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setEnableCrossSiteXHR", webview.id, true);
        webview.enableCrossSiteXHR(false);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setEnableCrossSiteXHR", webview.id, false);
    });
});
<commit_msg>Changed 'describe' in unit test to have proper capitalization<commit_after>var srcPath = __dirname + "./../../../lib/";

describe("WebView", function () {

    var WebView,
        events = require(srcPath + "events"),
        chrome = require(srcPath + "chrome"),
        mockedQnx;

    beforeEach(function () {
        mockedQnx = {callExtensionMethod : jasmine.createSpy().andReturn(42)};
        GLOBAL.qnx = mockedQnx;
        WebView = require(srcPath + "WebView");
    });

    it("can create a webview instance", function () {
        var webview = new WebView();
        expect(webview.id).toEqual(jasmine.any(Number));
        expect(webview.windowGroup).toEqual(jasmine.any(Number));
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.applicationWindowGroup", chrome.id);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.create", jasmine.any(Number), "InProcess");
    });

    it("can create a webview with a specific id", function () {
        var options = {webviewId : 42},
            webview = new WebView(options);
        expect(webview.id).toEqual(42);
    });

    it("can create a webview instance that can be destroyed", function () {
        var webview = new WebView(),
            webviewId = webview.id;
        spyOn(events, "clear");
        webview.destroy();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.destroy", webview.id);
        expect(events.clear).toHaveBeenCalledWith(webviewId);
    });

    it("can create a webview instance that can set a url", function () {
        var webview = new WebView(),
            url = "http://www.google.com";
        webview.url = url;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.loadURL", jasmine.any(Number), url);
    });

    it("can create a webview instance that can get a URL", function () {
        var webview = new WebView();
        expect(webview.url).toBeDefined();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.location", webview.id);
    });

    it("has a READ ONLY originalLocation property", function () {
        var webview = new WebView(),
            originalLocation;
        expect(webview.originalLocation).toBeDefined();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.originalLocation", webview.id);
        originalLocation = webview.originalLocation;
        webview.originalLocation = "http://www.google.com";
        expect(webview.originalLocation).toEqual(originalLocation);
    });

    it("can create a webview instance that can execute javascript", function () {
        var webview = new WebView(),
            jsExpression = "var a = 'awesome';";
        webview.executeJavaScript(jsExpression);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.executeJavaScript", jasmine.any(Number), jsExpression, false);
    });

    it("can create a webview instance that can retrieve its visibility", function () {
        var webview = new WebView();
        expect(webview.visible).toBeDefined();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.isVisible", webview.id);
    });

    it("can create a webview instance that can have its visibility changed", function () {
        var webview = new WebView();
        webview.visible = true;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setVisible", webview.id, true);
        webview.visible = false;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setVisible", webview.id, false);
    });

    it("can create a webview instance that can retrieve its activity", function () {
        var webview = new WebView();
        expect(webview.active).toBeDefined();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.isActive", webview.id);
    });

    it("can create a webview instance that can have its activity changed", function () {
        var webview = new WebView();
        webview.active = true;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setActive", webview.id, true);
        webview.active = false;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setActive", webview.id, false);
    });

    it("can create a webview instance that can retrieve its zOrder", function () {
        var webview = new WebView();
        expect(webview.zOrder).toBeDefined();
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.zOrder", webview.id);
    });

    it("can create a webview instance that can have it's zOrder changed", function () {
        var webview = new WebView();
        webview.zOrder = 0;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setZOrder", webview.id, 0);
        webview.zOrder = -99;
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setZOrder", webview.id, -99);
    });

    it("can create a webview instance that can have its geometry set", function () {
        var webview = new WebView();
        webview.setGeometry(0, 0, 0, 0);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setGeometry", webview.id, 0, 0, 0, 0);
    });

    it("can create a webview instance that can have its background color set", function () {
        var webview = new WebView();
        webview.setBackgroundColor("0x00FFFF00");
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setBackgroundColor", webview.id, "0x00FFFF00");
    });

    it("can create a webview instance that can listen to events", function () {
        var webview = new WebView(),
            callback = function () {};
        spyOn(events, "on");
        webview.addEventListener("Created", callback);
        expect(events.on).toHaveBeenCalledWith(webview.id, "Created", callback);
    });

    it("can create a webview instance that can dispatch events", function () {
        var webview = new WebView(),
            callback = jasmine.createSpy(),
            args = ["one", "two", "many"];
        spyOn(events, "on").andCallThrough();
        webview.addEventListener("Created", callback);
        expect(events.on).toHaveBeenCalledWith(
            webview.id, "Created", callback);

        spyOn(events, "emit").andCallThrough();
        webview.dispatchEvent("Created", args);
        expect(events.emit).toHaveBeenCalledWith(
            webview.id, "Created", args);

        waits(1);
        runs(function () {
            expect(callback).toHaveBeenCalledWith(args[0], args[1], args[2]);
        });
    });

    it("can create a webview instance that can remove a single event listener", function () {
        var webview = new WebView(),
            eventType = "Created",
            callback = jasmine.createSpy();
        spyOn(events, "removeEventListener");
        webview.removeEventListener(eventType, callback);
        expect(events.removeEventListener).toHaveBeenCalledWith(webview.id, eventType, callback);
    });

    it("can create a webview instance that can have webinspector enabled", function () {
        var webview = new WebView();
        webview.enableWebInspector(true);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setEnableWebInspector", webview.id, true);
        webview.enableWebInspector(false);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setEnableWebInspector", webview.id, false);
    });

    it("can create a webview instance that can have crossSite XHR enabled", function () {
        var webview = new WebView();
        webview.enableCrossSiteXHR(true);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setEnableCrossSiteXHR", webview.id, true);
        webview.enableCrossSiteXHR(false);
        expect(mockedQnx.callExtensionMethod).toHaveBeenCalledWith("webview.setEnableCrossSiteXHR", webview.id, false);
    });
});
<|endoftext|>


<commit_before>import finput from '../../src/finput';

describe('setRawValue', () => {

    let element;
    let destroy;

    beforeEach(() => {
        element = document.createElement('input');
        destroy = finput(element);
    });

    afterEach(() => {
        destroy();
    });

    it('when passed 0 sets value 0', () => {
        element.setRawValue(0);
        expect(element.value).toBe('0.00');
    });

    it('has an initial value of empty string and rawValue of undefined', () => {
        expect(element.value).toBe('');
        expect(element.rawValue).toBe(undefined);
    });

    it('resets back to empty string and undefined when entry is deleted', () => {
        element.setRawValue(100);
        element.setRawValue('');

        expect(element.value).toBe('');
        expect(element.rawValue).toBe(undefined);
    });

});
<commit_msg>fix: setRawValue tests<commit_after>import finput from '../../dist/finput';

describe('setRawValue', () => {

    let element;
    let api;

    beforeEach(() => {
        element = document.createElement('input');
        api = finput(element);
    });

    afterEach(() => {
        api.destroy();
    });

    it('when passed 0 sets value 0', () => {
        api.setRawValue(0);
        expect(element.value).toBe('0.00');
    });

    it('has an initial value of empty string and rawValue of undefined', () => {
        expect(element.value).toBe('');
        expect(api.rawValue).toBe(undefined);
    });

    it('resets back to empty string and undefined when entry is deleted', () => {
        api.setRawValue(100);
        api.setRawValue('');

        expect(element.value).toBe('');
        expect(api.rawValue).toBe(undefined);
    });

});
<|endoftext|>


<commit_before>'use strict'

const assert = require('assert')
const { Application } = require('spectron')

describe('Opening windows', function() {
  this.timeout(15000)

  // Encode to allow comparison with getURL
  const soundcleodURL = encodeURI(`file://${__dirname}/window-open.html`)

  beforeEach(function() {
    this.app = new Application({
      args: [ 'app/main.js' ],
      env: {
        NODE_ENV: 'test',
        SOUNDCLEOD_PROFILE: 'test',
        SOUNDCLEOD_URL: soundcleodURL
      },
      path: 'node_modules/.bin/electron',
      requireName: 'electronRequire'
    })
    return this.app.start()
  })

  afterEach(function() {
    if (this.app && this.app.isRunning())
      return this.app.stop()
  })

  it('opens external link in browser', function() {
    return this.app.client
      .click('=external no target')
      .then(() => this.app.client.getWindowCount())
      .then(count => assert.equal(count, 1, 'opened no new window'))
      // Should verify URL, but:
      // https://github.com/electron/spectron/issues/64
      //.then(() => this.app.webContents.getURL())
      //.then(url => assert.equal(url, soundcleodURL))
  })

  it('opens internal link in main window', function() {
    return this.app.client
      .click('=internal no target')
      .then(() => this.app.client.getWindowCount())
      .then(count => assert.equal(count, 1, 'opened no new window'))
      // Should verify URL, but:
      // https://github.com/electron/spectron/issues/64
      //.then(() => this.app.webContents.getURL())
      //.then(url => assert.equal(url, 'https://soundcloud.com/robots.txt'))
  })

  it('opens Facebook login in main window', function() {
    return this.app.client
      .click('=Facebook login')
      .then(() => this.app.client.getWindowCount())
      .then(count => assert.equal(count, 1, 'opened no new window'))
      .waitForExist('#facebook')
  })

  xit('opens window.open with no options in browser', function() {
    return this.app.client
      .click('=window.open no options')
      .then(() => this.app.client.getWindowCount())
      .then(count => assert.equal(count, 1, 'opened no new window'))
      // Should verify URL, but:
      // https://github.com/electron/spectron/issues/64
      //.then(() => this.app.webContents.getURL())
      //.then(url => assert.equal(url, soundcleodURL))
  })

  it('opens window.open with options in popup', function() {
    return this.app.client
      .click('=window.open with options')
      .then(() => this.app.client.getWindowCount())
      .then(count => assert.equal(count, 2, 'opened new window'))
      // Should verify URL, but:
      // https://github.com/electron/spectron/issues/64
      //.then(() => this.app.webContents.getURL())
      //.then(url => assert.equal(url, soundcleodURL))
  })
})
<commit_msg>Decrease test flakyness<commit_after>'use strict'

const assert = require('assert')
const { Application } = require('spectron')

describe('Opening windows', function() {
  this.timeout(15000)

  // Encode to allow comparison with getURL
  const soundcleodURL = encodeURI(`file://${__dirname}/window-open.html`)

  beforeEach(function() {
    this.app = new Application({
      args: [ 'app/main.js' ],
      env: {
        NODE_ENV: 'test',
        SOUNDCLEOD_PROFILE: 'test',
        SOUNDCLEOD_URL: soundcleodURL
      },
      path: 'node_modules/.bin/electron',
      requireName: 'electronRequire'
    })
    return this.app.start()
  })

  afterEach(function() {
    if (this.app && this.app.isRunning())
      return this.app.stop()
  })

  it('opens external link in browser', function() {
    return this.app.client
      .click('=external no target')
      .then(() => this.app.client.getWindowCount())
      .then(count => assert.equal(count, 1, 'opened no new window'))
      // Should verify URL, but:
      // https://github.com/electron/spectron/issues/64
      //.then(() => this.app.webContents.getURL())
      //.then(url => assert.equal(url, soundcleodURL))
  })

  it('opens internal link in main window', function() {
    return this.app.client
      .click('=internal no target')
      .then(() => this.app.client.getWindowCount())
      .then(count => assert.equal(count, 1, 'opened no new window'))
      // Should verify URL, but:
      // https://github.com/electron/spectron/issues/64
      //.then(() => this.app.webContents.getURL())
      //.then(url => assert.equal(url, 'https://soundcloud.com/robots.txt'))
  })

  it('opens Facebook login in main window', function() {
    return this.app.client
      .click('=Facebook login')
      .then(() => this.app.client.getWindowCount())
      .waitForExist('#facebook')
      .then(count => assert.equal(count, 1, 'opened no new window'))
  })

  xit('opens window.open with no options in browser', function() {
    return this.app.client
      .click('=window.open no options')
      .then(() => this.app.client.getWindowCount())
      .then(count => assert.equal(count, 1, 'opened no new window'))
      // Should verify URL, but:
      // https://github.com/electron/spectron/issues/64
      //.then(() => this.app.webContents.getURL())
      //.then(url => assert.equal(url, soundcleodURL))
  })

  it('opens window.open with options in popup', function() {
    return this.app.client
      .click('=window.open with options')
      .waitUntil(() => this.app.client.getWindowCount().then(count => count > 1))
      .then(() => this.app.client.getWindowCount())
      .then(count => assert.equal(count, 2, 'opened new window'))
      // Should verify URL, but:
      // https://github.com/electron/spectron/issues/64
      //.then(() => this.app.webContents.getURL())
      //.then(url => assert.equal(url, soundcleodURL))
  })
})
<|endoftext|>


<commit_before>var Helper = require('./test_helper'),
Sys = require('sys'),
HttpClient = require('../index'),
Log4js = require('log4js');

Log4js.addAppender(Log4js.consoleAppender());
var logger = Log4js.getLogger('wwwdude-redirect');
logger.setLevel('INFO');

client = HttpClient.createClient({
    logger: logger
  });

function _redirect(test, verb) {
  var server = Helper.redirectServer(),
  upCase = verb.replace(/del/, 'delete').toUpperCase();

  test.expect(20);

  var req = client[verb](server.url)
  .addListener('301', function (data, resp) {
      test.ok(data);
      test.ok(resp);
    })
  .addListener('redirect', function (data, resp) {
      var response = JSON.parse(data);
      test.ok(data, 'Data must be provided');
      test.ok(resp);
      test.strictEqual(resp.statusCode, 301);
      test.strictEqual(response.method, upCase);
      test.strictEqual(response.url, '/');
      test.strictEqual(response.headers['user-agent'], 'node-wwwdude');
      test.strictEqual(response.msg, 'Redirecting');
    })
  .addListener('200', function (data, resp) {
      test.ok(data);
      test.ok(resp);
    })
  .addListener('2XX', function (data, resp) {
      test.ok(data);
      test.ok(resp);
    })
  .addListener('success', function (data, resp) {
      var response = JSON.parse(data);
      test.ok(data, 'Data must be provided');
      test.ok(resp);
      test.strictEqual(resp.statusCode, 200);
      test.strictEqual(response.method, upCase);
      test.strictEqual(response.url, '/redirected');
      test.strictEqual(response.headers['user-agent'], 'node-wwwdude');
      test.strictEqual(response.msg, 'Been there, done that!');
      test.done();
    }).send();

  setTimeout(function () {
      test.done();
    }, 1000);

}

exports.simpleRedirect = {
  get: function (test) {
    _redirect(test, 'get');
  },
  put: function (test) {
    _redirect(test, 'put');
  },
  post: function (test) {
    _redirect(test, 'post');
  },
  del: function (test) {
    _redirect(test, 'del');
  }
};
<commit_msg>Refactoring wwwdude-redirect<commit_after>var Helper = require('./test_helper'),
Sys = require('sys'),
HttpClient = require('../index'),
Log4js = require('log4js');

Log4js.addAppender(Log4js.consoleAppender());
var logger = Log4js.getLogger('wwwdude-redirect');
logger.setLevel('INFO');

client = HttpClient.createClient({
    logger: logger
  });

function _redirect(test, verb) {
  var server = Helper.redirectServer(),
  upCase = verb.replace(/del/, 'delete').toUpperCase();

  test.expect(20);

  var req = client[verb](server.url)
  .on('301', function (data, resp) {
      test.ok(data);
      test.ok(resp);
    })
  .on('redirect', function (data, resp) {
      var response = JSON.parse(data);
      test.ok(data, 'Data must be provided');
      test.ok(resp);
      test.strictEqual(resp.statusCode, 301);
      test.strictEqual(response.method, upCase);
      test.strictEqual(response.url, '/');
      test.strictEqual(response.headers['user-agent'], 'node-wwwdude');
      test.strictEqual(response.msg, 'Redirecting');
    })
  .on('200', function (data, resp) {
      test.ok(data);
      test.ok(resp);
    })
  .on('2XX', function (data, resp) {
      test.ok(data);
      test.ok(resp);
    })
  .on('success', function (data, resp) {
      var response = JSON.parse(data);
      test.ok(data, 'Data must be provided');
      test.ok(resp);
      test.strictEqual(resp.statusCode, 200);
      test.strictEqual(response.method, upCase);
      test.strictEqual(response.url, '/redirected');
      test.strictEqual(response.headers['user-agent'], 'node-wwwdude');
      test.strictEqual(response.msg, 'Been there, done that!');
      test.done();
    }).send();

  setTimeout(function () {
      test.done();
    }, 1000);

}

exports.simpleRedirect = {
  get: function (test) {
    _redirect(test, 'get');
  },
  put: function (test) {
    _redirect(test, 'put');
  },
  post: function (test) {
    _redirect(test, 'post');
  },
  del: function (test) {
    _redirect(test, 'del');
  }
};
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import { shallow, mount } from 'enzyme';
import MenuBar from './MenuBar';

it('Menu Bar renders 7 menu items with no errors', () => {
  const wrapper = shallow(<MenuBar/>);
  expect(wrapper.find('MenuItem').length).toEqual(7);
});

// This runs into the "Invariant Violation: <Link>s rendered outside of a router context cannot navigate."
// error. This is fixed in `react-router` v4.0.0. See https://github.com/ReactTraining/react-router/issues/2051
// TODO: work around issue or re-enable when react-router v4 is released

// Integration test
// it('Clicking on MenuItem calls MenuBar handleClick method', () => {
//   const spy = spyOn(MenuBar.prototype, "closeMenu");
//   console.log(MenuBar.prototype);
//   const wrapper = mount(<MenuBar/>);
//   wrapper.find('Link').first().simulate('click');
//   expect(spy).toHaveBeenCalled();
// });
<commit_msg>increase number of MenuItems<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import { shallow, mount } from 'enzyme';
import MenuBar from './MenuBar';

it('Menu Bar renders 7 menu items with no errors', () => {
  const wrapper = shallow(<MenuBar/>);
  expect(wrapper.find('MenuItem').length).toEqual(8);
});

// This runs into the "Invariant Violation: <Link>s rendered outside of a router context cannot navigate."
// error. This is fixed in `react-router` v4.0.0. See https://github.com/ReactTraining/react-router/issues/2051
// TODO: work around issue or re-enable when react-router v4 is released

// Integration test
// it('Clicking on MenuItem calls MenuBar handleClick method', () => {
//   const spy = spyOn(MenuBar.prototype, "closeMenu");
//   console.log(MenuBar.prototype);
//   const wrapper = mount(<MenuBar/>);
//   wrapper.find('Link').first().simulate('click');
//   expect(spy).toHaveBeenCalled();
// });
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import MetadataBlock from '../shared/MetadataBlock';
import Radium from 'radium';

class Color extends React.Component {
  handleClick() {
    document.execCommand('copy');
  }
  render() {
    const {theme, colors, modifiers} = this.props;
    let styles = {
      container: {
        display: 'flex',
        alignItems: 'stretch',
        flexWrap: 'wrap',
        justifyContent: 'flex-start',
        margin: '20px 0',
        overflow: 'auto',
        flexBasis: '100%'
      },
      rows: {
        flexDirection: 'row'
      },
      columns: {
        flexDirection: 'column'
      },
      box: {
        display: 'flex',
        flex: '0 1 auto',
        justifyContent: 'flex-start',
        flexDirection: 'row',
        marginRight: theme.sizeL,
        padding: `${theme.sizeL / 2}px 0`
      },
      well: {
        alignSelf: 'flex-start',
        flex: '0 0 auto',
        height: '64px',
        marginRight: `${theme.sizeL / 2}px`,
        padding: `${theme.sizeL / 2}px`,
        width: '64px',
        borderRadius: 64
      },
      mono: {
        fontFamily: theme.fontMono,
        cursor: 'copy'
      },
      paletteItem: {
        padding: '20px',
        flex: 1
      },
      paletteText: {
        fontFamily: theme.fontFamily,
        filter: 'invert(60%) hue-rotate(0deg)',
        mixBlendMode: 'difference',
        textOverflow: 'ellipsis',
        whiteSpace: 'nowrap',
        overflow: 'hidden',
        opacity: 0.5,
        ':hover': {
          opacity: 1
        }
      },
      info: {
        alignSelf: 'flex-start',
        flex: '1 1 auto',
        width: '7em'
      }
    };

    let isPalette = modifiers.contains('palette') || modifiers.contains('palette-vertical');

    let colorSwatches = colors.map( (color, key) => {
      return (

            <MetadataBlock title={color.name} attributes={[color.value]} theme={theme}/>

      );
    });

    let colorPalette = colors.map( (color, key) => {
      return (

          {color.name}
{color.value}

      );
    });

    return (

        {isPalette ? colorPalette : colorSwatches }

    );
  }
}

Color.propTypes = {
  colors: PropTypes.array.isRequired,
  modifiers: PropTypes.array,
  theme: PropTypes.object.isRequired
};

export default Radium(Color);
<commit_msg>changed swatch layout<commit_after>import React, { PropTypes } from 'react';
import Radium from 'radium';

class Color extends React.Component {
  handleClick() {
    document.execCommand('copy');
  }
  render() {
    const {theme, colors, modifiers} = this.props;
    let styles = {
      container: {
        display: 'flex',
        alignItems: 'stretch',
        flexWrap: 'wrap',
        justifyContent: 'flex-start',
        margin: '20px 0',
        overflow: 'auto',
        flexBasis: '100%'
      },
      rows: {
        flexDirection: 'row'
      },
      columns: {
        flexDirection: 'column'
      },
      box: {
        flexBasis: `calc(${ 1 / 6 * 100}%)`
      },
      well: {
        alignSelf: 'flex-start',
        flex: '0 0 auto',
        height: '111px',
        marginRight: 10
      },
      mono: {
        fontFamily: theme.fontMono,
        cursor: 'copy'
      },
      paletteItem: {
        padding: '20px',
        flexBasis: 'calc(100% - 10px)',
        flex: 1
      },
      text: {
        fontFamily: theme.fontFamily,
        color: theme.textColor,
        marginRight: 10,
        flex: '0 0 auto',
        boxSizing: 'border-box',
        padding: '10px',
        flexBasis: 'calc(100% - 10px)',
        background: theme.background
      },
      textPalette: {
        fontFamily: theme.fontFamily,
        color: theme.textColor,
        filter: 'invert(60%) hue-rotate(0deg)',
        mixBlendMode: 'difference',
        textOverflow: 'ellipsis',
        whiteSpace: 'nowrap',
        overflow: 'hidden',
        opacity: 0.5,
        ':hover': {
          opacity: 1
        }
      },
      info: {
        alignSelf: 'flex-start',
        flex: '1 1 auto',
        width: '7em'
      }
    };

    let isPalette = modifiers.contains('palette') || modifiers.contains('palette-horizontal');

    let colorSwatches = colors.map( (color, key) => {
      return (

            {color.name}
{color.value}

      );
    });

    let colorPalette = colors.map( (color, key) => {
      return (

            {color.name}
{color.value}

      );
    });

    return (

        {isPalette ? colorPalette : colorSwatches }

    );
  }
}

Color.propTypes = {
  colors: PropTypes.array.isRequired,
  modifiers: PropTypes.array,
  theme: PropTypes.object.isRequired
};

export default Radium(Color);
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Moment from 'moment';

//  The components
import WeatherForecast from './WeatherForecast.react';
import WeatherForecastIcon from './WeatherForecastIcon.react';
import WeatherAlerts from './WeatherAlerts.react';

//  The API utils
import WeatherAPIUtils from '../utils/WeatherAPIUtils';

//  Stylesheets & images
import 'weathericons/css/weather-icons-wind.css';

class WeatherDisplay extends Component {

  render() {

    let temperature = 0;
    let windspeed = 0;
    let forecastdays = [];
    let forecasticon = "";
    let alerts = []
    let feelslike = 0;
    let sunrise = 0;
    let formattedSunrise = "";
    let sunset = 0;
    let formattedSunset = "";
    let pollendays = [];
    let formattedHumidity = "";
    let formattedStatus = "";
    let pollenSummary = "";
    let winddirectionicon = "";

    if (this.props.weather.currently) {
      //  Format the current weather summary:
      forecasticon = this.props.weather.currently.icon;
      temperature = Math.round(this.props.weather.currently.temperature);

      windspeed = Math.round(this.props.weather.currently.windspeed);
      formattedHumidity = Math.floor((this.props.weather.currently.humidity * 100));
      formattedHumidity = formattedHumidity + "%"
      feelslike = Math.round(this.props.weather.currently.apparent_temp);

      sunrise = this.props.weather.currently.sunrise;
      formattedSunrise = Moment(sunrise).format("h:mma");
      sunset = this.props.weather.currently.sunset;
      formattedSunset = Moment(sunset).format("h:mma");

      forecastdays = this.props.weather.daily.data;

      formattedStatus = this.props.weather.source + ' last updated ' + Moment(this.props.weather.lastupdated).format("h:mma") + ' / '

      //  If we have alerts, use them
      if (this.props.weather.alerts != null) {
        alerts = this.props.weather.alerts;
      }

      //  Set the current temperature color:
      var tempColor = WeatherAPIUtils.getTempColor(temperature);

      //  Set the feels like color (if it's different from the current temp):
      var feelsLikeStyles = {};
      if (temperature !== feelslike) {
        feelsLikeStyles.color = WeatherAPIUtils.getTempColor(feelslike);
      }

      //  Set the wind direction icon:
      winddirectionicon = WeatherAPIUtils.getWindDirectionIcon(this.props.weather.currently.wind_direction);

      //  Set pollen information
      if (this.props.pollen.PollenCount) {
        pollendays = this.props.pollen.PollenCount;

        //  Add the pollen data to the forecastdays
        for (var i = pollendays.length - 1; i >= 0; i--) {
          forecastdays[i].pollen = pollendays[i];
        };

        //  Set the pollen summary:
        pollenSummary = this.props.pollen.PredominantPollen;
      }
    }

    return (

<WeatherForecastIcon icon={forecasticon} /> {temperature}°

          Wind: {windspeed}mph  • {formattedHumidity} humidity • Feels like: {feelslike} °

           {formattedSunrise} /  {formattedSunset}

{this.props.locationname} / {formattedStatus} Settings

        <WeatherForecast forecastdays={forecastdays} />

          Predominant pollen: {pollenSummary}

        <WeatherAlerts alerts={alerts} />

    );
  }
}

export default WeatherDisplay;<commit_msg>Update wind display<commit_after>import React, { Component } from 'react';
import Moment from 'moment';

//  The components
import WeatherForecast from './WeatherForecast.react';
import WeatherForecastIcon from './WeatherForecastIcon.react';
import WeatherAlerts from './WeatherAlerts.react';

//  The API utils
import WeatherAPIUtils from '../utils/WeatherAPIUtils';

//  Stylesheets & images
import 'weathericons/css/weather-icons-wind.css';

class WeatherDisplay extends Component {

  render() {

    let temperature = 0;
    let windspeed = 0;
    let forecastdays = [];
    let forecasticon = "";
    let alerts = []
    let feelslike = 0;
    let sunrise = 0;
    let formattedSunrise = "";
    let sunset = 0;
    let formattedSunset = "";
    let pollendays = [];
    let formattedHumidity = "";
    let formattedStatus = "";
    let pollenSummary = "";
    let winddirectionicon = "";

    if (this.props.weather.currently) {
      //  Format the current weather summary:
      forecasticon = this.props.weather.currently.icon;
      temperature = Math.round(this.props.weather.currently.temperature);

      windspeed = Math.round(this.props.weather.currently.windspeed);
      formattedHumidity = Math.floor((this.props.weather.currently.humidity * 100));
      formattedHumidity = formattedHumidity + "%"
      feelslike = Math.round(this.props.weather.currently.apparent_temp);

      sunrise = this.props.weather.currently.sunrise;
      formattedSunrise = Moment(sunrise).format("h:mma");
      sunset = this.props.weather.currently.sunset;
      formattedSunset = Moment(sunset).format("h:mma");

      forecastdays = this.props.weather.daily.data;

      formattedStatus = this.props.weather.source + ' last updated ' + Moment(this.props.weather.lastupdated).format("h:mma") + ' / '

      //  If we have alerts, use them
      if (this.props.weather.alerts != null) {
        alerts = this.props.weather.alerts;
      }

      //  Set the current temperature color:
      var tempColor = WeatherAPIUtils.getTempColor(temperature);

      //  Set the feels like color (if it's different from the current temp):
      var feelsLikeStyles = {};
      if (temperature !== feelslike) {
        feelsLikeStyles.color = WeatherAPIUtils.getTempColor(feelslike);
      }

      //  Set the wind direction icon:
      winddirectionicon = WeatherAPIUtils.getWindDirectionIcon(this.props.weather.currently.wind_direction);

      //  Set pollen information
      if (this.props.pollen.PollenCount) {
        pollendays = this.props.pollen.PollenCount;

        //  Add the pollen data to the forecastdays
        for (var i = pollendays.length - 1; i >= 0; i--) {
          forecastdays[i].pollen = pollendays[i];
        };

        //  Set the pollen summary:
        pollenSummary = this.props.pollen.PredominantPollen;
      }
    }

    return (

<WeatherForecastIcon icon={forecasticon} /> {temperature}°

          Wind:  {windspeed}mph • {formattedHumidity} humidity • Feels like: {feelslike} °

           {formattedSunrise} /  {formattedSunset}

{this.props.locationname} / {formattedStatus} Settings

        <WeatherForecast forecastdays={forecastdays} />

          Predominant pollen: {pollenSummary}

        <WeatherAlerts alerts={alerts} />

    );
  }
}

export default WeatherDisplay;<|endoftext|>


<commit_before>const dragObjects = []
const dragThreshold = 5
let dragX = 0
let dragY = 0
let dragged = false
let hasListeners = false
let isDragging = false
let lastDragX = 0
let lastDragY = 0
let lastX = -1
let lastY = -1
let target = null
let totalDrag = 0
let totalDragX = 0
let totalDragY = 0

function reset() {
  dragX = 0
  dragY = 0
  dragged = false
  isDragging = false
  lastDragX = 0
  lastDragY = 0
  lastX = -1
  lastY = -1
  target = null
  totalDrag = 0
  totalDragX = 0
  totalDragY = 0
}

function callMethod(method) {
  const props = {
    dragX,
    dragY,
    dragged,
    lastDragX,
    lastDragY,
    lastX,
    lastY,
    target,
    totalDrag,
    totalDragX,
    totalDragY,
  }
  for (const obj of dragObjects) {
    if (obj.component[method] && target.dataset.dragId === obj.dragId) {
      obj.component[method](props)
    }
  }
}

function dragMove(x, y) {
  lastDragX = dragX
  lastDragY = dragY
  dragX += x - lastX
  dragY += y - lastY
  totalDragX += Math.abs(x - lastX)
  totalDragY += Math.abs(y - lastY)
  lastX = x
  lastY = y
  totalDrag = totalDragX + totalDragY
  dragged = (totalDrag > dragThreshold)
  callMethod('onDragMove')
}

function mouseMove(e) {
  if (!isDragging) return
  dragMove(e.clientX, e.clientY)
}

function touchMove(e) {
  if (!isDragging) return
  dragMove(e.touches[0].clientX, e.touches[0].clientY)
}

function dragStart(x, y, t) {
  reset()
  target = t
  lastX = x
  lastY = y
  isDragging = true
  callMethod('onDragStart')
  document.addEventListener('mousemove', mouseMove)
  document.addEventListener('touchmove', touchMove)
}

function mouseDown(e) {
  // return if not the drag handler || fix android exception
  if (e.target.className.indexOf('DragHandler') === -1 ||
      !e.target.classList) return
  dragStart(e.clientX, e.clientY, e.target)
}

function touchStart(e) {
  // return if not the drag handler || fix android exception
  if (e.target.className.indexOf('DragHandler') === -1 ||
      !e.target.classList) return
  dragStart(e.touches[0].clientX, e.touches[0].clientY)
}

function dragEnd() {
  if (!isDragging) return
  callMethod('onDragEnd')
  document.removeEventListener('mousemove', mouseMove)
  document.removeEventListener('touchmove', touchMove)
  // this gives us enough time to respond on the frame
  // of the mouse/touch event to know if we dragged when it fired.
  requestAnimationFrame(() => {
    reset()
  })
}

function addListeners() {
  document.addEventListener('mousedown', mouseDown)
  document.addEventListener('touchstart', touchStart)
  document.addEventListener('mouseup', dragEnd)
  document.addEventListener('touchend', dragEnd)
}

function removeListeners() {
  document.removeEventListener('mousedown', mouseDown)
  document.removeEventListener('touchstart', touchStart)
  document.removeEventListener('mousemove', mouseMove)
  document.removeEventListener('touchmove', touchMove)
  document.removeEventListener('mouseup', dragEnd)
  document.removeEventListener('touchend', dragEnd)
}

export function addDragObject(obj) {
  if (dragObjects.indexOf(obj) === -1) {
    dragObjects.push(obj)
  }
  if (dragObjects.length === 1 && !hasListeners) {
    hasListeners = true
    addListeners()
  }
}

export function removeDragObject(obj) {
  const index = dragObjects.indexOf(obj)
  if (index > -1) {
    dragObjects.splice(index, 1)
  }
  if (dragObjects.length === 0) {
    hasListeners = false
    removeListeners()
  }
}

<commit_msg>add 'dragEnd' after 'dragStart', instead of in 'addListeners'<commit_after>const dragObjects = []
const dragThreshold = 5
let dragX = 0
let dragY = 0
let dragged = false
let hasListeners = false
let isDragging = false
let lastDragX = 0
let lastDragY = 0
let lastX = -1
let lastY = -1
let target = null
let totalDrag = 0
let totalDragX = 0
let totalDragY = 0

function reset() {
  dragX = 0
  dragY = 0
  dragged = false
  isDragging = false
  lastDragX = 0
  lastDragY = 0
  lastX = -1
  lastY = -1
  target = null
  totalDrag = 0
  totalDragX = 0
  totalDragY = 0
}

function callMethod(method) {
  const props = {
    dragX,
    dragY,
    dragged,
    lastDragX,
    lastDragY,
    lastX,
    lastY,
    target,
    totalDrag,
    totalDragX,
    totalDragY,
  }
  for (const obj of dragObjects) {
    if (obj.component[method] && target.dataset.dragId === obj.dragId) {
      obj.component[method](props)
    }
  }
}

function dragMove(x, y) {
  lastDragX = dragX
  lastDragY = dragY
  dragX += x - lastX
  dragY += y - lastY
  totalDragX += Math.abs(x - lastX)
  totalDragY += Math.abs(y - lastY)
  lastX = x
  lastY = y
  totalDrag = totalDragX + totalDragY
  dragged = (totalDrag > dragThreshold)
  callMethod('onDragMove')
}

function mouseMove(e) {
  if (!isDragging) return
  dragMove(e.clientX, e.clientY)
}

function touchMove(e) {
  if (!isDragging) return
  dragMove(e.touches[0].clientX, e.touches[0].clientY)
}

function dragEnd() {
  if (!isDragging) return
  callMethod('onDragEnd')
  document.removeEventListener('mousemove', mouseMove)
  document.removeEventListener('touchmove', touchMove)
  document.removeEventListener('mouseup', dragEnd)
  document.removeEventListener('touchend', dragEnd)
  // this gives us enough time to respond on the frame
  // of the mouse/touch event to know if we dragged when it fired.
  requestAnimationFrame(() => {
    reset()
  })
}

function dragStart(x, y, t) {
  reset()
  target = t
  lastX = x
  lastY = y
  isDragging = true
  callMethod('onDragStart')
  document.addEventListener('mousemove', mouseMove)
  document.addEventListener('touchmove', touchMove)
  document.addEventListener('mouseup', dragEnd)
  document.addEventListener('touchend', dragEnd)
}

function mouseDown(e) {
  // return if not the drag handler || fix android exception
  if (e.target.className.indexOf('DragHandler') === -1 ||
      !e.target.classList) return
  dragStart(e.clientX, e.clientY, e.target)
}

function touchStart(e) {
  // return if not the drag handler || fix android exception
  if (e.target.className.indexOf('DragHandler') === -1 ||
      !e.target.classList) return
  dragStart(e.touches[0].clientX, e.touches[0].clientY)
}

function addListeners() {
  document.addEventListener('mousedown', mouseDown)
  document.addEventListener('touchstart', touchStart)
}

function removeListeners() {
  document.removeEventListener('mousedown', mouseDown)
  document.removeEventListener('touchstart', touchStart)
  document.removeEventListener('mousemove', mouseMove)
  document.removeEventListener('touchmove', touchMove)
  document.removeEventListener('mouseup', dragEnd)
  document.removeEventListener('touchend', dragEnd)
}

export function addDragObject(obj) {
  if (dragObjects.indexOf(obj) === -1) {
    dragObjects.push(obj)
  }
  if (dragObjects.length === 1 && !hasListeners) {
    hasListeners = true
    addListeners()
  }
}

export function removeDragObject(obj) {
  const index = dragObjects.indexOf(obj)
  if (index > -1) {
    dragObjects.splice(index, 1)
  }
  if (dragObjects.length === 0) {
    hasListeners = false
    removeListeners()
  }
}

<|endoftext|>


<commit_before>import React from 'react'
import { Link } from 'react-router-dom'

class ModalContainer extends React.Component {
  constructor(props) {
    super(props)
    this.state = { isModalOpen: false }
  }

  render() {
    return (

        <button onClick={() => this.openModal()}>Open modal</button>
        <Modal isOpen={this.state.isModalOpen} onClose={() => this.closeModal()}>

<button onClick={() => this.closeModal()}>Close</button>

<Link to="/">Home</Link>

<Link to="/about">About</Link>

<Link to="/search">Search</Link>

<Link to="/filter">Filter</Link>

<Link to="/topics">Topics</Link>

<Link to="/gjhfhghj">404</Link>

        </Modal>

    )
  }

  openModal() {
    this.setState({ isModalOpen: true })
  }

  closeModal() {
    this.setState({ isModalOpen: false })
  }
}

class Modal extends React.Component {
  render() {
    if (this.props.isOpen === false)
      return null

    let modalStyle = {
      width: '100%',
      height: '100%',
      position: 'absolute',
      top: '50%',
      left: '50%',
      transform: 'translate(-50%, -50%)',
      zIndex: '9999',
      background: '#454552',
      color: '#d8e9ef'
    }

    if (this.props.width && this.props.height) {
      modalStyle.width = this.props.width + 'px'
      modalStyle.height = this.props.height + 'px'
      modalStyle.marginLeft = '-' + (this.props.width/2) + 'px',
      modalStyle.marginTop = '-' + (this.props.height/2) + 'px',
      modalStyle.transform = null
    }

    if (this.props.style) {
      for (let key in this.props.style) {
        modalStyle[key] = this.props.style[key]
      }
    }

    let backdropStyle = {
      position: 'absolute',
      width: '100%',
      height: '100%',
      top: '0px',
      left: '0px',
      zIndex: '9998',
      background: 'rgba(0, 0, 0, 0.3)'
    }

    if (this.props.backdropStyle) {
      for (let key in this.props.backdropStyle) {
        backdropStyle[key] = this.props.backdropStyle[key]
      }
    }

    return (

          {this.props.children}

        {!this.props.noBackdrop &&

 this.close(e)}/>}

    )
  }

  close(e) {
    e.preventDefault()

    if (this.props.onClose) {
      this.props.onClose()
    }
  }
}

export default ModalContainer
<commit_msg>updating<commit_after>import React from 'react'
import { Link } from 'react-router-dom'

class ModalContainer extends React.Component {
  constructor(props) {
    super(props)
    this.state = { isModalOpen: false }
  }

  render() {
    return (

        <button onClick={() => this.openModal()}>Open modal</button>
        <Modal isOpen={this.state.isModalOpen} onClose={() => this.closeModal()}>

<button onClick={() => this.closeModal()}>Close</button>

<Link to="/">Home</Link>

<Link to="/about">About</Link>

<Link to="/search">Search</Link>

<Link to="/filter">Filter</Link>

<Link to="/topics">Topics</Link>

<Link to="/gjhfhghj">404</Link>

        </Modal>

    )
  }

  openModal() {
    this.setState({ isModalOpen: true })
  }

  closeModal() {
    this.setState({ isModalOpen: false })
  }
}

class Modal extends React.Component {
  render() {
    if (this.props.isOpen === false)
      return null

    let modalStyle = {
      width: '100%',
      height: '100%',
      position: 'absolute',
      top: '50%',
      left: '50%',
      transform: 'translate(-50%, -50%)',
      zIndex: '9999',
      background: '#454552',
      color: '#d8e9ef'
    }

    // if (this.props.width && this.props.height) {
    //   //modalStyle.width = this.props.width + 'px',
    //   modalStyle.height = this.props.height + 'px',
    //   modalStyle.marginLeft = '-' + (this.props.width/2) + 'px',
    //   modalStyle.marginTop = '-' + (this.props.height/2) + 'px',
    //   modalStyle.transform = null
    // };

    if (this.props.style) {
      for (let key in this.props.style) {
        modalStyle[key] = this.props.style[key]
      }
    }

    let backdropStyle = {
      position: 'absolute',
      width: '100%',
      height: '100%',
      top: '0px',
      left: '0px',
      zIndex: '9998',
      background: 'rgba(0, 0, 0, 0.3)'
    }

    if (this.props.backdropStyle) {
      for (let key in this.props.backdropStyle) {
        backdropStyle[key] = this.props.backdropStyle[key]
      }
    }

    return (

          {this.props.children}

        {!this.props.noBackdrop &&

 this.close(e)}/>}

    )
  }

  close(e) {
    e.preventDefault()

    if (this.props.onClose) {
      this.props.onClose()
    }
  }
}

export default ModalContainer
<|endoftext|>


<commit_before>import React from 'react';
import {
  Form,
  Radio,
  Modal,
  Button,
  Message,
} from 'semantic-ui-react';

// CUSTOM
import { renderIfTrue } from '../renderIfTrue';

// URL to direct requests to, from the Google Apps Script
const postUrl = 'https://script.google.com/macros/s/AKfycbyXYbemTPcqsdbmXITnjaNi-CkN85g5kKPrgzt4AS8ykT2jH6Zn/exec';

/**
 * Modal that asks for permission to store user data for debugging purposes
 */
class AskPermission extends React.Component {
  state = {
    submitType: null,
    submitting: false,
  };

  close = () => {
    this.setState({ submitFunc: null });
    this.props.closeAskPermission();
  };

  submit = (evnt) => {
    this.props.submit(evnt, this.state.submitType);
  };

  setSubmitType = (evnt, inputProps) => {
    this.setState({ submitType: inputProps.value });
  };

  // Return an array to take advantage of `Modal` styling
  render () {return ([
    <Modal.Content key = { `ask-permission-content` }>

{ this.props.question }

      <Form.Field>
        <Radio
          name     = { `data-ask` }
          value    = { `withData` }
          label    = { `Yes` }
          checked  = { this.state.submitType === `withData` }
          onChange = { this.setSubmitType } />
      </Form.Field>
      <Form.Field>
        <Radio
          name     = { `data-ask` }
          value    = { `withoutData` }
          label    = { `No` }
          checked  = { this.state.submitType === `withoutData` }
          onChange = { this.setSubmitType } />
      </Form.Field>
    </Modal.Content>,
    <Modal.Actions key = { `ask-permission-actions` }>
      <Button
        onClick  ={ this.close }
        disabled ={ this.props.submitting }>Cancel
      </Button>
      <Button
        onClick  = { this.submit }
        loading  = { this.props.submitting }
        disabled = { this.state.submitType === null }
        color    ='teal'>
        {renderIfTrue(this.state.submitType === `withData`,
          `Send With Data`
        )}
        {renderIfTrue(this.state.submitType === `withoutData`,
          `Send Without Data`
        )}
        {renderIfTrue(this.state.submitType === null,
          `Send`
        )}
      </Button>
    </Modal.Actions>,
  ]);}
}

/**
 * Modal that shows the feedback form.
 */
class FeedbackPrompt extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      formData:         {},
      ready:            false,
      submitting:       false,
      submissionFailed: false,
    };
  }

  handleInputChange = (event) => {
    // Source: https://reactjs.org/docs/forms.html#controlled-components
    const target = event.target;
    const name = target.name;
    let value;
    if (target.type === 'checkbox') {
      value = target.checked;
    } else {
      value = target.value;
    }

    this.setState({ formData: Object.assign({}, this.state.formData, { [ name ]: value }) });
  };

  // returns promise that succeeds if submission is successful, else rejects.
  sendDataToSpreadsheet(data) {
    const fetchOptions = {
      method: 'POST',
      body:   JSON.stringify(data),
    };
    return fetch(postUrl, fetchOptions)
      .then((response) => {
        if (response.ok) {
          return response;
        } else {
          var error = new Error(response.statusText);
          error.response = response;
          throw error;
        }
      });
  }

  close = (event) => {
    // Reset state for next time it's opened
    this.setState({
      formData:         {},
      ready:            false,
      submitting:       false,
      submissionFailed: false,
    });
    this.props.close();
  };

  onReady = () => {
    this.setState({ ready: true });
  };

  closeAskPermission = () => {
    this.setState({ ready: false });
  };

  submit = (evnt, type) => {
    this.setState({ submitting: true });

    let data = this.state.formData;
    if (type === `withData`) {
      data = Object.assign({ clientData: this.props.data }, this.state.formData);
    }

    this.sendDataToSpreadsheet(data)
      .then((response) => {
        this.close();
      })
      .catch((error) => {
        this.setState({ submissionFailed: true, submitting: false });
        console.error(error.message);
      });
  };

  render () {
    const inputProps = (name) => {
      return {
        name,
        value:    this.state.formData[ name ] || '',
        onChange: this.handleInputChange,
      };
    };

    return (
      <Modal
        size='large'
        open={ this.props.isOpen }
        onClose={ this.close }
        closeOnDimmerClick={ false }
        closeOnEscape={ false }
        closeIcon>
        <Modal.Header>Tell Us More</Modal.Header>
        <Modal.Content scrolling>
          <Form>
            <Form.Input
              { ...inputProps('currentSnap') }
              label={ 'If amount for the CURRENT SNAP subsidy was wrong, what\'s the correct amount?' } />
            <Form.Input
              { ...inputProps('futureSnap') }
              label={ 'If amount for the FUTURE SNAP subsidy was wrong, what\'s the correct amount?' } />
            <Form.Input
              { ...inputProps('futureS8') }
              label={ 'If amount for the FUTURE Section 8 voucher was wrong, what\'s the correct amount?' } />
            <Form.TextArea
              { ...inputProps('otherCircumstances') }
              label={ 'What else could be going on that could affect your benefit amount? ' +
              'For example, are you a veteran? Are you a full-time student?' } />
            <Form.TextArea
              { ...inputProps('bugReport') }
              label={ 'If there was a bug or error, describe the bug and what you were trying to do when the bug happened.' } />
            <Form.TextArea
              { ...inputProps('comments') }
              label={ 'Do you have any other comments?' } />
          </Form>
          <Message
            hidden={ !this.state.submissionFailed }
            error>
            Error submitting data, please try again or email us.
          </Message>
        </Modal.Content>
        <Modal.Actions>
          <Button
            onClick={ this.close }
            disabled={ this.state.submitting }>Cancel
          </Button>
          <Button
            onClick={ this.onReady }
            color='teal'>Ready
          </Button>
        </Modal.Actions>

        <Modal
          size               = { `large` }
          open               = { this.state.ready }
          onClose            = { this.closeAskPermission }
          closeOnDimmerClick = { false }
          closeOnEscape      = { false }
          closeIcon>
          <AskPermission
            submitting         = { this.state.submitting }
            closeAskPermission = { this.closeAskPermission }
            submit             = { this.submit }
            question           = { `Is it ok if we save the data you've filled in? We won't save your name or any other information that could give away your identity and it'll help us understand your situation better.` } />
        </Modal>
      </Modal>
    );
  }
};

export default FeedbackPrompt;
export { AskPermission };
<commit_msg>Tweaks wording to be more plain and to resemble other romance langs<commit_after>import React from 'react';
import {
  Form,
  Radio,
  Modal,
  Button,
  Message,
} from 'semantic-ui-react';

// CUSTOM
import { renderIfTrue } from '../renderIfTrue';

// URL to direct requests to, from the Google Apps Script
const postUrl = 'https://script.google.com/macros/s/AKfycbyXYbemTPcqsdbmXITnjaNi-CkN85g5kKPrgzt4AS8ykT2jH6Zn/exec';

/**
 * Modal that asks for permission to store user data for debugging purposes
 */
class AskPermission extends React.Component {
  state = {
    submitType: null,
    submitting: false,
  };

  close = () => {
    this.setState({ submitFunc: null });
    this.props.closeAskPermission();
  };

  submit = (evnt) => {
    this.props.submit(evnt, this.state.submitType);
  };

  setSubmitType = (evnt, inputProps) => {
    this.setState({ submitType: inputProps.value });
  };

  // Return an array to take advantage of `Modal` styling
  render () {return ([
    <Modal.Content key = { `ask-permission-content` }>

{ this.props.question }

      <Form.Field>
        <Radio
          name     = { `data-ask` }
          value    = { `withData` }
          label    = { `Yes` }
          checked  = { this.state.submitType === `withData` }
          onChange = { this.setSubmitType } />
      </Form.Field>
      <Form.Field>
        <Radio
          name     = { `data-ask` }
          value    = { `withoutData` }
          label    = { `No` }
          checked  = { this.state.submitType === `withoutData` }
          onChange = { this.setSubmitType } />
      </Form.Field>
    </Modal.Content>,
    <Modal.Actions key = { `ask-permission-actions` }>
      <Button
        onClick  ={ this.close }
        disabled ={ this.props.submitting }>Cancel
      </Button>
      <Button
        onClick  = { this.submit }
        loading  = { this.props.submitting }
        disabled = { this.state.submitType === null }
        color    ='teal'>
        {renderIfTrue(this.state.submitType === `withData`,
          `Send it with my information`
        )}
        {renderIfTrue(this.state.submitType === `withoutData`,
          `Send it without my information`
        )}
        {renderIfTrue(this.state.submitType === null,
          `Send it`
        )}
      </Button>
    </Modal.Actions>,
  ]);}
}

/**
 * Modal that shows the feedback form.
 */
class FeedbackPrompt extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      formData:         {},
      ready:            false,
      submitting:       false,
      submissionFailed: false,
    };
  }

  handleInputChange = (event) => {
    // Source: https://reactjs.org/docs/forms.html#controlled-components
    const target = event.target;
    const name = target.name;
    let value;
    if (target.type === 'checkbox') {
      value = target.checked;
    } else {
      value = target.value;
    }

    this.setState({ formData: Object.assign({}, this.state.formData, { [ name ]: value }) });
  };

  // returns promise that succeeds if submission is successful, else rejects.
  sendDataToSpreadsheet(data) {
    const fetchOptions = {
      method: 'POST',
      body:   JSON.stringify(data),
    };
    return fetch(postUrl, fetchOptions)
      .then((response) => {
        if (response.ok) {
          return response;
        } else {
          var error = new Error(response.statusText);
          error.response = response;
          throw error;
        }
      });
  }

  close = (event) => {
    // Reset state for next time it's opened
    this.setState({
      formData:         {},
      ready:            false,
      submitting:       false,
      submissionFailed: false,
    });
    this.props.close();
  };

  onReady = () => {
    this.setState({ ready: true });
  };

  closeAskPermission = () => {
    this.setState({ ready: false });
  };

  submit = (evnt, type) => {
    this.setState({ submitting: true });

    let data = this.state.formData;
    if (type === `withData`) {
      data = Object.assign({ clientData: this.props.data }, this.state.formData);
    }

    this.sendDataToSpreadsheet(data)
      .then((response) => {
        this.close();
      })
      .catch((error) => {
        this.setState({ submissionFailed: true, submitting: false });
        console.error(error.message);
      });
  };

  render () {
    const inputProps = (name) => {
      return {
        name,
        value:    this.state.formData[ name ] || '',
        onChange: this.handleInputChange,
      };
    };

    return (
      <Modal
        size='large'
        open={ this.props.isOpen }
        onClose={ this.close }
        closeOnDimmerClick={ false }
        closeOnEscape={ false }
        closeIcon>
        <Modal.Header>Tell Us More</Modal.Header>
        <Modal.Content scrolling>
          <Form>
            <Form.Input
              { ...inputProps('currentSnap') }
              label={ 'If amount for the CURRENT SNAP amount was wrong, what\'s the right amount?' } />
            <Form.Input
              { ...inputProps('futureSnap') }
              label={ 'If amount for the FUTURE SNAP amount was wrong, what\'s the right amount?' } />
            <Form.Input
              { ...inputProps('futureS8') }
              label={ 'If amount for the FUTURE Section 8 amount was wrong, what\'s the right amount?' } />
            <Form.TextArea
              { ...inputProps('otherCircumstances') }
              label={ 'What else could be going on that could affect your benefit amount? ' +
              'For example, are you a veteran? Are you a full-time student?' } />
            <Form.TextArea
              { ...inputProps('bugReport') }
              label={ 'If there was a bug or error, describe the bug and what you were trying to do when the bug happened.' } />
            <Form.TextArea
              { ...inputProps('comments') }
              label={ 'Do you have any other comments?' } />
          </Form>
          <Message
            hidden={ !this.state.submissionFailed }
            error>
            Error submitting data, please try again or email us.
          </Message>
        </Modal.Content>
        <Modal.Actions>
          <Button
            onClick={ this.close }
            disabled={ this.state.submitting }>Cancel
          </Button>
          <Button
            onClick={ this.onReady }
            color='teal'>Finished
          </Button>
        </Modal.Actions>

        <Modal
          size               = { `large` }
          open               = { this.state.ready }
          onClose            = { this.closeAskPermission }
          closeOnDimmerClick = { false }
          closeOnEscape      = { false }
          closeIcon>
          <AskPermission
            submitting         = { this.state.submitting }
            closeAskPermission = { this.closeAskPermission }
            submit             = { this.submit }
            question           = { `Is it ok if we save the information you've filled in? We won't save anythign else about you. If you had problems, it'll help us solve them.` } />
        </Modal>
      </Modal>
    );
  }
};

export default FeedbackPrompt;
export { AskPermission };
<|endoftext|>


<commit_before>if (typeof define !== 'function') { var define = require('amdefine')(module); }
if (typeof expect !== 'function') { var expect = require('expect.js'); }

define([
  'app/flowControl'
], function(answers) {
  describe("flow control", function() {
    it("you should be able to conditionally branch your code", function() {
      var num = Math.floor(Math.random() * 10) + 1;

      expect(answers.fizzBuzz()).not.to.be.ok();
      expect(answers.fizzBuzz(2)).to.be(2);
      expect(answers.fizzBuzz(101)).to.be(101);

      expect(answers.fizzBuzz(3)).to.be('fizz');
      expect(answers.fizzBuzz(6)).to.be('fizz');
      expect(answers.fizzBuzz(num * 3)).to.be('fizz');

      expect(answers.fizzBuzz(5)).to.be('buzz');
      expect(answers.fizzBuzz(10)).to.be('buzz');
      expect(answers.fizzBuzz(num * 5)).to.be('buzz');

      expect(answers.fizzBuzz(15)).to.be('fizzbuzz');
      expect(answers.fizzBuzz(num * 3 * 5)).to.be('fizzbuzz');
    });
  });
});
<commit_msg>fix fizzbuzz in line 21 or 25<commit_after>if (typeof define !== 'function') { var define = require('amdefine')(module); }
if (typeof expect !== 'function') { var expect = require('expect.js'); }

define([
  'app/flowControl'
], function(answers) {
  describe("flow control", function() {
    it("you should be able to conditionally branch your code", function() {
      var num = 0;

      while (num % 3 === 0 || num % 5 === 0) {
          num = Math.floor(Math.random() * 10) + 1;
      }

      expect(answers.fizzBuzz()).not.to.be.ok();
      expect(answers.fizzBuzz(2)).to.be(2);
      expect(answers.fizzBuzz(101)).to.be(101);

      expect(answers.fizzBuzz(3)).to.be('fizz');
      expect(answers.fizzBuzz(6)).to.be('fizz');
      expect(answers.fizzBuzz(num * 3)).to.be('fizz');

      expect(answers.fizzBuzz(5)).to.be('buzz');
      expect(answers.fizzBuzz(10)).to.be('buzz');
      expect(answers.fizzBuzz(num * 5)).to.be('buzz');

      expect(answers.fizzBuzz(15)).to.be('fizzbuzz');
      expect(answers.fizzBuzz(num * 3 * 5)).to.be('fizzbuzz');
    });
  });
});
<|endoftext|>


<commit_before>import { Component } from 'react';
import PropTypes from 'prop-types';

let scrollTimeout;

class InfiniteScroll extends Component {
  static defaultProps = {
    offset: 25,
    children: null,
  };

  static propTypes = {
    onScroll: PropTypes.func.isRequired,
    offset: PropTypes.number,
    children: PropTypes.node,
  };

  componentDidMount() {
    window.addEventListener('scroll', () => this.handleScroll());
  }

  componentWillUnmount() {
    window.removeEventListener('scroll', () => this.handleScroll());
  }

  handleScroll() {
    clearTimeout(scrollTimeout);

    scrollTimeout = setTimeout(() => {
      const visibleArea = window.scrollY + window.innerHeight;
      const toReach = window.outerHeight - this.props.offset;

      if (visibleArea >= toReach) {
        this.props.onScroll();
      }
    }, 100);
  }

  render() {
    return this.props.children;
  }
}

export default InfiniteScroll;
<commit_msg>Fix InfiniteScroll<commit_after>import { Component } from 'react';
import PropTypes from 'prop-types';

let scrollTimeout;

class InfiniteScroll extends Component {
  static defaultProps = {
    offset: 25,
    children: null,
  };

  static propTypes = {
    onScroll: PropTypes.func.isRequired,
    offset: PropTypes.number,
    children: PropTypes.node,
  };

  componentDidMount() {
    window.addEventListener('scroll', () => this.handleScroll());
  }

  componentWillUnmount() {
    window.removeEventListener('scroll', () => this.handleScroll());
  }

  handleScroll() {
    clearTimeout(scrollTimeout);

    scrollTimeout = setTimeout(() => {
      const visibleArea = window.scrollY + window.innerHeight;
      const toReach = document.body.scrollHeight - this.props.offset;

      if (visibleArea >= toReach) {
        this.props.onScroll();
      }
    }, 100);
  }

  render() {
    return this.props.children;
  }
}

export default InfiniteScroll;
<|endoftext|>


<commit_before>/*
Copyright 2015 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';
var React = require("react");
var ReactDOM = require("react-dom");
var GeminiScrollbar = require('react-gemini-scrollbar');
var MatrixClientPeg = require("../../../MatrixClientPeg");
var RoomListSorter = require("../../../RoomListSorter");
var UnreadStatus = require('../../../UnreadStatus');
var dis = require("../../../dispatcher");
var sdk = require('../../../index');

var HIDE_CONFERENCE_CHANS = true;

module.exports = React.createClass({
    displayName: 'RoomList',

    propTypes: {
        ConferenceHandler: React.PropTypes.any,
        collapsed: React.PropTypes.bool,
        currentRoom: React.PropTypes.string
    },

    getInitialState: function() {
        return {
            activityMap: null,
            lists: {},
        }
    },

    componentWillMount: function() {
        var cli = MatrixClientPeg.get();
        cli.on("Room", this.onRoom);
        cli.on("Room.timeline", this.onRoomTimeline);
        cli.on("Room.name", this.onRoomName);
        cli.on("Room.tags", this.onRoomTags);
        cli.on("RoomState.events", this.onRoomStateEvents);
        cli.on("RoomMember.name", this.onRoomMemberName);

        var s = this.getRoomLists();
        s.activityMap = {};
        this.setState(s);
    },

    componentDidMount: function() {
        this.dispatcherRef = dis.register(this.onAction);
    },

    onAction: function(payload) {
        switch (payload.action) {
            case 'view_tooltip':
                this.tooltip = payload.tooltip;
                this._repositionTooltip();
                if (this.tooltip) this.tooltip.style.display = 'block';
                break
        }
    },

    componentWillUnmount: function() {
        dis.unregister(this.dispatcherRef);
        if (MatrixClientPeg.get()) {
            MatrixClientPeg.get().removeListener("Room", this.onRoom);
            MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
            MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
            MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents);
        }
    },

    componentWillReceiveProps: function(newProps) {
        this.state.activityMap[newProps.selectedRoom] = undefined;
        this.setState({
            activityMap: this.state.activityMap
        });
    },

    onRoom: function(room) {
        this.refreshRoomList();
    },

    onRoomTimeline: function(ev, room, toStartOfTimeline) {
        if (toStartOfTimeline) return;

        var hl = 0;
        if (
            room.roomId != this.props.selectedRoom &&
            ev.getSender() != MatrixClientPeg.get().credentials.userId)
        {
            if (UnreadStatus.eventTriggersUnreadCount(ev)) {
                hl = 1;
            }

            var me = room.getMember(MatrixClientPeg.get().credentials.userId);
            var actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
            if ((actions && actions.tweaks && actions.tweaks.highlight) ||
                (me && me.membership == "invite"))
            {
                hl = 2;
            }
        }

        var newState = this.getRoomLists();
        if (hl > 0) {
            // obviously this won't deep copy but this shouldn't be necessary
            var amap = this.state.activityMap;
            amap[room.roomId] = Math.max(amap[room.roomId] || 0, hl);

            newState.activityMap = amap;

        }
        // still want to update the list even if the highlight status
        // hasn't changed because the ordering may have
        this.setState(newState);
    },

    onRoomName: function(room) {
        this.refreshRoomList();
    },

    onRoomTags: function(event, room) {
        this.refreshRoomList();
    },

    onRoomStateEvents: function(ev, state) {
        setTimeout(this.refreshRoomList, 0);
    },

    onRoomMemberName: function(ev, member) {
        setTimeout(this.refreshRoomList, 0);
    },

    refreshRoomList: function() {
        // TODO: rather than bluntly regenerating and re-sorting everything
        // every time we see any kind of room change from the JS SDK
        // we could do incremental updates on our copy of the state
        // based on the room which has actually changed.  This would stop
        // us re-rendering all the sublists every time anything changes anywhere
        // in the state of the client.
        this.setState(this.getRoomLists());
    },

    getRoomLists: function() {
        var self = this;
        var s = { lists: {} };

        s.lists["im.vector.fake.invite"] = [];
        s.lists["m.favourite"] = [];
        s.lists["im.vector.fake.recent"] = [];
        s.lists["m.lowpriority"] = [];
        s.lists["im.vector.fake.archived"] = [];

        MatrixClientPeg.get().getRooms().forEach(function(room) {
            var me = room.getMember(MatrixClientPeg.get().credentials.userId);

            if (me && me.membership == "invite") {
                s.lists["im.vector.fake.invite"].push(room);
            }
            else {
                var shouldShowRoom =  (
                    me && (me.membership == "join")
                );

                // hiding conf rooms only ever toggles shouldShowRoom to false
                if (shouldShowRoom && HIDE_CONFERENCE_CHANS) {
                    // we want to hide the 1:1 conf<->user room and not the group chat
                    var joinedMembers = room.getJoinedMembers();
                    if (joinedMembers.length === 2) {
                        var otherMember = joinedMembers.filter(function(m) {
                            return m.userId !== me.userId
                        })[0];
                        var ConfHandler = self.props.ConferenceHandler;
                        if (ConfHandler && ConfHandler.isConferenceUser(otherMember.userId)) {
                            // console.log("Hiding conference 1:1 room %s", room.roomId);
                            shouldShowRoom = false;
                        }
                    }
                }

                if (shouldShowRoom) {
                    var tagNames = Object.keys(room.tags);
                    if (tagNames.length) {
                        for (var i = 0; i < tagNames.length; i++) {
                            var tagName = tagNames[i];
                            s.lists[tagName] = s.lists[tagName] || [];
                            s.lists[tagNames[i]].push(room);
                        }
                    }
                    else {
                        s.lists["im.vector.fake.recent"].push(room);
                    }
                }
            }
        });

        //console.log("calculated new roomLists; im.vector.fake.recent = " + s.lists["im.vector.fake.recent"]);

        // we actually apply the sorting to this when receiving the prop in RoomSubLists.

        return s;
    },

    _repositionTooltip: function(e) {
        if (this.tooltip && this.tooltip.parentElement) {
            var scroll = ReactDOM.findDOMNode(this);
            this.tooltip.style.top = (scroll.parentElement.offsetTop + this.tooltip.parentElement.offsetTop - scroll.children[2].scrollTop) + "px";
        }
    },

    onShowClick: function() {
        dis.dispatch({
            action: 'show_left_panel',
        });
    },

    render: function() {
        var expandButton = this.props.collapsed ?
                           "/> :
                           null;

        var RoomSubList = sdk.getComponent('structures.RoomSubList');
        var self = this;

        return (
            <GeminiScrollbar className="mx_RoomList_scrollbar" autoshow={true} onScroll={self._repositionTooltip}>

                { expandButton }

                <RoomSubList list={ self.state.lists['im.vector.fake.invite'] }
                             label="Invites"
                             editable={ false }
                             order="recent"
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

                <RoomSubList list={ self.state.lists['m.favourite'] }
                             label="Favourites"
                             tagName="m.favourite"
                             verb="favourite"
                             editable={ true }
                             order="manual"
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

                <RoomSubList list={ self.state.lists['im.vector.fake.recent'] }
                             label="Conversations"
                             editable={ true }
                             verb="restore"
                             order="recent"
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

                { Object.keys(self.state.lists).map(function(tagName) {
                    if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|archived))$/)) {
                        return <RoomSubList list={ self.state.lists[tagName] }
                             key={ tagName }
                             label={ tagName }
                             tagName={ tagName }
                             verb={ "tag as " + tagName }
                             editable={ true }
                             order="manual"
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

                    }
                }) }

                <RoomSubList list={ self.state.lists['m.lowpriority'] }
                             label="Low priority"
                             tagName="m.lowpriority"
                             verb="demote"
                             editable={ true }
                             order="recent"
                             bottommost={ self.state.lists['im.vector.fake.archived'].length === 0 }
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

                <RoomSubList list={ self.state.lists['im.vector.fake.archived'] }
                             label="Historical"
                             editable={ false }
                             order="recent"
                             bottommost={ true }
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

            </GeminiScrollbar>
        );
    }
});
<commit_msg>s/Conversations/Rooms/ as per https://github.com/vector-im/vector-web/issues/535<commit_after>/*
Copyright 2015 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';
var React = require("react");
var ReactDOM = require("react-dom");
var GeminiScrollbar = require('react-gemini-scrollbar');
var MatrixClientPeg = require("../../../MatrixClientPeg");
var RoomListSorter = require("../../../RoomListSorter");
var UnreadStatus = require('../../../UnreadStatus');
var dis = require("../../../dispatcher");
var sdk = require('../../../index');

var HIDE_CONFERENCE_CHANS = true;

module.exports = React.createClass({
    displayName: 'RoomList',

    propTypes: {
        ConferenceHandler: React.PropTypes.any,
        collapsed: React.PropTypes.bool,
        currentRoom: React.PropTypes.string
    },

    getInitialState: function() {
        return {
            activityMap: null,
            lists: {},
        }
    },

    componentWillMount: function() {
        var cli = MatrixClientPeg.get();
        cli.on("Room", this.onRoom);
        cli.on("Room.timeline", this.onRoomTimeline);
        cli.on("Room.name", this.onRoomName);
        cli.on("Room.tags", this.onRoomTags);
        cli.on("RoomState.events", this.onRoomStateEvents);
        cli.on("RoomMember.name", this.onRoomMemberName);

        var s = this.getRoomLists();
        s.activityMap = {};
        this.setState(s);
    },

    componentDidMount: function() {
        this.dispatcherRef = dis.register(this.onAction);
    },

    onAction: function(payload) {
        switch (payload.action) {
            case 'view_tooltip':
                this.tooltip = payload.tooltip;
                this._repositionTooltip();
                if (this.tooltip) this.tooltip.style.display = 'block';
                break
        }
    },

    componentWillUnmount: function() {
        dis.unregister(this.dispatcherRef);
        if (MatrixClientPeg.get()) {
            MatrixClientPeg.get().removeListener("Room", this.onRoom);
            MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
            MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
            MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents);
        }
    },

    componentWillReceiveProps: function(newProps) {
        this.state.activityMap[newProps.selectedRoom] = undefined;
        this.setState({
            activityMap: this.state.activityMap
        });
    },

    onRoom: function(room) {
        this.refreshRoomList();
    },

    onRoomTimeline: function(ev, room, toStartOfTimeline) {
        if (toStartOfTimeline) return;

        var hl = 0;
        if (
            room.roomId != this.props.selectedRoom &&
            ev.getSender() != MatrixClientPeg.get().credentials.userId)
        {
            if (UnreadStatus.eventTriggersUnreadCount(ev)) {
                hl = 1;
            }

            var me = room.getMember(MatrixClientPeg.get().credentials.userId);
            var actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
            if ((actions && actions.tweaks && actions.tweaks.highlight) ||
                (me && me.membership == "invite"))
            {
                hl = 2;
            }
        }

        var newState = this.getRoomLists();
        if (hl > 0) {
            // obviously this won't deep copy but this shouldn't be necessary
            var amap = this.state.activityMap;
            amap[room.roomId] = Math.max(amap[room.roomId] || 0, hl);

            newState.activityMap = amap;

        }
        // still want to update the list even if the highlight status
        // hasn't changed because the ordering may have
        this.setState(newState);
    },

    onRoomName: function(room) {
        this.refreshRoomList();
    },

    onRoomTags: function(event, room) {
        this.refreshRoomList();
    },

    onRoomStateEvents: function(ev, state) {
        setTimeout(this.refreshRoomList, 0);
    },

    onRoomMemberName: function(ev, member) {
        setTimeout(this.refreshRoomList, 0);
    },

    refreshRoomList: function() {
        // TODO: rather than bluntly regenerating and re-sorting everything
        // every time we see any kind of room change from the JS SDK
        // we could do incremental updates on our copy of the state
        // based on the room which has actually changed.  This would stop
        // us re-rendering all the sublists every time anything changes anywhere
        // in the state of the client.
        this.setState(this.getRoomLists());
    },

    getRoomLists: function() {
        var self = this;
        var s = { lists: {} };

        s.lists["im.vector.fake.invite"] = [];
        s.lists["m.favourite"] = [];
        s.lists["im.vector.fake.recent"] = [];
        s.lists["m.lowpriority"] = [];
        s.lists["im.vector.fake.archived"] = [];

        MatrixClientPeg.get().getRooms().forEach(function(room) {
            var me = room.getMember(MatrixClientPeg.get().credentials.userId);

            if (me && me.membership == "invite") {
                s.lists["im.vector.fake.invite"].push(room);
            }
            else {
                var shouldShowRoom =  (
                    me && (me.membership == "join")
                );

                // hiding conf rooms only ever toggles shouldShowRoom to false
                if (shouldShowRoom && HIDE_CONFERENCE_CHANS) {
                    // we want to hide the 1:1 conf<->user room and not the group chat
                    var joinedMembers = room.getJoinedMembers();
                    if (joinedMembers.length === 2) {
                        var otherMember = joinedMembers.filter(function(m) {
                            return m.userId !== me.userId
                        })[0];
                        var ConfHandler = self.props.ConferenceHandler;
                        if (ConfHandler && ConfHandler.isConferenceUser(otherMember.userId)) {
                            // console.log("Hiding conference 1:1 room %s", room.roomId);
                            shouldShowRoom = false;
                        }
                    }
                }

                if (shouldShowRoom) {
                    var tagNames = Object.keys(room.tags);
                    if (tagNames.length) {
                        for (var i = 0; i < tagNames.length; i++) {
                            var tagName = tagNames[i];
                            s.lists[tagName] = s.lists[tagName] || [];
                            s.lists[tagNames[i]].push(room);
                        }
                    }
                    else {
                        s.lists["im.vector.fake.recent"].push(room);
                    }
                }
            }
        });

        //console.log("calculated new roomLists; im.vector.fake.recent = " + s.lists["im.vector.fake.recent"]);

        // we actually apply the sorting to this when receiving the prop in RoomSubLists.

        return s;
    },

    _repositionTooltip: function(e) {
        if (this.tooltip && this.tooltip.parentElement) {
            var scroll = ReactDOM.findDOMNode(this);
            this.tooltip.style.top = (scroll.parentElement.offsetTop + this.tooltip.parentElement.offsetTop - scroll.children[2].scrollTop) + "px";
        }
    },

    onShowClick: function() {
        dis.dispatch({
            action: 'show_left_panel',
        });
    },

    render: function() {
        var expandButton = this.props.collapsed ?
                           "/> :
                           null;

        var RoomSubList = sdk.getComponent('structures.RoomSubList');
        var self = this;

        return (
            <GeminiScrollbar className="mx_RoomList_scrollbar" autoshow={true} onScroll={self._repositionTooltip}>

                { expandButton }

                <RoomSubList list={ self.state.lists['im.vector.fake.invite'] }
                             label="Invites"
                             editable={ false }
                             order="recent"
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

                <RoomSubList list={ self.state.lists['m.favourite'] }
                             label="Favourites"
                             tagName="m.favourite"
                             verb="favourite"
                             editable={ true }
                             order="manual"
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

                <RoomSubList list={ self.state.lists['im.vector.fake.recent'] }
                             label="Rooms"
                             editable={ true }
                             verb="restore"
                             order="recent"
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

                { Object.keys(self.state.lists).map(function(tagName) {
                    if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|archived))$/)) {
                        return <RoomSubList list={ self.state.lists[tagName] }
                             key={ tagName }
                             label={ tagName }
                             tagName={ tagName }
                             verb={ "tag as " + tagName }
                             editable={ true }
                             order="manual"
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

                    }
                }) }

                <RoomSubList list={ self.state.lists['m.lowpriority'] }
                             label="Low priority"
                             tagName="m.lowpriority"
                             verb="demote"
                             editable={ true }
                             order="recent"
                             bottommost={ self.state.lists['im.vector.fake.archived'].length === 0 }
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

                <RoomSubList list={ self.state.lists['im.vector.fake.archived'] }
                             label="Historical"
                             editable={ false }
                             order="recent"
                             bottommost={ true }
                             activityMap={ self.state.activityMap }
                             selectedRoom={ self.props.selectedRoom }
                             collapsed={ self.props.collapsed } />

            </GeminiScrollbar>
        );
    }
});
<|endoftext|>