<commit_before>var pubnub = PUBNUB.init({
    publish_key   : 'demo',
    subscribe_key : 'demo'
});

var channel = 'javascript-test-channel-' + Math.random();
var count = 0;

var message_string = 'Hi from Javascript';
var message_jsono = {'message': 'Hi Hi from Javascript'};
var message_jsona = ['message' , 'Hi Hi from javascript'];

asyncTest("uuid() response", function() {
    expect(1);
    pubnub.uuid(function(uuid){
            ok(uuid, "Pass");
            start();
    });
});

asyncTest("uuid() response should be long enough", function() {
    expect(1);
    pubnub.uuid(function(uuid){
        ok(uuid.length > 10, "Pass");
        start();
    });
});

asyncTest("publish() should publish strings without error", function() {
    expect(2);
    var ch = channel + '-' + ++count;
    pubnub.subscribe({ channel : ch,
        connect : function(response)  {
            pubnub.publish({channel: ch, message: message_string,
                callback : function(response) {
                    deepEqual(response[0],1);
                }
            });
        },
        callback : function(response) {
            deepEqual(response, message_string);
            pubnub.unsubscribe({channel : ch});
            start();
        }
    });
});

asyncTest("publish() should publish json array without error", function() {
    expect(2);
    var ch = channel + '-' + ++count;
    pubnub.subscribe({ channel : ch,
        connect : function(response)  {
            pubnub.publish({channel: ch, message: message_jsona,
                callback : function(response) {
                    deepEqual(response[0],1);
                }
            });
        },
        callback : function(response) {
            deepEqual(response, message_jsona);
            pubnub.unsubscribe({channel : ch});
            start();
        }
    });
});

asyncTest("publish() should publish json object without error", function() {
    expect(2);
    var ch = channel + '-' + ++count;
    pubnub.subscribe({ channel : ch,
        connect : function(response)  {
            pubnub.publish({channel: ch, message: message_jsono,
                callback : function(response) {
                    deepEqual(response[0],1);
                }
            });
        },
        callback : function(response) {
            deepEqual(response, message_jsono);
            pubnub.unsubscribe({channel : ch});
            start();
        }
    });
});

asyncTest("#here_now() should show occupancy 1 when 1 user subscribed to channel", function() {
    expect(3);
    var ch = channel + '-' + 'here-now' ;
    pubnub.subscribe({channel : ch ,
        connect : function(response) {
            setTimeout(function() {
                pubnub.here_now( {channel : ch, callback : function(data) {
                    deepEqual(data.occupancy, 1);
                    start();
                    pubnub.unsubscribe({channel : ch});
                }})}, 10000
            );
            pubnub.publish({channel: ch , message : message_jsona,
                callback : function(response) {
                    deepEqual(response[0],1);
                }
            });
        },
        callback : function(response) {
            deepEqual(response, message_jsona);

        }
    });
});

asyncTest('#history() should return 1 messages when 2 messages were published on channel but count is 1', function() {
    var history_channel = channel + '-history-1';
    expect(3);
    pubnub.publish({channel: history_channel,
        message : message_string,
        callback : function(response){
            deepEqual(response[0],1);
            pubnub.publish({channel: history_channel,
                message : message_string,
                callback : function(response){
                    deepEqual(response[0],1);
                    setTimeout(function() {
                        pubnub.history({channel : history_channel,
                            count : 1,
                            callback : function(response) {
                                deepEqual(response[0].length, 1);
                                start();
                            }
                        });
                    }, 5000);
                }
            });
        }
    });
})
asyncTest('#history() should return 2 messages when 2 messages were published on channel', function() {
    var history_channel = channel + '-history-2';
    expect(3);
    pubnub.publish({channel: history_channel,
        message : message_string,
        callback : function(response){
            deepEqual(response[0],1);
            pubnub.publish({channel: history_channel,
                message : message_string,
                callback : function(response){
                    deepEqual(response[0],1);
                    setTimeout(function() {
                        pubnub.history({channel : history_channel,
                            callback : function(response) {
                                deepEqual(response[0].length, 2);
                                start();
                            }
                        });
                    }, 5000);
                }
            });
        }
    });
})

asyncTest('connection restore feature', function() {
    var restore_channel = channel + '-restore-channel';
    expect(2);

    pubnub.subscribe({
        restore: true,
        channel: restore_channel,
        callback: function () {
        },
        connect: function () {
            pubnub.unsubscribe({ channel: restore_channel });

            // Send Message While Not Connected
            pubnub.publish({
                channel: restore_channel,
                message: 'test',
                callback: function (response) {
                    deepEqual(response[0],1);
                    pubnub.subscribe({
                        restore: true,
                        channel: restore_channel,
                        callback: function (message, stack) {
                            pubnub.unsubscribe({ channel: restore_channel });
                            deepEqual(message, "test");
                            start();
                        }
                    });
                }
            });
        }
    });
})
asyncTest('Encryption tests', function() {
    var aes = PUBNUB.secure({
        publish_key: "demo",
        subscribe_key: "demo",
        cipher_key: "enigma"
    });
    expect(17);
    var test_plain_string_1 = "Pubnub Messaging API 1";
    var test_plain_string_2 = "Pubnub Messaging API 2";
    var test_plain_object_1 = {"foo": {"bar": "foobar"}};
    var test_plain_object_2 = {"this stuff": {"can get": "complicated!"}};
    var test_plain_unicode_1 = '漢語'
    var test_cipher_string_1 = "f42pIQcWZ9zbTbH8cyLwByD/GsviOE0vcREIEVPARR0=";
    var test_cipher_string_2 = "f42pIQcWZ9zbTbH8cyLwB/tdvRxjFLOYcBNMVKeHS54=";
    var test_cipher_object_1 = "GsvkCYZoYylL5a7/DKhysDjNbwn+BtBtHj2CvzC4Y4g=";
    var test_cipher_object_2 = "zMqH/RTPlC8yrAZ2UhpEgLKUVzkMI2cikiaVg30AyUu7B6J0FLqCazRzDOmrsFsF";
    var test_cipher_unicode_1 = "WvztVJ5SPNOcwrKsDrGlWQ==";

    ok(aes.raw_encrypt(test_plain_string_1) == test_cipher_string_1, "AES String Encryption Test 1");
    ok(aes.raw_encrypt(test_plain_string_2) == test_cipher_string_2, "AES String Encryption Test 2");
    ok(aes.raw_encrypt(test_plain_object_1) == test_cipher_object_1, "AES Object Encryption Test 1");
    ok(aes.raw_encrypt(test_plain_object_2) == test_cipher_object_2, "AES Object Encryption Test 2");
    ok(aes.raw_encrypt(test_plain_unicode_1) == test_cipher_unicode_1, "AES Unicode Encryption Test 1");
    ok(aes.raw_decrypt(test_cipher_string_1) == test_plain_string_1, "AES String Decryption Test 1");
    ok(aes.raw_decrypt(test_cipher_string_2) == test_plain_string_2, "AES String Decryption Test 2");
    ok(JSON.stringify(aes.raw_decrypt(test_cipher_object_1)) == JSON.stringify(test_plain_object_1), "AES Object Decryption Test 1");
    ok(JSON.stringify(aes.raw_decrypt(test_cipher_object_2)) == JSON.stringify(test_plain_object_2), "AES Object Decryption Test 2");
    ok(aes.raw_decrypt(test_cipher_unicode_1) == test_plain_unicode_1, "AES Unicode Decryption Test 1");

    aes_channel = channel + "aes-channel";

    aes.subscribe({
        channel: aes_channel,
        connect: function() {
            aes.publish({
                channel: aes_channel,
                message: { test: "test" },
                callback: function (response) {
                    ok(response[0], 'AES Successful Publish ' + response[0]);
                    ok(response[1], 'AES Success With Demo ' + response[1]);
                    setTimeout(function() {
                        aes.history({
                            limit: 1,
                            reverse: false,
                            channel: aes_channel,
                            callback: function (data) {
                                ok(data, 'AES History Response');
                                ok(data[0][0].test === "test", 'AES History Content');
                                start();
                            }
                        });
                    }, 6000);
                }
            });
        },
        presence: function (message, envelope, aes_channel) {

        },
        callback: function (message, envelope, aes_channel) {
            ok(message, 'AES Subscribe Message');
            ok(message.test === "test", 'AES Subscribe Message Data');
            ok(envelope[1], 'AES TimeToken Returned: ' + envelope[1]);
        }
    });
})
<commit_msg>formatting<commit_after>var pubnub = PUBNUB.init({
    publish_key   : 'demo',
    subscribe_key : 'demo'
});

var channel = 'javascript-test-channel-' + Math.random();
var count = 0;

var message_string = 'Hi from Javascript';
var message_jsono = {'message': 'Hi Hi from Javascript'};
var message_jsona = ['message' , 'Hi Hi from javascript'];

asyncTest("uuid() response", function() {
    expect(1);
    pubnub.uuid(function(uuid){
            ok(uuid, "Pass");
            start();
    });
});

asyncTest("uuid() response should be long enough", function() {
    expect(1);
    pubnub.uuid(function(uuid){
        ok(uuid.length > 10, "Pass");
        start();
    });
});

asyncTest("publish() should publish strings without error", function() {
    expect(2);
    var ch = channel + '-' + ++count;
    pubnub.subscribe({ channel : ch,
        connect : function(response)  {
            pubnub.publish({channel: ch, message: message_string,
                callback : function(response) {
                    deepEqual(response[0],1);
                }
            });
        },
        callback : function(response) {
            deepEqual(response, message_string);
            pubnub.unsubscribe({channel : ch});
            start();
        }
    });
});

asyncTest("publish() should publish json array without error", function() {
    expect(2);
    var ch = channel + '-' + ++count;
    pubnub.subscribe({ channel : ch,
        connect : function(response)  {
            pubnub.publish({channel: ch, message: message_jsona,
                callback : function(response) {
                    deepEqual(response[0],1);
                }
            });
        },
        callback : function(response) {
            deepEqual(response, message_jsona);
            pubnub.unsubscribe({channel : ch});
            start();
        }
    });
});

asyncTest("publish() should publish json object without error", function() {
    expect(2);
    var ch = channel + '-' + ++count;
    pubnub.subscribe({ channel : ch,
        connect : function(response)  {
            pubnub.publish({channel: ch, message: message_jsono,
                callback : function(response) {
                    deepEqual(response[0],1);
                }
            });
        },
        callback : function(response) {
            deepEqual(response, message_jsono);
            pubnub.unsubscribe({channel : ch});
            start();
        }
    });
});

asyncTest("#here_now() should show occupancy 1 when 1 user subscribed to channel", function() {
    expect(3);
    var ch = channel + '-' + 'here-now' ;
    pubnub.subscribe({channel : ch ,
        connect : function(response) {
            setTimeout(function() {
                pubnub.here_now( {channel : ch, callback : function(data) {
                    deepEqual(data.occupancy, 1);
                    start();
                    pubnub.unsubscribe({channel : ch});
                }})}, 10000
            );
            pubnub.publish({channel: ch , message : message_jsona,
                callback : function(response) {
                    deepEqual(response[0],1);
                }
            });
        },
        callback : function(response) {
            deepEqual(response, message_jsona);

        }
    });
});

asyncTest('#history() should return 1 messages when 2 messages were published on channel but count is 1', function() {
    var history_channel = channel + '-history-1';
    expect(3);
    pubnub.publish({channel: history_channel,
        message : message_string,
        callback : function(response){
            deepEqual(response[0],1);
            pubnub.publish({channel: history_channel,
                message : message_string,
                callback : function(response){
                    deepEqual(response[0],1);
                    setTimeout(function() {
                        pubnub.history({channel : history_channel,
                            count : 1,
                            callback : function(response) {
                                deepEqual(response[0].length, 1);
                                start();
                            }
                        });
                    }, 5000);
                }
            });
        }
    });
})
asyncTest('#history() should return 2 messages when 2 messages were published on channel', function() {
    var history_channel = channel + '-history-2';
    expect(3);
    pubnub.publish({channel: history_channel,
        message : message_string,
        callback : function(response){
            deepEqual(response[0],1);
            pubnub.publish({channel: history_channel,
                message : message_string,
                callback : function(response){
                    deepEqual(response[0],1);
                    setTimeout(function() {
                        pubnub.history({channel : history_channel,
                            callback : function(response) {
                                deepEqual(response[0].length, 2);
                                start();
                            }
                        });
                    }, 5000);
                }
            });
        }
    });
})

asyncTest('connection restore feature', function() {
    var restore_channel = channel + '-restore-channel';
    expect(2);

    pubnub.subscribe({
        restore: true,
        channel: restore_channel,
        callback: function () {
        },
        connect: function () {
            pubnub.unsubscribe({ channel: restore_channel });

            // Send Message While Not Connected
            pubnub.publish({
                channel: restore_channel,
                message: 'test',
                callback: function (response) {
                    deepEqual(response[0],1);
                    pubnub.subscribe({
                        restore: true,
                        channel: restore_channel,
                        callback: function (message, stack) {
                            pubnub.unsubscribe({ channel: restore_channel });
                            deepEqual(message, "test");
                            start();
                        }
                    });
                }
            });
        }
    });
})
asyncTest('Encryption tests', function() {
    var aes = PUBNUB.secure({
        publish_key: "demo",
        subscribe_key: "demo",
        cipher_key: "enigma"
    });
    expect(17);
    var test_plain_string_1 = "Pubnub Messaging API 1";
    var test_plain_string_2 = "Pubnub Messaging API 2";
    var test_plain_object_1 = {"foo": {"bar": "foobar"}};
    var test_plain_object_2 = {"this stuff": {"can get": "complicated!"}};
    var test_plain_unicode_1 = '漢語'
    var test_cipher_string_1 = "f42pIQcWZ9zbTbH8cyLwByD/GsviOE0vcREIEVPARR0=";
    var test_cipher_string_2 = "f42pIQcWZ9zbTbH8cyLwB/tdvRxjFLOYcBNMVKeHS54=";
    var test_cipher_object_1 = "GsvkCYZoYylL5a7/DKhysDjNbwn+BtBtHj2CvzC4Y4g=";
    var test_cipher_object_2 = "zMqH/RTPlC8yrAZ2UhpEgLKUVzkMI2cikiaVg30AyUu7B6J0FLqCazRzDOmrsFsF";
    var test_cipher_unicode_1 = "WvztVJ5SPNOcwrKsDrGlWQ==";

    ok(aes.raw_encrypt(test_plain_string_1) == test_cipher_string_1, "AES String Encryption Test 1");
    ok(aes.raw_encrypt(test_plain_string_2) == test_cipher_string_2, "AES String Encryption Test 2");
    ok(aes.raw_encrypt(test_plain_object_1) == test_cipher_object_1, "AES Object Encryption Test 1");
    ok(aes.raw_encrypt(test_plain_object_2) == test_cipher_object_2, "AES Object Encryption Test 2");
    ok(aes.raw_encrypt(test_plain_unicode_1) == test_cipher_unicode_1, "AES Unicode Encryption Test 1");
    ok(aes.raw_decrypt(test_cipher_string_1) == test_plain_string_1, "AES String Decryption Test 1");
    ok(aes.raw_decrypt(test_cipher_string_2) == test_plain_string_2, "AES String Decryption Test 2");
    ok(JSON.stringify(aes.raw_decrypt(test_cipher_object_1)) == JSON.stringify(test_plain_object_1), "AES Object Decryption Test 1");
    ok(JSON.stringify(aes.raw_decrypt(test_cipher_object_2)) == JSON.stringify(test_plain_object_2), "AES Object Decryption Test 2");
    ok(aes.raw_decrypt(test_cipher_unicode_1) == test_plain_unicode_1, "AES Unicode Decryption Test 1");

    aes_channel = channel + "aes-channel";

    aes.subscribe({
        channel: aes_channel,
        connect: function() {
            aes.publish({
                channel: aes_channel,
                message: { test: "test" },
                callback: function (response) {
                    ok(response[0], 'AES Successful Publish ' + response[0]);
                    ok(response[1], 'AES Success With Demo ' + response[1]);
                    setTimeout(function() {
                        aes.history({
                            limit: 1,
                            reverse: false,
                            channel: aes_channel,
                            callback: function (data) {
                                ok(data, 'AES History Response');
                                ok(data[0][0].test === "test", 'AES History Content');
                                start();
                            }
                        });
                    }, 6000);
                }
            });
        },
        presence: function (message, envelope, aes_channel) {

        },
        callback: function (message, envelope, aes_channel) {
            ok(message, 'AES Subscribe Message');
            ok(message.test === "test", 'AES Subscribe Message Data');
            ok(envelope[1], 'AES TimeToken Returned: ' + envelope[1]);
        }
    });
})
<|endoftext|>


<commit_before>$(document).ready(function() {
    $(".search-box").on("input", function(){
        var val = $(this).val().toLowerCase();

        var notags = [];
        var nomatches = val.match(/notag:\w+/g);
        if (nomatches) {
            $.each(nomatches, function(k, v) {
                notags.push(v.substring(6).toLowerCase());
            });
        }
        val = $.trim(val.replace(/\s*notag:\w+/g, ""));

        var tags = [];

        var show_online = false;
        var show_offline = false;

        var matches = val.match(/tag:\w+/g);
        if (matches) {
            $.each(matches, function(k, v) {
                var tag = v.substring(4).toLowerCase();
                if (tag == "online") {
                    show_online = true;
                }
                else if (tag == "offline") {
                    show_offline = true;
                }
                else {
                    tags.push(tag);
                }
            });
        }
        val = $.trim(val.replace(/\s*tag:\w+/g, ""));
        var search_objects = $(this).data("search");
        var search_fields = $(this).data("fields").split(",");
        $(search_objects).each(function(k, v) {
            var fields = $.map(search_fields, function(val, i) {
                return $(this).find(val).text().toLowerCase();
            });
            var show = true;
            var site_tags = null;
            if (tags.length || notags.length) {
                site_tags = [];
                $(this).find(".tag").each(function(k, v) {
                    site_tags.push($(this).text().replace(/\W/g, "").toLowerCase());
                });
            }
            if (tags.length) {
                show = false;
                $.each(tags, function(k, v) {
                    $.each(site_tags, function(k2, v2) {
                        if (v2.indexOf(v) != -1) {
                            show = true;
                            return false;
                        }
                    });
                });
            }
            if (notags.length) {
                $.each(notags, function(k, v) {
                    $.each(site_tags, function(k2, v2) {
                        if (v2.indexOf(v) != -1) {
                            show = false;
                            return false;
                        }
                    });
                });
            }
            var matches = false;
            $.each(search_fields, function(k, v) {
                if (v.includes(val)) {
                    matches = true;
                    return false;
                }
            });
            if (show_offline) {
                if (!$(this).find(".fa.pull-left span").hasClass("red")) {
                    show = false;
                }
            }
            if (show_online) {
                if (!$(this).find(".fa.pull-left span").hasClass("green")) {
                    show = false;
                }
            }
            if (show && matches) {
                $(this).show();
            }
            else {
                $(this).hide();
            }
        });
        var sites_shown = $(search_objects + ":visible").length;
        var sites_total = $(search_objects).length;
        if (sites_shown < sites_total) {
            $("#filtered").html("(" + sites_shown + " shown out of " + sites_total + ")");
        }
        else {
            $("#filtered").html("");
        }
    });
});
<commit_msg>fix search<commit_after>$(document).ready(function() {
    $(".search-box").on("input", function(){
        var val = $(this).val().toLowerCase();

        var notags = [];
        var nomatches = val.match(/notag:\w+/g);
        if (nomatches) {
            $.each(nomatches, function(k, v) {
                notags.push(v.substring(6).toLowerCase());
            });
        }
        val = $.trim(val.replace(/\s*notag:\w+/g, ""));

        var tags = [];

        var show_online = false;
        var show_offline = false;

        var matches = val.match(/tag:\w+/g);
        if (matches) {
            $.each(matches, function(k, v) {
                var tag = v.substring(4).toLowerCase();
                if (tag == "online") {
                    show_online = true;
                }
                else if (tag == "offline") {
                    show_offline = true;
                }
                else {
                    tags.push(tag);
                }
            });
        }
        val = $.trim(val.replace(/\s*tag:\w+/g, ""));
        var search_objects = $(this).data("search");
        var search_fields = $(this).data("fields").split(",");
        $(search_objects).each(function(k, v) {
            var t = $(this);
            var fields = $.map(search_fields, function(val, i) {
                return t.find(val).text().toLowerCase();
            });
            var show = true;
            var site_tags = null;
            if (tags.length || notags.length) {
                site_tags = [];
                $(this).find(".tag").each(function(k, v) {
                    site_tags.push($(this).text().replace(/\W/g, "").toLowerCase());
                });
            }
            if (tags.length) {
                show = false;
                $.each(tags, function(k, v) {
                    $.each(site_tags, function(k2, v2) {
                        if (v2.indexOf(v) != -1) {
                            show = true;
                            return false;
                        }
                    });
                });
            }
            if (notags.length) {
                $.each(notags, function(k, v) {
                    $.each(site_tags, function(k2, v2) {
                        if (v2.indexOf(v) != -1) {
                            show = false;
                            return false;
                        }
                    });
                });
            }
            var matches = false;
            $.each(search_fields, function(k, v) {
                if (v.includes(val)) {
                    matches = true;
                    return false;
                }
            });
            if (show_offline) {
                if (!$(this).find(".fa.pull-left span").hasClass("red")) {
                    show = false;
                }
            }
            if (show_online) {
                if (!$(this).find(".fa.pull-left span").hasClass("green")) {
                    show = false;
                }
            }
            if (show && matches) {
                $(this).show();
            }
            else {
                $(this).hide();
            }
        });
        var sites_shown = $(search_objects + ":visible").length;
        var sites_total = $(search_objects).length;
        if (sites_shown < sites_total) {
            $("#filtered").html("(" + sites_shown + " shown out of " + sites_total + ")");
        }
        else {
            $("#filtered").html("");
        }
    });
});
<|endoftext|>


<commit_before>/* @flow */

import type { Context, Logger } from '../../types.js';

const fs = require('fs');
const spawn = require('cross-spawn').spawn;
const path = require('path');

// This is a necessary hack to find Jest depending if node_modules has flatten dependencies or not
const JEST_PATH = `${require.resolve('jest').split('jest')[0]}.bin/jest`;
const JEST_DEBUG_CONFIG_PATH = path.join(__dirname, 'jestEnvironmentNodeDebug.js');
const TEST_MOCKS_PATH = `${path.join(__dirname)}`;

const mergeCustomConfig = (defaultConfig: Object): Object => {
  const customConfig: Object = require(path.join(process.cwd(), 'package.json')).jest;
  if (!customConfig) {
    return defaultConfig;
  }

  return Object.keys(customConfig).reduce((prev: Object, curr: string): Object => {
    return {
      ...prev,
      [curr]: Array.isArray(customConfig[curr]) && Array.isArray(defaultConfig[curr])
        ? defaultConfig[curr].concat(customConfig[curr])
        : customConfig[curr],
    };
  }, defaultConfig);
};

const getJestDefaultConfig = (aliases: Object, webpackRules: RegExp[]): string[] => {
  const moduleNameMapper = {};

  // Handling Static Assets = mock them out
  const fileRegex: RegExp = new RegExp(
    `${webpackRules[3].source}|${webpackRules[4].source}|${webpackRules[5].source}`,
  );
  moduleNameMapper[fileRegex.source] = `${TEST_MOCKS_PATH}/fileMock.js`;
  const stylesRegex: RegExp = new RegExp(`${webpackRules[1].source}|${webpackRules[2].source}`);
  moduleNameMapper[stylesRegex.source] = `${TEST_MOCKS_PATH}/styleMock.js`;

  // We map webpack aliases from webpack-isomorphic-tools-config file
  // so Jest can detect them in tests too
  Object.keys(aliases).forEach((key) => {
    moduleNameMapper[`^${key}(.*)$`] = `${aliases[key]}$1`;
  });

  const roots: string[] = ['src'];
  if (fs.existsSync(path.join(process.cwd(), 'test'))) {
    // Previous to gluestick 1.0, projects used to have test folder, if that folder is not present
    // and we add it to the roots, the watch mode of Jest will fail: ENOENT
    roots[roots.length] = 'test';
  }

  const config = {
    testRegex: '\\/__tests__\\/.*\\.(test|spec)\\.jsx?$',
    moduleNameMapper,
    roots,
    transformIgnorePatterns: [
      '/node_modules/(?!gluestick-addon-)',
    ],
    // Clear watchman warnings (including the one of `test` folder non-existing for new projects)
    // Might be worth in the future to come back here and see if there is a really difference
    // using watchman or not
    watchman: false,
  };

  const argv: string[] = [];
  argv.push('--config', JSON.stringify(mergeCustomConfig(config)));
  return argv;
};

const getDebugDefaultConfig = (
  logger: Logger, aliases: Object, webpackRules: RegExp[], options: string[],
): string[] => {
  const argv = [];
  argv.push('--inspect');
  argv.push('--debug-brk');
  argv.push(JEST_PATH);
  argv.push('--env');
  argv.push(JEST_DEBUG_CONFIG_PATH);
  argv.push(...getJestDefaultConfig(aliases, webpackRules));
  argv.push('-i');
  argv.push('--watch');
  // Exclude those options to avoid dublication.
  const optionsToExclude = [
    { value: '-D' },
    { value: '--debug-test' },
    { value: '-i', printMsg: true },
    { value: '--runInBand', printMsg: true },
    { value: '--watch', printMsg: true },
    { value: '--config', printMsg: true },
    { value: '-c', printMsg: true },
  ];
  return argv.concat(
    options.filter((option: string): boolean => {
      return optionsToExclude.findIndex((optionToExclude: Object): boolean => {
        const check = new RegExp(`^${optionToExclude.value}.*`).test(option);
        if (check && optionToExclude.printMsg) {
          logger.info(`Option '${optionToExclude.value}' is always set by default in debug mode`);
        }
        return check;
      }) === -1;
    }),
  );
};

module.exports = (context: Context, ...commandArguments: any[]) => {
  const spawnOptions = {
    stdio: 'inherit',
  };
  // $FlowFixMe
  const aliases: Object = context.config.webpackConfig.client.resolve.alias;
  // $FlowFixMe
  const webpackRules: RegExp[] = context.config.webpackConfig.client.module.rules.map(
    rule => rule.test,
  );
  const options: Object = commandArguments[commandArguments.length - 1];
  const rawOptions: string[] = options.parent.rawArgs.slice(3);
  if (options.debugTest) {
    const argvDebug: string[] = getDebugDefaultConfig(
      context.logger, aliases, webpackRules, rawOptions,
    );
    spawn.sync('node', argvDebug, spawnOptions);
  } else {
    const jest = require('jest');
    const argv: string[] = getJestDefaultConfig(aliases, webpackRules).concat(rawOptions);
    // Since we require Jest programmatically, we need to make sure
    // to set NODE_ENV='test' when running it
    process.env.NODE_ENV = 'test';
    jest.run(argv);
  }
};
<commit_msg>#861: Tell Jest to ignore all gluestick related on transformIgnorePatterns as for now we ship it without compiling it.<commit_after>/* @flow */

import type { Context, Logger } from '../../types.js';

const fs = require('fs');
const spawn = require('cross-spawn').spawn;
const path = require('path');

// This is a necessary hack to find Jest depending if node_modules has flatten dependencies or not
const JEST_PATH = `${require.resolve('jest').split('jest')[0]}.bin/jest`;
const JEST_DEBUG_CONFIG_PATH = path.join(__dirname, 'jestEnvironmentNodeDebug.js');
const TEST_MOCKS_PATH = `${path.join(__dirname)}`;

const mergeCustomConfig = (defaultConfig: Object): Object => {
  const customConfig: Object = require(path.join(process.cwd(), 'package.json')).jest;
  if (!customConfig) {
    return defaultConfig;
  }

  return Object.keys(customConfig).reduce((prev: Object, curr: string): Object => {
    return {
      ...prev,
      [curr]: Array.isArray(customConfig[curr]) && Array.isArray(defaultConfig[curr])
        ? defaultConfig[curr].concat(customConfig[curr])
        : customConfig[curr],
    };
  }, defaultConfig);
};

const getJestDefaultConfig = (aliases: Object, webpackRules: RegExp[]): string[] => {
  const moduleNameMapper = {};

  // Handling Static Assets = mock them out
  const fileRegex: RegExp = new RegExp(
    `${webpackRules[3].source}|${webpackRules[4].source}|${webpackRules[5].source}`,
  );
  moduleNameMapper[fileRegex.source] = `${TEST_MOCKS_PATH}/fileMock.js`;
  const stylesRegex: RegExp = new RegExp(`${webpackRules[1].source}|${webpackRules[2].source}`);
  moduleNameMapper[stylesRegex.source] = `${TEST_MOCKS_PATH}/styleMock.js`;

  // We map webpack aliases from webpack-isomorphic-tools-config file
  // so Jest can detect them in tests too
  Object.keys(aliases).forEach((key) => {
    moduleNameMapper[`^${key}(.*)$`] = `${aliases[key]}$1`;
  });

  const roots: string[] = ['src'];
  if (fs.existsSync(path.join(process.cwd(), 'test'))) {
    // Previous to gluestick 1.0, projects used to have test folder, if that folder is not present
    // and we add it to the roots, the watch mode of Jest will fail: ENOENT
    roots[roots.length] = 'test';
  }

  const config = {
    testRegex: '\\/__tests__\\/.*\\.(test|spec)\\.jsx?$',
    moduleNameMapper,
    roots,
    transformIgnorePatterns: [
      '/node_modules/(?!gluestick)',
    ],
    // Clear watchman warnings (including the one of `test` folder non-existing for new projects)
    // Might be worth in the future to come back here and see if there is a really difference
    // using watchman or not
    watchman: false,
  };

  const argv: string[] = [];
  argv.push('--config', JSON.stringify(mergeCustomConfig(config)));
  return argv;
};

const getDebugDefaultConfig = (
  logger: Logger, aliases: Object, webpackRules: RegExp[], options: string[],
): string[] => {
  const argv = [];
  argv.push('--inspect');
  argv.push('--debug-brk');
  argv.push(JEST_PATH);
  argv.push('--env');
  argv.push(JEST_DEBUG_CONFIG_PATH);
  argv.push(...getJestDefaultConfig(aliases, webpackRules));
  argv.push('-i');
  argv.push('--watch');
  // Exclude those options to avoid dublication.
  const optionsToExclude = [
    { value: '-D' },
    { value: '--debug-test' },
    { value: '-i', printMsg: true },
    { value: '--runInBand', printMsg: true },
    { value: '--watch', printMsg: true },
    { value: '--config', printMsg: true },
    { value: '-c', printMsg: true },
  ];
  return argv.concat(
    options.filter((option: string): boolean => {
      return optionsToExclude.findIndex((optionToExclude: Object): boolean => {
        const check = new RegExp(`^${optionToExclude.value}.*`).test(option);
        if (check && optionToExclude.printMsg) {
          logger.info(`Option '${optionToExclude.value}' is always set by default in debug mode`);
        }
        return check;
      }) === -1;
    }),
  );
};

module.exports = (context: Context, ...commandArguments: any[]) => {
  const spawnOptions = {
    stdio: 'inherit',
  };
  // $FlowFixMe
  const aliases: Object = context.config.webpackConfig.client.resolve.alias;
  // $FlowFixMe
  const webpackRules: RegExp[] = context.config.webpackConfig.client.module.rules.map(
    rule => rule.test,
  );
  const options: Object = commandArguments[commandArguments.length - 1];
  const rawOptions: string[] = options.parent.rawArgs.slice(3);
  if (options.debugTest) {
    const argvDebug: string[] = getDebugDefaultConfig(
      context.logger, aliases, webpackRules, rawOptions,
    );
    spawn.sync('node', argvDebug, spawnOptions);
  } else {
    const jest = require('jest');
    const argv: string[] = getJestDefaultConfig(aliases, webpackRules).concat(rawOptions);
    // Since we require Jest programmatically, we need to make sure
    // to set NODE_ENV='test' when running it
    process.env.NODE_ENV = 'test';
    jest.run(argv);
  }
};
<|endoftext|>


<commit_before>// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.

/**
 * Breadcrumb component
 *
 * Shows the user's current location in a hierarchy and provides a means of navigating upward.
 *
 */

/**
 * @namespace fabric
 */
var fabric = fabric || {};
/**
 *
 * @param {HTMLElement} container - the target container for an instance of Breadcrumb
 * @constructor
 *
 * If dynamically populating a list run the constructor after the list has been populated
 * in the DOM.
 */
fabric.Breadcrumb = function(container) {
  this.breadcrumb = container;
  this.breadcrumbList = container.querySelector('.ms-Breadcrumb-list');
  this.listItems = container.querySelectorAll('.ms-Breadcrumb-listItem');
  this.contextMenu = container.querySelector('.ms-ContextualMenu');
  this.overflowButton = container.querySelector('.ms-Breadcrumb-overflowButton');
  this.overflowMenu = container.querySelector('.ms-Breadcrumb-overflowMenu');
  this.itemCollection = [];
  this.currentMaxItems = 0;
  this.init(this);

};

fabric.Breadcrumb.prototype = (function() {

  //medium breakpoint
  var MEDIUM = 639;

  /**
   * create internal model of list items from DOM
   */
  var _createItemCollection = function() {
    var length = this.listItems.length;
    var i = 0;
    var item;
    var text;
    var link;
    var tabIndex;

    for (i; i < length; i++) {
      item = this.listItems[i].querySelector('.ms-Breadcrumb-itemLink');
      text = item.textContent;
      link = item.getAttribute('href');
      tabIndex = parseInt(item.getAttribute('tabindex'), 10);
      this.itemCollection.push({text: text, link: link, tabIndex: tabIndex});
    }
  };

  /**
   * Re-render lists on resize
   *
   */
  var _onResize = function() {
    _closeOverflow.call(this, null);
    _renderListOnResize.call(this);
  };

  /**
   * render breadcrumbs and overflow menus on resize
   */
  var _renderListOnResize = function() {
    var maxItems = window.innerWidth > MEDIUM ? 4 : 2;
    if (maxItems !== this.currentMaxItems) {
      _updateBreadcrumbs.call(this);
    }

    this.currentMaxItems = maxItems;
  };

  /**
   * creates the overflow menu
   */
  var _addItemsToOverflow = function(maxItems) {
    _resetList.call(this, this.contextMenu);
    var end = this.itemCollection.length - maxItems;
    var overflowItems = this.itemCollection.slice(0, end);
    var contextMenu = this.contextMenu;
    overflowItems.forEach(function(item) {
      var li = document.createElement('li');
      li.className = 'ms-ContextualMenu-item';
      if(!isNaN(item.tabIndex)) {
        li.setAttribute('tabindex', item.tabIndex);
      }
      var a = document.createElement('a');
      a.className = 'ms-ContextualMenu-link';
      if (item.link !== null) {
        a.setAttribute('href', item.link);
      }
      a.textContent = item.text;
      li.appendChild(a);
      contextMenu.appendChild(li);
    });
  };

  /**
   * creates the breadcrumbs
   */
  var _addBreadcrumbItems = function(maxItems) {
    _resetList.call(this, this.breadcrumbList);
    var i = this.itemCollection.length - maxItems;
    i = i < 0 ? 0 : i;
    if (i >= 0) {
      for (i; i < this.itemCollection.length; i++) {
        var listItem = document.createElement('li');
        var item = this.itemCollection[i];
        var a = document.createElement('a');
        var chevron = document.createElement('i');
        listItem.className = 'ms-Breadcrumb-listItem';
        a.className = 'ms-Breadcrumb-itemLink';
        if (item.link !== null) {
          a.setAttribute('href', item.link);
        }
        if (!isNaN(item.tabIndex)) {
          a.setAttribute('tabindex', item.tabIndex);
        }
        a.textContent = item.text;
        chevron.className = 'ms-Breadcrumb-chevron ms-Icon ms-Icon--chevronRight';
        listItem.appendChild(a);
        listItem.appendChild(chevron);
        this.breadcrumbList.appendChild(listItem);
      }
    }
  };

  /**
   * resets a list by removing its children
   */
  var _resetList = function(list) {
    while (list.firstChild) {
      list.removeChild(list.firstChild);
    }
  };

  /**
   * opens the overflow menu
   */
  var _openOverflow = function(event) {
    if (this.overflowMenu.className.indexOf(' is-open') === -1) {
      this.overflowMenu.className += ' is-open';
      removeOutlinesOnClick.call(this, event);
      // force focus rect onto overflow button
      this.overflowButton.focus();
    }
  };

  var _overflowKeyPress = function(event) {
    if (event.keyCode === 13) {
      _openOverflow.call(this, event);
    }
  };

  /**
   * closes the overflow menu
   */
  var _closeOverflow = function(event) {
    if (!event || event.target !== this.overflowButton) {
      _removeClass.call(this, this.overflowMenu, ' is-open');
    }
  };

  /**
   * utility that removes a class from an element
   */
  var _removeClass = function (element, value) {
    var index = element.className.indexOf(value);
    if (index > -1) {
      element.className = element.className.substring(0, index);
    }
  };

  /**
   * sets handlers for resize and button click events
   */
  var _setListeners = function() {
    window.addEventListener('resize', _onResize.bind(this), false);
    document.addEventListener('click', _closeOverflow.bind(this), false);
    this.overflowButton.addEventListener('click', _openOverflow.bind(this), false);
    this.overflowButton.addEventListener('keypress', _overflowKeyPress.bind(this), false);
    this.breadcrumbList.addEventListener('click', removeOutlinesOnClick.bind(this), false);
  };

  /**
   * removes focus outlines so they don't linger after click
   */
  var removeOutlinesOnClick = function(event) {
    event.target.blur();
  };

  /**
   * updates the breadcrumbs and overflow menu
   */
  var _updateBreadcrumbs = function() {
    var maxItems = window.innerWidth > MEDIUM ? 4 : 2;
    if (this.itemCollection.length > maxItems) {
      this.breadcrumb.className += ' is-overflow';
    } else {
      _removeClass.call(this, this.breadcrumb, ' is-overflow');
    }

    _addBreadcrumbItems.call(this, maxItems);
    _addItemsToOverflow.call(this, maxItems);
  };

  /**
   * initializes component
   */
  var init = function(context) {
    _setListeners.call(this);
    _createItemCollection.call(this);
    _onResize.call(this, null);
  };

  /**
   * Adds a breadcrumb item to a breadcrumb
   * @param itemLabel {String} the item's text label
   * @param itemLink {String} the item's href link
   * @param tabIndex {number} the item's tabIndex
   */
  var addItem = function(itemLabel, itemLink, tabIndex) {
    this.itemCollection.push({text: itemLabel, link: itemLink, tabIndex: tabIndex});
    _updateBreadcrumbs.call(this);
  };

  /**
   * Removes a breadcrumb item to a breadcrumb
   * @param itemLabel {String} the item's text label
   */
  var removeItemByLabel = function(itemLabel) {
    var i = this.itemCollection.length;
    while(i--) {
      if(this.itemCollection[i].text === itemLabel) {
        this.itemCollection.splice(i, 1);
      }
    }
    _updateBreadcrumbs.call(this);
  };

  /**
   * adds a breadcrumb item to a breadcrumb
   * @param itemLabel {String} the item's text label
   * @param itemLink {String} the item's href link
   * @param tabIndex {number} the item's tabIndex
   */
  return {
    init: init,
    addItem: addItem,
    removeItemByLabel: removeItemByLabel
  };

}());

<commit_msg>Cleaned up code. Added removeItemByListPosition to remove breadcrumb items by position in breadcrumb list.<commit_after>// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.

/**
 * Breadcrumb component
 *
 * Shows the user's current location in a hierarchy and provides a means of navigating upward.
 *
 */

/**
 * @namespace fabric
 */
var fabric = fabric || {};
/**
 *
 * @param {HTMLElement} container - the target container for an instance of Breadcrumb
 * @constructor
 *
 * If dynamically populating a list run the constructor after the list has been populated
 * in the DOM.
 */
fabric.Breadcrumb = function(container) {
  this.breadcrumb = container;
  this.breadcrumbList = container.querySelector('.ms-Breadcrumb-list');
  this.listItems = container.querySelectorAll('.ms-Breadcrumb-listItem');
  this.contextMenu = container.querySelector('.ms-ContextualMenu');
  this.overflowButton = container.querySelector('.ms-Breadcrumb-overflowButton');
  this.overflowMenu = container.querySelector('.ms-Breadcrumb-overflowMenu');
  this.itemCollection = [];
  this.currentMaxItems = 0;
  this.init();

};

fabric.Breadcrumb.prototype = (function() {

  //medium breakpoint
  var MEDIUM = 639;

  /**
   * create internal model of list items from DOM
   */
  var _createItemCollection = function() {
    var length = this.listItems.length;
    var i = 0;
    var item;
    var text;
    var link;
    var tabIndex;

    for (i; i < length; i++) {
      item = this.listItems[i].querySelector('.ms-Breadcrumb-itemLink');
      text = item.textContent;
      link = item.getAttribute('href');
      tabIndex = parseInt(item.getAttribute('tabindex'), 10);
      this.itemCollection.push({text: text, link: link, tabIndex: tabIndex});
    }
  };

  /**
   * Re-render lists on resize
   *
   */
  var _onResize = function() {
    _closeOverflow.call(this, null);
    _renderListOnResize.call(this);
  };

  /**
   * render breadcrumbs and overflow menus on resize
   */
  var _renderListOnResize = function() {
    var maxItems = window.innerWidth > MEDIUM ? 4 : 2;
    if (maxItems !== this.currentMaxItems) {
      _updateBreadcrumbs.call(this);
    }

    this.currentMaxItems = maxItems;
  };

  /**
   * creates the overflow menu
   */
  var _addItemsToOverflow = function(maxItems) {
    _resetList.call(this, this.contextMenu);
    var end = this.itemCollection.length - maxItems;
    var overflowItems = this.itemCollection.slice(0, end);
    var contextMenu = this.contextMenu;
    overflowItems.forEach(function(item) {
      var li = document.createElement('li');
      li.className = 'ms-ContextualMenu-item';
      if(!isNaN(item.tabIndex)) {
        li.setAttribute('tabindex', item.tabIndex);
      }
      var a = document.createElement('a');
      a.className = 'ms-ContextualMenu-link';
      if (item.link !== null) {
        a.setAttribute('href', item.link);
      }
      a.textContent = item.text;
      li.appendChild(a);
      contextMenu.appendChild(li);
    });
  };

  /**
   * creates the breadcrumbs
   */
  var _addBreadcrumbItems = function(maxItems) {
    _resetList.call(this, this.breadcrumbList);
    var i = this.itemCollection.length - maxItems;
    i = i < 0 ? 0 : i;
    if (i >= 0) {
      for (i; i < this.itemCollection.length; i++) {
        var listItem = document.createElement('li');
        var item = this.itemCollection[i];
        var a = document.createElement('a');
        var chevron = document.createElement('i');
        listItem.className = 'ms-Breadcrumb-listItem';
        a.className = 'ms-Breadcrumb-itemLink';
        if (item.link !== null) {
          a.setAttribute('href', item.link);
        }
        if (!isNaN(item.tabIndex)) {
          a.setAttribute('tabindex', item.tabIndex);
        }
        a.textContent = item.text;
        chevron.className = 'ms-Breadcrumb-chevron ms-Icon ms-Icon--chevronRight';
        listItem.appendChild(a);
        listItem.appendChild(chevron);
        this.breadcrumbList.appendChild(listItem);
      }
    }
  };

  /**
   * resets a list by removing its children
   */
  var _resetList = function(list) {
    while (list.firstChild) {
      list.removeChild(list.firstChild);
    }
  };

  /**
   * opens the overflow menu
   */
  var _openOverflow = function(event) {
    if (this.overflowMenu.className.indexOf(' is-open') === -1) {
      this.overflowMenu.className += ' is-open';
      removeOutlinesOnClick.call(this, event);
      // force focus rect onto overflow button
      this.overflowButton.focus();
    }
  };

  var _overflowKeyPress = function(event) {
    if (event.keyCode === 13) {
      _openOverflow.call(this, event);
    }
  };

  /**
   * closes the overflow menu
   */
  var _closeOverflow = function(event) {
    if (!event || event.target !== this.overflowButton) {
      _removeClass.call(this, this.overflowMenu, ' is-open');
    }
  };

  /**
   * utility that removes a class from an element
   */
  var _removeClass = function (element, value) {
    var index = element.className.indexOf(value);
    if (index > -1) {
      element.className = element.className.substring(0, index);
    }
  };

  /**
   * sets handlers for resize and button click events
   */
  var _setListeners = function() {
    window.addEventListener('resize', _onResize.bind(this), false);
    document.addEventListener('click', _closeOverflow.bind(this), false);
    this.overflowButton.addEventListener('click', _openOverflow.bind(this), false);
    this.overflowButton.addEventListener('keypress', _overflowKeyPress.bind(this), false);
    this.breadcrumbList.addEventListener('click', removeOutlinesOnClick.bind(this), false);
  };

  /**
   * removes focus outlines so they don't linger after click
   */
  var removeOutlinesOnClick = function(event) {
    event.target.blur();
  };

  /**
   * updates the breadcrumbs and overflow menu
   */
  var _updateBreadcrumbs = function() {
    var maxItems = window.innerWidth > MEDIUM ? 4 : 2;
    if (this.itemCollection.length > maxItems) {
      this.breadcrumb.className += ' is-overflow';
    } else {
      _removeClass.call(this, this.breadcrumb, ' is-overflow');
    }

    _addBreadcrumbItems.call(this, maxItems);
    _addItemsToOverflow.call(this, maxItems);
  };

  /**
   * initializes component
   */
  var init = function() {
    _setListeners.call(this);
    _createItemCollection.call(this);
    _onResize.call(this, null);
  };

  /**
   * Adds a breadcrumb item to a breadcrumb
   * @param itemLabel {String} the item's text label
   * @param itemLink {String} the item's href link
   * @param tabIndex {number} the item's tabIndex
   */
  var addItem = function(itemLabel, itemLink, tabIndex) {
    this.itemCollection.push({text: itemLabel, link: itemLink, tabIndex: tabIndex});
    _updateBreadcrumbs.call(this);
  };

  /**
   * Removes a breadcrumb item by item label in the breadcrumbs list
   * @param itemLabel {String} the item's text label
   */
  var removeItemByLabel = function(itemLabel) {
    var i = this.itemCollection.length;
    while (i--) {
      if (this.itemCollection[i].text === itemLabel) {
        this.itemCollection.splice(i, 1);
      }
    }
    _updateBreadcrumbs.call(this);
  };

  /**
   * removes a breadcrumb item by position in the breadcrumbs list
   * index starts at 0
   * @param itemLabel {String} the item's text label
   * @param itemLink {String} the item's href link
   * @param tabIndex {number} the item's tabIndex
   */
  var removeItemByListPosition = function(value) {
    this.itemCollection.splice(value, 1);
    _updateBreadcrumbs.call(this);
  };

  return {
    init: init,
    addItem: addItem,
    removeItemByLabel: removeItemByLabel,
    removeItemByListPosition: removeItemByListPosition
  };

}());

<|endoftext|>


<commit_before>import React, { Component } from 'react'
import { Input, Button, Form, Upload, Collapse } from 'antd'
import Messages from '../Messages'
import { formatTag } from '../../../utils/format'
import './Dialog.scss'

const { TextArea } = Input
const { Panel } = Collapse

class Dialog extends Component {
  handleTextChange = (e) => {
    const { setText, id } = this.props
    const text = e.target.value
    setText(id, text)
  }

  handleSubmit = (e) => {
    e.preventDefault()
    const { id, fileList, sendFiles, text, sendMessage, setText } = this.props
    if (text) {
      sendMessage(id, text)
      setText(id, '')
    }
    if (fileList.length > 0) {
      const filePaths = fileList.map(x => x.path)
      sendFiles(id, filePaths)
    }
  }

  handleFileRemove = (file) => {
    const { removeFile, id } = this.props
    removeFile(id, file.path)
  }

  handleFileAdd = (file) => {
    const { addFile, id } = this.props
    addFile(id, file.path)

    return false
  }

  render() {
    const { messages, username, fileList, text, info } = this.props
    return (

        {info.name && (
          <Collapse bordered={false}>
            <Panel
              header={`${info.name} (${info.onlineCount + 1}/${info.totalCount + 1})`}
              key="1"
            >

                onlines:{' '}
                {Object.values(info.users)
                  .filter(x => x.online)
                  .map(x => (

                      {x.username}
                      {formatTag(x.tag)}{' '}

                  ))}

            </Panel>
          </Collapse>
        )}
        {info.username && (

            {info.username}
            {formatTag(info.tag)} ({info.host}:{info.port})

        )}
        <Messages messages={messages} username={username} />

{this.props.children}

        <Upload
          multiple
          onRemove={this.handleFileRemove}
          beforeUpload={this.handleFileAdd}
          fileList={fileList}
        >
          <Button shape="circle" icon="paper-clip" />
        </Upload>
        <Form onSubmit={this.handleSubmit}>
          <TextArea
            rows={4}
            value={text}
            onChange={this.handleTextChange}
            styleName="text"
          />

            <Button
              type="primary"
              htmlType="submit"
              disabled={!info.online || (!text && fileList.length <= 0)}
            >
              Send
            </Button>

        </Form>

    )
  }
}

export default Dialog
<commit_msg>dialog: show `me` in online user<commit_after>import React, { Component } from 'react'
import { Input, Button, Form, Upload, Collapse } from 'antd'
import Messages from '../Messages'
import { formatTag } from '../../../utils/format'
import './Dialog.scss'

const { TextArea } = Input
const { Panel } = Collapse

class Dialog extends Component {
  handleTextChange = (e) => {
    const { setText, id } = this.props
    const text = e.target.value
    setText(id, text)
  }

  handleSubmit = (e) => {
    e.preventDefault()
    const { id, fileList, sendFiles, text, sendMessage, setText } = this.props
    if (text) {
      sendMessage(id, text)
      setText(id, '')
    }
    if (fileList.length > 0) {
      const filePaths = fileList.map(x => x.path)
      sendFiles(id, filePaths)
    }
  }

  handleFileRemove = (file) => {
    const { removeFile, id } = this.props
    removeFile(id, file.path)
  }

  handleFileAdd = (file) => {
    const { addFile, id } = this.props
    addFile(id, file.path)

    return false
  }

  render() {
    const { messages, username, fileList, text, info } = this.props
    return (

        {info.name && (
          <Collapse bordered={false}>
            <Panel
              header={`${info.name} (${info.onlineCount + 1}/${info.totalCount + 1})`}
            >

                onlines: {username}[me]{' '}
                {Object.values(info.users)
                  .filter(x => x.online)
                  .map(x => (

                      {x.username}
                      {formatTag(x.tag)}{' '}

                  ))}

            </Panel>
          </Collapse>
        )}
        {info.username && (

            {info.username}
            {formatTag(info.tag)} ({info.host}:{info.port})

        )}
        <Messages messages={messages} username={username} />

{this.props.children}

        <Upload
          multiple
          onRemove={this.handleFileRemove}
          beforeUpload={this.handleFileAdd}
          fileList={fileList}
        >
          <Button shape="circle" icon="paper-clip" />
        </Upload>
        <Form onSubmit={this.handleSubmit}>
          <TextArea
            rows={4}
            value={text}
            onChange={this.handleTextChange}
            styleName="text"
          />

            <Button
              type="primary"
              htmlType="submit"
              disabled={!info.online || (!text && fileList.length <= 0)}
            >
              Send
            </Button>

        </Form>

    )
  }
}

export default Dialog
<|endoftext|>


<commit_before>/**
 * React Starter Kit (https://www.reactstarterkit.com/)
 *
 * Copyright © 2014-2016 Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import React, { PropTypes } from 'react';
import { defineMessages, FormattedMessage } from 'react-intl';
import cx from 'classnames';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Navigation.css';
import Link from '../Link';

const messages = defineMessages({
  about: {
    id: 'navigation.about',
    defaultMessage: 'About',
    description: 'About link in header',
  },
  contact: {
    id: 'navigation.contact',
    defaultMessage: 'Contact',
    description: 'Contact link in header',
  },
  login: {
    id: 'navigation.login',
    defaultMessage: 'Log in',
    description: 'Log in link in header',
  },
  or: {
    id: 'navigation.separator.or',
    defaultMessage: 'or',
    description: 'Last separator in list, lowercase "or"',
  },
  signup: {
    id: 'navigation.signup',
    defaultMessage: 'Sign up',
    description: 'Sign up link in header',
  },
});

function Navigation({ className }) {
  return (

      <Link className={s.link} to="/about">
        <FormattedMessage {...messages.about} />
      </Link>
      <Link className={s.link} to="/contact">
        <FormattedMessage {...messages.contact} />
      </Link>
       |
      <Link className={s.link} to="/login">
        <FormattedMessage {...messages.login} />
      </Link>

        <FormattedMessage {...messages.or} />

      <Link className={cx(s.link, s.highlight)} to="/register">
        <FormattedMessage {...messages.signup} />
      </Link>

  );
}

Navigation.propTypes = {
  className: PropTypes.string,
};

export default withStyles(s)(Navigation);
<commit_msg>inserting login component<commit_after>/**
 * React Starter Kit (https://www.reactstarterkit.com/)
 *
 * Copyright © 2014-2016 Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import React, { PropTypes } from 'react';
import { defineMessages, FormattedMessage } from 'react-intl';
import cx from 'classnames';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Navigation.css';
import Link from '../Link';
import Login from '../Login';

const messages = defineMessages({
  about: {
    id: 'navigation.about',
    defaultMessage: 'About',
    description: 'About link in header',
  },
  contact: {
    id: 'navigation.contact',
    defaultMessage: 'Contact',
    description: 'Contact link in header',
  },
  login: {
    id: 'navigation.login',
    defaultMessage: 'Log in',
    description: 'Log in link in header',
  },
  or: {
    id: 'navigation.separator.or',
    defaultMessage: 'or',
    description: 'Last separator in list, lowercase "or"',
  },
  signup: {
    id: 'navigation.signup',
    defaultMessage: 'Sign up',
    description: 'Sign up link in header',
  },
});

function Navigation({ className }) {
  return (

      <Link className={s.link} to="/about">
        <FormattedMessage {...messages.about} />
      </Link>
      <Link className={s.link} to="/contact">
        <FormattedMessage {...messages.contact} />
      </Link>
       |
      <Link className={s.link} to="/login">
        <FormattedMessage {...messages.login} />
      </Link>

        <FormattedMessage {...messages.or} />

      <Link className={cx(s.link, s.highlight)} to="/register">
        <FormattedMessage {...messages.signup} />
      </Link>
        <Login/>

  );
}

Navigation.propTypes = {
  className: PropTypes.string,
};

export default withStyles(s)(Navigation);
<|endoftext|>


<commit_before>import './SectionTable.less';
import React from 'react';
import PropTypes from 'prop-types';
import { TABLE_CELL_TYPE, DEFAULT_MAX_LENGTH } from '../../constants/Constants';
import { isEmpty, isString, isArray, truncate, isObjectLike, map } from 'lodash';
import WidgetEmptyState from './WidgetEmptyState';
import SectionTitle from './SectionTitle';

const SectionTable = ({ columns, columnsMetaData, readableHeaders, data, classes, style, title, titleStyle, emptyString,
  maxColumns, forceRangeMessage, headerStyle }) => {
  let tableData = data || [];

  if (isString(data)) {
    try {
      tableData = JSON.parse(data);
    } catch (ignored) {
      return
Error parsing table
;
    }
  }

  if (!isArray(tableData) && isObjectLike(tableData)) {
    tableData = tableData.data || tableData.iocs || tableData.messages || [];
  }

  let readyColumns = columns;
  if (isEmpty(columns) && isArray(tableData)) {
    const headerKeys = {};
    tableData.forEach((val, i) => {
      for (const key in tableData[i]) { // eslint-disable-line no-restricted-syntax
        if (headerKeys[key] !== key) {
          headerKeys[key] = key;
        }
      }
    });

    readyColumns = Object.keys(headerKeys);
  }

  const columnsMetaDataMap = new Map();
  if (columnsMetaData && isArray(columnsMetaData)) {
    columnsMetaData.forEach(mData => columnsMetaDataMap.set(mData.key, mData));
  }

  let tableBody;
  if (isArray(readyColumns)) {
    readyColumns = maxColumns > 0 ? readyColumns.slice(0, maxColumns) : readyColumns;
    tableBody = tableData.length > 0 ? (

            {readyColumns.map((col) => {
              const key = col.key || col;
              const extraProps = {};
              const metaData = columnsMetaDataMap.get(key);

              if (metaData) {
                extraProps.width = metaData.width;
              }

              if (headerStyle) {
                extraProps.style = headerStyle;
              }

              return (

                  {!col.hidden && ((readableHeaders && readableHeaders[key]) || key)}

              );
            })}

          {tableData.map((row, i) =>

              {readyColumns.map((col, j) =>
                (() => {
                  const key = col.key || col;
                  const cell = row[key] || (readableHeaders && row[readableHeaders[key]]);

                  let cellToRender = '';
                  if (cell) {
                    switch (cell.type) {
                      case TABLE_CELL_TYPE.image:
                        cellToRender = (

                        );
                        break;
                      default:
                        cellToRender = truncate(cell, { length: DEFAULT_MAX_LENGTH });
                    }
                  }
                  return (

                      {cellToRender}

                  );
                })()
              )}

)
          }

    ) : (

              {readyColumns.map((col) => {
              const key = col.key || col;
                return (

                    {!col.hidden && ((readableHeaders && readableHeaders[key]) || key)}

                );
            })}

        <WidgetEmptyState emptyString={emptyString} />

);
  } else {
    tableBody = (

          {map(tableData, (val, key) => (

                {key}

              {truncate(val, { length: DEFAULT_MAX_LENGTH })}

          ))}

    );
  }

  return (

      <SectionTitle title={title} titleStyle={titleStyle} subTitle={forceRangeMessage} />
      {tableBody}

  );
};
SectionTable.propTypes = {
  columns: PropTypes.array,
  columnsMetaData: PropTypes.array,
  readableHeaders: PropTypes.object,
  data: PropTypes.oneOfType([
    PropTypes.array,
    PropTypes.object,
    PropTypes.string
  ]),
  classes: PropTypes.string,
  style: PropTypes.object,
  title: PropTypes.string,
  maxColumns: PropTypes.number,
  titleStyle: PropTypes.object,
  emptyString: PropTypes.string,
  forceRangeMessage: PropTypes.string,
  headerStyle: PropTypes.object
};

export default SectionTable;
<commit_msg>keep table columns size from the web client<commit_after>import './SectionTable.less';
import React from 'react';
import PropTypes from 'prop-types';
import { TABLE_CELL_TYPE, DEFAULT_MAX_LENGTH } from '../../constants/Constants';
import { isEmpty, isString, isArray, truncate, isObjectLike, map } from 'lodash';
import WidgetEmptyState from './WidgetEmptyState';
import SectionTitle from './SectionTitle';

const SectionTable = ({ columns, readableHeaders, data, classes, style, title, titleStyle, emptyString,
  maxColumns, forceRangeMessage, headerStyle }) => {
  let tableData = data || [];

  if (isString(data)) {
    try {
      tableData = JSON.parse(data);
    } catch (ignored) {
      return
Error parsing table
;
    }
  }

  if (!isArray(tableData) && isObjectLike(tableData)) {
    tableData = tableData.data || tableData.iocs || tableData.messages || [];
  }

  let readyColumns = columns;
  if (isEmpty(columns) && isArray(tableData)) {
    const headerKeys = {};
    tableData.forEach((val, i) => {
      for (const key in tableData[i]) { // eslint-disable-line no-restricted-syntax
        if (headerKeys[key] !== key) {
          headerKeys[key] = key;
        }
      }
    });

    readyColumns = Object.keys(headerKeys);
  }

  const columnsMetaDataMap = new Map();
  if (columns && isArray(columns)) {
    columns.forEach(mData => columnsMetaDataMap.set(mData.key, mData));
  }

  let tableBody;
  if (isArray(readyColumns)) {
    readyColumns = maxColumns > 0 ? readyColumns.slice(0, maxColumns) : readyColumns;
    tableBody = tableData.length > 0 ? (

            {readyColumns.map((col) => {
              const key = col.key || col;
              const extraProps = {};
              const metaData = columnsMetaDataMap.get(key);

              if (metaData) {
                extraProps.width = metaData.width;
              }

              if (headerStyle) {
                extraProps.style = headerStyle;
              }

              return (

                  {!col.hidden && ((readableHeaders && readableHeaders[key]) || key)}

              );
            })}

          {tableData.map((row, i) =>

              {readyColumns.map((col, j) =>
                (() => {
                  const key = col.key || col;
                  const cell = row[key] || (readableHeaders && row[readableHeaders[key]]);

                  let cellToRender = '';
                  if (cell) {
                    switch (cell.type) {
                      case TABLE_CELL_TYPE.image:
                        cellToRender = (

                        );
                        break;
                      default:
                        cellToRender = truncate(cell, { length: DEFAULT_MAX_LENGTH });
                    }
                  }
                  return (

                      {cellToRender}

                  );
                })()
              )}

)
          }

    ) : (

              {readyColumns.map((col) => {
              const key = col.key || col;
                return (

                    {!col.hidden && ((readableHeaders && readableHeaders[key]) || key)}

                );
            })}

        <WidgetEmptyState emptyString={emptyString} />

);
  } else {
    tableBody = (

          {map(tableData, (val, key) => (

                {key}

              {truncate(val, { length: DEFAULT_MAX_LENGTH })}

          ))}

    );
  }

  return (

      <SectionTitle title={title} titleStyle={titleStyle} subTitle={forceRangeMessage} />
      {tableBody}

  );
};
SectionTable.propTypes = {
  columns: PropTypes.array,
  columnsMetaData: PropTypes.array,
  readableHeaders: PropTypes.object,
  data: PropTypes.oneOfType([
    PropTypes.array,
    PropTypes.object,
    PropTypes.string
  ]),
  classes: PropTypes.string,
  style: PropTypes.object,
  title: PropTypes.string,
  maxColumns: PropTypes.number,
  titleStyle: PropTypes.object,
  emptyString: PropTypes.string,
  forceRangeMessage: PropTypes.string,
  headerStyle: PropTypes.object
};

export default SectionTable;
<|endoftext|>


<commit_before>import { addKeyObject, removeKeyObject } from '../interface/KeyComponent'
import { getWordFromSelection } from './SelectionUtil'
import { emojiRegex, userRegex } from '../completers/Completer'

const methods = {}

export let range = null
const inputObjects = []
let hasListeners = false

function getPositionFromSelection() {
  range = window.getSelection().getRangeAt(0)
  const pos = range.getBoundingClientRect()
  // TODO: magic number of -60 should be tested
  // in multiple browsers, this works for safari
  return { left: Math.round(pos.left), top: Math.round(pos.top) }
}

function getActiveTextTools() {
  if (!range) return {}
  const contents = range.cloneContents()
  const parentNode = range.commonAncestorContainer.parentNode
  const tagName = parentNode.nodeName.toLowerCase()
  return {
    isLinkActive: tagName === 'a' || contents.querySelectorAll('a').length > 0,
    isBoldActive: document.queryCommandEnabled('bold') && document.queryCommandState('bold'),
    isItalicActive: document.queryCommandEnabled('italic') && document.queryCommandState('italic'),
  }
}

function callMethod(method, vo) {
  for (const obj of inputObjects) {
    if (obj[method]) {
      obj[method](vo)
    }
  }
}

function toggleTools(input) {
  const word = input.trim()
  if (word && word.length) {
    callMethod('onPositionChange', { coordinates: getPositionFromSelection() })
    callMethod('onShowTextTools', { activeTools: getActiveTextTools() })
  } else {
    callMethod('onHideTextTools', { activeTools: null })
  }
}

function onKeyUp(e) {
  // Handles text tools show/hide and position
  if (!e.target.classList || !e.target.classList.contains('text')) return false
  toggleTools(window.getSelection().toString())
  // Handles autocompletion stuff
  // check for autocompletable strings: currently usernames and emoji codes
  switch (e.which) {
    case 9: // tab
    case 13: // enter
    case 27: // esc
    case 38: // up
    case 40: // down
      return false
    default:
      break
  }
  const word = getWordFromSelection()
  // now do something for the auto completers
  if (word.match(userRegex)) {
    callMethod('onUserCompleter', { word })
  } else if (word.match(emojiRegex)) {
    callMethod('onEmojiCompleter', { word })
  } else {
    callMethod('onHideCompleter')
  }
}
methods.onKeyUp = (e) =>
  onKeyUp(e)

function onKeyDown(e) {
  if (!e.target.classList || !e.target.classList.contains('text')) return false
  // b or i for key commands
  if ((e.keyCode === 66 || e.keyCode === 73) && (e.metaKey || e.ctrlKey)) {
    requestAnimationFrame(() => {
      callMethod('onShowTextTools', { activeTools: getActiveTextTools() })
    })
  }
  if ((e.metaKey || e.ctrlKey) && e.keyCode === 13) {
    callMethod('onSubmitPost')
  }
}
methods.onKeyDown = (e) =>
  onKeyDown(e)

function onClick(e) {
  callMethod('onHideCompleter')
  const classList = e.target.classList
  if (classList.contains('text')) {
    requestAnimationFrame(() => {
      onKeyUp(e)
    })
  } else if (!classList.contains('TextToolButton') &&
      !classList.contains('TextToolForm') &&
      !classList.contains('TextToolLinkInput')) {
    callMethod('onHideTextTools', { activeTools: null })
  }
}

function addListeners() {
  document.addEventListener('click', onClick)
  addKeyObject(methods)
}

function removeListeners() {
  document.removeEventListener('click', onClick)
  removeKeyObject(methods)
}

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

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

<commit_msg>Adds br tags instead of divs.<commit_after>import { addKeyObject, removeKeyObject } from '../interface/KeyComponent'
import { getWordFromSelection } from './SelectionUtil'
import { emojiRegex, userRegex } from '../completers/Completer'

const methods = {}

export let range = null
const inputObjects = []
let hasListeners = false

function getPositionFromSelection() {
  range = window.getSelection().getRangeAt(0)
  const pos = range.getBoundingClientRect()
  // TODO: magic number of -60 should be tested
  // in multiple browsers, this works for safari
  return { left: Math.round(pos.left), top: Math.round(pos.top) }
}

function getActiveTextTools() {
  if (!range) return {}
  const contents = range.cloneContents()
  const parentNode = range.commonAncestorContainer.parentNode
  const tagName = parentNode.nodeName.toLowerCase()
  return {
    isLinkActive: tagName === 'a' || contents.querySelectorAll('a').length > 0,
    isBoldActive: document.queryCommandEnabled('bold') && document.queryCommandState('bold'),
    isItalicActive: document.queryCommandEnabled('italic') && document.queryCommandState('italic'),
  }
}

function callMethod(method, vo) {
  for (const obj of inputObjects) {
    if (obj[method]) {
      obj[method](vo)
    }
  }
}

function toggleTools(input) {
  const word = input.trim()
  if (word && word.length) {
    callMethod('onPositionChange', { coordinates: getPositionFromSelection() })
    callMethod('onShowTextTools', { activeTools: getActiveTextTools() })
  } else {
    callMethod('onHideTextTools', { activeTools: null })
  }
}

function onKeyUp(e) {
  // Handles text tools show/hide and position
  if (!e.target.classList || !e.target.classList.contains('text')) return false
  toggleTools(window.getSelection().toString())
  // Handles autocompletion stuff
  // check for autocompletable strings: currently usernames and emoji codes
  switch (e.which) {
    case 9: // tab
    case 13: // enter
    case 27: // esc
    case 38: // up
    case 40: // down
      return false
    default:
      break
  }
  const word = getWordFromSelection()
  // now do something for the auto completers
  if (word.match(userRegex)) {
    callMethod('onUserCompleter', { word })
  } else if (word.match(emojiRegex)) {
    callMethod('onEmojiCompleter', { word })
  } else {
    callMethod('onHideCompleter')
  }
}
methods.onKeyUp = (e) =>
  onKeyUp(e)

function onKeyDown(e) {
  if (!e.target.classList || !e.target.classList.contains('text')) return false
  // b or i for key commands
  if ((e.keyCode === 66 || e.keyCode === 73) && (e.metaKey || e.ctrlKey)) {
    requestAnimationFrame(() => {
      callMethod('onShowTextTools', { activeTools: getActiveTextTools() })
    })
  }
  if ((e.metaKey || e.ctrlKey) && e.keyCode === 13) {
    callMethod('onSubmitPost')
  }
  // adding br tags while completing causes all of the text to disappear
  const completerActive = document.body.querySelector('.Completion.active')
  if (e.keyCode === 13 && !completerActive) {
    e.preventDefault() // Prevent DIVs from being created
    document.execCommand('insertHTML', false, '

')
  }
}
methods.onKeyDown = (e) =>
  onKeyDown(e)

function onClick(e) {
  callMethod('onHideCompleter')
  const classList = e.target.classList
  if (classList.contains('text')) {
    requestAnimationFrame(() => {
      onKeyUp(e)
    })
  } else if (!classList.contains('TextToolButton') &&
      !classList.contains('TextToolForm') &&
      !classList.contains('TextToolLinkInput')) {
    callMethod('onHideTextTools', { activeTools: null })
  }
}

function addListeners() {
  document.addEventListener('click', onClick)
  addKeyObject(methods)
}

function removeListeners() {
  document.removeEventListener('click', onClick)
  removeKeyObject(methods)
}

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

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

<|endoftext|>


<commit_before>import idMixin from '../../mixins/id'
import formMixin from '../../mixins/form'
import formSizeMixin from '../../mixins/form-size'
import formStateMixin from '../../mixins/form-state'
import { arrayIncludes } from '../../utils/array'

// Import styles
import './form-input.css'

// Valid supported input types
const TYPES = [
  'text',
  'password',
  'email',
  'number',
  'url',
  'tel',
  'search',
  'range',
  'color',
  `date`,
  `time`,
  `datetime`,
  `datetime-local`,
  `month`,
  `week`
]

export default {
  mixins: [idMixin, formMixin, formSizeMixin, formStateMixin],
  render (h) {
    return h('input', {
      ref: 'input',
      class: this.inputClass,
      domProps: { value: this.localValue },
      attrs: {
        id: this.safeId(),
        name: this.name,
        type: this.localType,
        disabled: this.disabled,
        required: this.required,
        readonly: this.readonly || this.plaintext,
        placeholder: this.placeholder,
        autocomplete: this.autocomplete || null,
        'aria-required': this.required ? 'true' : null,
        'aria-invalid': this.computedAriaInvalid
      },
      on: {
        input: this.onInput,
        change: this.onChange
      }
    })
  },
  data () {
    return {
      localValue: this.value
    }
  },
  props: {
    value: {
      default: null
    },
    type: {
      type: String,
      default: 'text',
      validator: type => arrayIncludes(TYPES, type)
    },
    ariaInvalid: {
      type: [Boolean, String],
      default: false
    },
    readonly: {
      type: Boolean,
      default: false
    },
    plaintext: {
      type: Boolean,
      default: false
    },
    autocomplete: {
      type: String,
      default: null
    },
    placeholder: {
      type: String,
      default: null
    },
    formatter: {
      type: Function
    },
    lazyFormatter: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    localType () {
      // We only allow certain types
      return arrayIncludes(TYPES, this.type) ? this.type : 'text'
    },
    inputClass () {
      return [
        this.plaintext ? 'form-control-plaintext' : 'form-control',
        this.sizeFormClass,
        this.stateClass
      ]
    },
    computedAriaInvalid () {
      if (!this.ariaInvalid || this.ariaInvalid === 'false') {
        // this.ariaInvalid is null or false or 'false'
        return this.computedState === false ? 'true' : null
      }
      if (this.ariaInvalid === true) {
        // User wants explicit aria-invalid=true
        return 'true'
      }
      // Most likely a string value (which could be 'true')
      return this.ariaInvalid
    }
  },
  watch: {
    value (newVal, oldVal) {
      if (newVal !== oldVal) {
        this.localValue = newVal
      }
    },
    localValue (newVal, oldVal) {
      if (newVal !== oldVal) {
        this.$emit('input', newVal)
      }
    }
  },
  methods: {
    format (value, e) {
      if (this.formatter) {
          return this.formatter(value, e)
      }
      return value
    },
    onInput (evt) {
      const value = evt.target.value
      if (this.lazyFormatter) {
        // Update the model with the current unformated value
        this.localValue = value
      } else {
        this.localValue = this.format(value, evt)
      }
    },
    onChange (evt) {
      this.localValue = this.format(evt.target.value, evt)
      this.$emit('change', this.localValue)
    },
    focus () {
      if (!this.disabled) {
        this.$el.focus()
      }
    }
  }
}
<commit_msg>fix(form-input): force update formatted value (#1845)<commit_after>import idMixin from '../../mixins/id'
import formMixin from '../../mixins/form'
import formSizeMixin from '../../mixins/form-size'
import formStateMixin from '../../mixins/form-state'
import { arrayIncludes } from '../../utils/array'

// Import styles
import './form-input.css'

// Valid supported input types
const TYPES = [
  'text',
  'password',
  'email',
  'number',
  'url',
  'tel',
  'search',
  'range',
  'color',
  `date`,
  `time`,
  `datetime`,
  `datetime-local`,
  `month`,
  `week`
]

export default {
  mixins: [idMixin, formMixin, formSizeMixin, formStateMixin],
  render (h) {
    return h('input', {
      ref: 'input',
      class: this.inputClass,
      attrs: {
        id: this.safeId(),
        name: this.name,
        type: this.localType,
        disabled: this.disabled,
        required: this.required,
        readonly: this.readonly || this.plaintext,
        placeholder: this.placeholder,
        autocomplete: this.autocomplete || null,
        'aria-required': this.required ? 'true' : null,
        'aria-invalid': this.computedAriaInvalid,
        value: this.value
      },
      on: {
        input: this.onInput,
        change: this.onChange
      }
    })
  },
  props: {
    value: {
      default: null
    },
    type: {
      type: String,
      default: 'text',
      validator: type => arrayIncludes(TYPES, type)
    },
    ariaInvalid: {
      type: [Boolean, String],
      default: false
    },
    readonly: {
      type: Boolean,
      default: false
    },
    plaintext: {
      type: Boolean,
      default: false
    },
    autocomplete: {
      type: String,
      default: null
    },
    placeholder: {
      type: String,
      default: null
    },
    formatter: {
      type: Function
    },
    lazyFormatter: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    localType () {
      // We only allow certain types
      return arrayIncludes(TYPES, this.type) ? this.type : 'text'
    },
    inputClass () {
      return [
        this.plaintext ? 'form-control-plaintext' : 'form-control',
        this.sizeFormClass,
        this.stateClass
      ]
    },
    computedAriaInvalid () {
      if (!this.ariaInvalid || this.ariaInvalid === 'false') {
        // this.ariaInvalid is null or false or 'false'
        return this.computedState === false ? 'true' : null
      }
      if (this.ariaInvalid === true) {
        // User wants explicit aria-invalid=true
        return 'true'
      }
      // Most likely a string value (which could be 'true')
      return this.ariaInvalid
    }
  },
  mounted () {
    if (this.value) {
      const fValue = this.format(this.value, null)
      this.setValue(fValue)
    }
  },
  watch: {
    value (newVal) {
      if (this.lazyFormatter) {
        this.setValue(newVal)
      } else {
        const fValue = this.format(newVal, null)
        this.setValue(fValue)
      }
    }
  },
  methods: {
    format (value, e) {
      if (this.formatter) {
        return this.formatter(value, e)
      }
      return value
    },
    setValue (value) {
      this.$emit('input', value)
      // When formatter removes last typed character, value of text input should update to formatted value
      this.$refs.input.value = value
    },
    onInput (evt) {
      const value = evt.target.value

      if (this.lazyFormatter) {
        this.setValue(value)
      } else {
        const fValue = this.format(value, evt)
        this.setValue(fValue)
      }
    },
    onChange (evt) {
      const fValue = this.format(evt.target.value, evt)
      this.setValue(fValue)
      this.$emit('change', fValue)
    },
    focus () {
      if (!this.disabled) {
        this.$el.focus()
      }
    }
  }
}
<|endoftext|>


<commit_before>// dependencies
//
import React from 'react';

const RadioButtonGroup = ({ label, options }) => (

        {label ? ({label}) : null}
        {options.map((opt) =>

)}

);

export default RadioButtonGroup;
<commit_msg>updated dependencies<commit_after>// dependencies
//
import React from 'react';
import uniqueId from 'lodash/uniqueId';

const RadioButtonGroup = ({ label, options }) => (

        {label ? ({label}) : null}
        {options.map((opt) =>

)}

);

export default RadioButtonGroup;
<|endoftext|>