<commit_before>/**
 * Amata.js - List multi-selection multi-action form multi-task executer
 *
 * @link    https://github.com/textpattern/amata
 * @license MIT
 */

/*
 * Copyright (C) 2013 The Textpattern Development Team
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @name jQuery
 * @class
 */

/**
 * @name fn
 * @class
 * @memberOf jQuery
 */

(function (factory)
{
    'use strict';

    if (typeof define === 'function' && define.amd)
    {
        define(['jquery'], factory);
    }
    else
    {
        factory(window.jQuery || window.Zepto);
    }
}(function ($)
{
    'use strict';

    /**
     * Methods.
     *
     * @var {Object}
     */

    var methods = {};

    /**
     * Initializes the multi-editor.
     *
     * @param {Object} [options={}] Options
     */

    methods.init = function (options)
    {
        options = $.extend({
            'selectAll'     : '[name=amata-select-all]',
            'button'        : '[type=submit]',
            'boxes'         : '[name="selected[]"]',
            'highlighted'   : 'tr',
            'selectedClass' : 'highlighted',
            'clickRegion'   : 'table tbody tr td'
        }, options);

        this.closest('form').not('.amata-ready').each(function ()
        {
            var $this = $(this), button = $this.find(options.button).hide(), actions = $(this).find('select.amata-actions').val(''), selectAll = $(options.selectAll), lastCheck = false;

            methods.registerOptions.call($this);

            selectAll.on('change', function ()
            {
                $(options.boxes).prop('checked', $(this).prop('checked')).change();
            });

            $this.on('click.amata', options.clickRegion, function (e)
            {
                var row = $(this), self = ($(e.target).is(options.boxes) || row.is(options.boxes)), box, checked;

                if (!self)
                {
                    // Clicking the row, but without holding CTRL/ALT.

                    if (!e.altKey && !e.ctrlKey)
                    {
                        return;
                    }

                    // Skip actions invoked from clicking links and inputs.

                    if (e.target !== this || row.is('a, :input') || $(e.target).is('a, :input'))
                    {
                        return;
                    }
                }

                box = row.closest(options.highlighted).find(options.boxes).eq(0);

                if (!box.length)
                {
                    return;
                }

                checked = box.prop('checked');

                if (self)
                {
                    checked = !checked;
                }

                if (e.shiftKey && lastCheck)
                {
                    var boxes = $this.find(options.boxes), start = boxes.index(box), end = boxes.index(lastCheck);

                    boxes
                        .slice(Math.min(start, end), Math.max(start, end) + 1)
                        .prop('checked', !checked)
                        .change();
                }
                else if (!self)
                {
                    box.prop('checked', !checked).change();
                }

                if (checked === false)
                {
                    lastCheck = box;
                }
                else
                {
                    lastCheck = null;
                }
            });

            $this.on('change.amata', options.boxes, function ()
            {
                var box = $(this), boxes = $(options.boxes);

                if (box.prop('checked'))
                {
                    box.closest(options.highlighted).addClass(options.selectedClass);
                    selectAll.prop('checked', boxes.filter(':checked').length === boxes.length);
                }
                else
                {
                    box.closest(options.highlighted).removeClass(options.selectedClass);
                    selectAll.prop('checked', false);
                }
            });

            actions.on('change.amata', function ()
            {
                var selected = $(this).find('option').filter(function ()
                {
                    return $(this).prop('selected');
                }).eq(0);

                $this.trigger('amata-action-change.amata').find('.amata-active-step').remove();

                if (!selected.val())
                {
                    button.hide();
                    return;
                }

                if (selected.data('amata-method'))
                {
                    $(this).after($('<div />').attr('class', 'amata-active-step').html(selected.data('amata-method')));
                    button.show();
                }
                else
                {
                    button.hide();
                    $this.trigger('submit.amata');
                }
            });

            $this.addClass('.amata-ready');
        });

        return this;
    };

    /**
     * Adds a multi-edit option.
     *
     * @param  {object} options
     * @param  {string} options.label The option's label
     * @param  {string} options.value The option's value
     * @param  {string} options.html  The second step HTML
     * @return {object} this
     * @example
     * $('form').amata('addOption', {
     *  'label' : 'Delete',
     *  'value' : 'delete'
     * });
     */

    methods.addOption = function (options)
    {
        options = $.extend({
            'label' : null,
            'value' : null,
            'html'  : null
        }, options);

        var $this = this.closest('form').find('.amata-actions').eq(0).val(''), exists = false;

        if (!options.value || !$this.length)
        {
            return this;
        }

        var option = $this.find('option').filter(function ()
        {
            return $(this).val() === options.value;
        }).eq(0);

        exists = (option.length !== 0);

        if (!exists)
        {
            option = $('<option />');
        }

        if (!exists || !option.data('amata-method'))
        {
            if (!option.val())
            {
                option.val(options.value);
            }

            if (!option.text() && options.label)
            {
                option.text(options.label);
            }

            option.data('amata-method', options.html);

            if (!exists)
            {
                $this.append(option);
            }
        }

        return this;
    };

    /**
     * Registers multi-edit options from the document.
     *
     * @return   {Object} this
     * @method   registerOptions
     * @memberof jQuery.fn.amata
     */

    methods.registerOptions = function ()
    {
        return this.each(function ()
        {
            var $this = $(this), multiOptions = $this.find('[data-amata-option]');

            $this.find('select.amata-actions option').each(function ()
            {
                var value = $(this).val();

                if (value)
                {
                    var option = multiOptions.filter(function ()
                    {
                        return $(this).attr('data-amata-option') === value;
                    });

                    if (option.length > 0)
                    {
                        methods.addOption.call($this, {
                            'label' : null,
                            'html'  : option.eq(0).html(),
                            'value' : $(this).val()
                        });
                    }
                }
            });

            multiOptions.remove();
        });
    };

    /**
     * Multi-edit functions.
     *
     * @param    {String|Object} [method=init] Called method
     * @param    {Object}        [options={}]  Options passed to the method
     * @class    amata
     * @memberof jQuery.fn
     */

    $.fn.amata = function (method, options)
    {
        if ($.type(method) !== 'string' || $.type(methods[method]) !== 'function')
        {
            options = method;
            method = 'init';
        }

        return methods[method].call(this, options);
    };
}));<commit_msg>Non-standard selector.<commit_after>/**
 * Amata.js - List multi-selection multi-action form multi-task executer
 *
 * @link    https://github.com/textpattern/amata
 * @license MIT
 */

/*
 * Copyright (C) 2013 The Textpattern Development Team
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @name jQuery
 * @class
 */

/**
 * @name fn
 * @class
 * @memberOf jQuery
 */

(function (factory)
{
    'use strict';

    if (typeof define === 'function' && define.amd)
    {
        define(['jquery'], factory);
    }
    else
    {
        factory(window.jQuery || window.Zepto);
    }
}(function ($)
{
    'use strict';

    /**
     * Methods.
     *
     * @var {Object}
     */

    var methods = {}, inputs = 'a, input, textarea, select, button';

    /**
     * Initializes the multi-editor.
     *
     * @param {Object} [options={}] Options
     */

    methods.init = function (options)
    {
        options = $.extend({
            'selectAll'     : '[name=amata-select-all]',
            'button'        : '[type=submit]',
            'boxes'         : '[name="selected[]"]',
            'highlighted'   : 'tr',
            'selectedClass' : 'highlighted',
            'clickRegion'   : 'table tbody tr td'
        }, options);

        this.closest('form').not('.amata-ready').each(function ()
        {
            var $this = $(this), button = $this.find(options.button).hide(), actions = $(this).find('select.amata-actions').val(''), selectAll = $(options.selectAll), lastCheck = false;

            methods.registerOptions.call($this);

            selectAll.on('change', function ()
            {
                $(options.boxes).prop('checked', $(this).prop('checked')).change();
            });

            $this.on('click.amata', options.clickRegion, function (e)
            {
                var row = $(this), self = ($(e.target).is(options.boxes) || row.is(options.boxes)), box, checked;

                if (!self)
                {
                    // Clicking the row, but without holding CTRL/ALT.

                    if (!e.altKey && !e.ctrlKey)
                    {
                        return;
                    }

                    // Skip actions invoked from clicking links and inputs.

                    if (e.target !== this || row.is(inputs) || $(e.target).is(inputs))
                    {
                        return;
                    }
                }

                box = row.closest(options.highlighted).find(options.boxes).eq(0);

                if (!box.length)
                {
                    return;
                }

                checked = box.prop('checked');

                if (self)
                {
                    checked = !checked;
                }

                if (e.shiftKey && lastCheck)
                {
                    var boxes = $this.find(options.boxes), start = boxes.index(box), end = boxes.index(lastCheck);

                    boxes
                        .slice(Math.min(start, end), Math.max(start, end) + 1)
                        .prop('checked', !checked)
                        .change();
                }
                else if (!self)
                {
                    box.prop('checked', !checked).change();
                }

                if (checked === false)
                {
                    lastCheck = box;
                }
                else
                {
                    lastCheck = null;
                }
            });

            $this.on('change.amata', options.boxes, function ()
            {
                var box = $(this), boxes = $(options.boxes);

                if (box.prop('checked'))
                {
                    box.closest(options.highlighted).addClass(options.selectedClass);
                    selectAll.prop('checked', boxes.filter(':checked').length === boxes.length);
                }
                else
                {
                    box.closest(options.highlighted).removeClass(options.selectedClass);
                    selectAll.prop('checked', false);
                }
            });

            actions.on('change.amata', function ()
            {
                var selected = $(this).find('option').filter(function ()
                {
                    return $(this).prop('selected');
                }).eq(0);

                $this.trigger('amata-action-change.amata').find('.amata-active-step').remove();

                if (!selected.val())
                {
                    button.hide();
                    return;
                }

                if (selected.data('amata-method'))
                {
                    $(this).after($('<div />').attr('class', 'amata-active-step').html(selected.data('amata-method')));
                    button.show();
                }
                else
                {
                    button.hide();
                    $this.trigger('submit.amata');
                }
            });

            $this.addClass('.amata-ready');
        });

        return this;
    };

    /**
     * Adds a multi-edit option.
     *
     * @param  {object} options
     * @param  {string} options.label The option's label
     * @param  {string} options.value The option's value
     * @param  {string} options.html  The second step HTML
     * @return {object} this
     * @example
     * $('form').amata('addOption', {
     *  'label' : 'Delete',
     *  'value' : 'delete'
     * });
     */

    methods.addOption = function (options)
    {
        options = $.extend({
            'label' : null,
            'value' : null,
            'html'  : null
        }, options);

        var $this = this.closest('form').find('.amata-actions').eq(0).val(''), exists = false;

        if (!options.value || !$this.length)
        {
            return this;
        }

        var option = $this.find('option').filter(function ()
        {
            return $(this).val() === options.value;
        }).eq(0);

        exists = (option.length !== 0);

        if (!exists)
        {
            option = $('<option />');
        }

        if (!exists || !option.data('amata-method'))
        {
            if (!option.val())
            {
                option.val(options.value);
            }

            if (!option.text() && options.label)
            {
                option.text(options.label);
            }

            option.data('amata-method', options.html);

            if (!exists)
            {
                $this.append(option);
            }
        }

        return this;
    };

    /**
     * Registers multi-edit options from the document.
     *
     * @return   {Object} this
     * @method   registerOptions
     * @memberof jQuery.fn.amata
     */

    methods.registerOptions = function ()
    {
        return this.each(function ()
        {
            var $this = $(this), multiOptions = $this.find('[data-amata-option]');

            $this.find('select.amata-actions option').each(function ()
            {
                var value = $(this).val();

                if (value)
                {
                    var option = multiOptions.filter(function ()
                    {
                        return $(this).attr('data-amata-option') === value;
                    });

                    if (option.length > 0)
                    {
                        methods.addOption.call($this, {
                            'label' : null,
                            'html'  : option.eq(0).html(),
                            'value' : $(this).val()
                        });
                    }
                }
            });

            multiOptions.remove();
        });
    };

    /**
     * Multi-edit functions.
     *
     * @param    {String|Object} [method=init] Called method
     * @param    {Object}        [options={}]  Options passed to the method
     * @class    amata
     * @memberof jQuery.fn
     */

    $.fn.amata = function (method, options)
    {
        if ($.type(method) !== 'string' || $.type(methods[method]) !== 'function')
        {
            options = method;
            method = 'init';
        }

        return methods[method].call(this, options);
    };
}));<|endoftext|>


<commit_before>define(function () {

    function OnDataChange (bezl) {
        if (bezl.data.Accounts) {
            bezl.vars.loading = false;

            // If there was a previously selected account in localStorage, grab a reference
            // so we can know whether to mark them as selected
            bezl.vars.selectedAccount = {};
            if (typeof(Storage) !== "undefined" && localStorage.getItem("selectedAccount")) {
                bezl.vars.selectedAccount = JSON.parse(localStorage.getItem("selectedAccount"));
            }

            // Perform additional processing on the returned data
            for (var i = 0; i < bezl.data.Accounts.length; i++) {
                // Add a Selected property to the account record
                if (bezl.data.Accounts[i].ID == bezl.vars.selectedAccount.ID) {
                    bezl.data.Accounts[i].Selected = true;
                } else {
                    bezl.data.Accounts[i].Selected = false;
                }

                // Create an AddressURL column with an encoded version of each Address
                // so that it can be part of a Google Maps AddressURL
                bezl.data.Accounts[i].AddressURL = encodeURI(bezl.data.Accounts[i].Address);

                // Determine the distance from the current location, if applicable
                if (bezl.data.Accounts[i].Geocode_Location) {
                    bezl.data.Accounts[i].Distance = CalcDistance(bezl.vars.currentLat
                                                                , bezl.vars.currentLng
                                                                , parseFloat(bezl.data.Accounts[i].Geocode_Location.split(',')[0].split(':')[1])
                                                                , parseFloat(bezl.data.Accounts[i].Geocode_Location.split(',')[1].split(':')[1]));
                }

                // Set up any of the properties we wish to consolidate additional
                // data into from subsequent queries
                bezl.data.Accounts[i].Contacts = [];
                bezl.data.Accounts[i].CRMCalls = [];
                bezl.data.Accounts[i].Tasks = [];
                bezl.data.Accounts[i].Attachments = [];

            };
        }

        // If we got the account contacts back, merge those in
        if (bezl.data.Accounts && bezl.data.AccountContacts) {
            for (var i = 0; i < bezl.data.AccountContacts.length; i++) {
                for (var x = 0; x < bezl.data.Accounts.length; x++) {
                    if (bezl.data.AccountContacts[i].ID == bezl.data.Accounts[x].ID) {
                        bezl.data.Accounts[x].Contacts.push(bezl.data.AccountContacts[i]);
                    }
                }
            }

            bezl.vars.loadingContacts = false;
        }

        // If we got the account calls back, merge those in
        if (bezl.data.CRMCalls) {
            if (bezl.data.Accounts) {
                for (var x = 0; x < bezl.data.Accounts.length; x++) {
                    for (var i = 0; i < bezl.data.CRMCalls.length; i++) {
                        if (bezl.data.CRMCalls[i].ID == bezl.data.Accounts[x].ID) {
                            bezl.data.Accounts[x].CRMCalls.push(bezl.data.CRMCalls[i]);
                        }
                    }
                }

                bezl.vars.loadingCalls = false;
            }
        }

        // If we got the account tasks back, merge those in
        if (bezl.data.Tasks) {
            if (bezl.data.Accounts) {
                for (var x = 0; x < bezl.data.Accounts.length; x++) {
                    for (var i = 0; i < bezl.data.Tasks.length; i++) {
                        if (bezl.data.Tasks[i].ID == bezl.data.Accounts[x].ID) {
                            bezl.data.Accounts[x].Tasks.push(bezl.data.Tasks[i]);
                        }
                    }
                }

                bezl.vars.loadingTasks = false;
            }
        }

        // If we got the account tasks back, merge those in
        if (bezl.data.Attachments) {
            if (bezl.data.Accounts) {
                for (var x = 0; x < bezl.data.Accounts.length; x++) {
                    for (var i = 0; i < bezl.data.Attachments.length; i++) {
                        if (bezl.data.Attachments[i].ID == bezl.data.Accounts[x].ID) {
                            bezl.data.Accounts[x].Attachments.push(bezl.data.Attachments[i]);
                        }
                    }
                }

                bezl.vars.loadingAttachments = false;
            }
        }
    }

    function CalcDistance(lat1, lon1, lat2, lon2, unit) {
        var radlat1 = Math.PI * lat1/180
        var radlat2 = Math.PI * lat2/180
        var theta = lon1-lon2
        var radtheta = Math.PI * theta/180
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        dist = Math.acos(dist)
        dist = dist * 180/Math.PI
        dist = dist * 60 * 1.1515
        if (unit=="K") { dist = dist * 1.609344 }
        if (unit=="N") { dist = dist * 0.8684 }
        return Math.round(dist)
    }

    return {
        onDataChange: OnDataChange
    }
});<commit_msg>Make all records visible on initial load.<commit_after>define(function () {

    function OnDataChange (bezl) {
        if (bezl.data.Accounts) {
            bezl.vars.loading = false;

            // If there was a previously selected account in localStorage, grab a reference
            // so we can know whether to mark them as selected
            bezl.vars.selectedAccount = {};
            if (typeof(Storage) !== "undefined" && localStorage.getItem("selectedAccount")) {
                bezl.vars.selectedAccount = JSON.parse(localStorage.getItem("selectedAccount"));
            }

            // Perform additional processing on the returned data
            for (var i = 0; i < bezl.data.Accounts.length; i++) {
                // Add a Selected property to the account record
                if (bezl.data.Accounts[i].ID == bezl.vars.selectedAccount.ID) {
                    bezl.data.Accounts[i].Selected = true;
                } else {
                    bezl.data.Accounts[i].Selected = false;
                }

                // Create an AddressURL column with an encoded version of each Address
                // so that it can be part of a Google Maps AddressURL
                bezl.data.Accounts[i].AddressURL = encodeURI(bezl.data.Accounts[i].Address);

                // Determine the distance from the current location, if applicable
                if (bezl.data.Accounts[i].Geocode_Location) {
                    bezl.data.Accounts[i].Distance = CalcDistance(bezl.vars.currentLat
                                                                , bezl.vars.currentLng
                                                                , parseFloat(bezl.data.Accounts[i].Geocode_Location.split(',')[0].split(':')[1])
                                                                , parseFloat(bezl.data.Accounts[i].Geocode_Location.split(',')[1].split(':')[1]));
                }

                // Set up any of the properties we wish to consolidate additional
                // data into from subsequent queries
                bezl.data.Accounts[i].Contacts = [];
                bezl.data.Accounts[i].CRMCalls = [];
                bezl.data.Accounts[i].Tasks = [];
                bezl.data.Accounts[i].Attachments = [];

                // Make all records visible to start off with
                bezl.data.Accounts[i].show = true;
            };
        }

        // If we got the account contacts back, merge those in
        if (bezl.data.Accounts && bezl.data.AccountContacts) {
            for (var i = 0; i < bezl.data.AccountContacts.length; i++) {
                for (var x = 0; x < bezl.data.Accounts.length; x++) {
                    if (bezl.data.AccountContacts[i].ID == bezl.data.Accounts[x].ID) {
                        bezl.data.Accounts[x].Contacts.push(bezl.data.AccountContacts[i]);
                    }
                }
            }

            bezl.vars.loadingContacts = false;
        }

        // If we got the account calls back, merge those in
        if (bezl.data.CRMCalls) {
            if (bezl.data.Accounts) {
                for (var x = 0; x < bezl.data.Accounts.length; x++) {
                    for (var i = 0; i < bezl.data.CRMCalls.length; i++) {
                        if (bezl.data.CRMCalls[i].ID == bezl.data.Accounts[x].ID) {
                            bezl.data.Accounts[x].CRMCalls.push(bezl.data.CRMCalls[i]);
                        }
                    }
                }

                bezl.vars.loadingCalls = false;
            }
        }

        // If we got the account tasks back, merge those in
        if (bezl.data.Tasks) {
            if (bezl.data.Accounts) {
                for (var x = 0; x < bezl.data.Accounts.length; x++) {
                    for (var i = 0; i < bezl.data.Tasks.length; i++) {
                        if (bezl.data.Tasks[i].ID == bezl.data.Accounts[x].ID) {
                            bezl.data.Accounts[x].Tasks.push(bezl.data.Tasks[i]);
                        }
                    }
                }

                bezl.vars.loadingTasks = false;
            }
        }

        // If we got the account tasks back, merge those in
        if (bezl.data.Attachments) {
            if (bezl.data.Accounts) {
                for (var x = 0; x < bezl.data.Accounts.length; x++) {
                    for (var i = 0; i < bezl.data.Attachments.length; i++) {
                        if (bezl.data.Attachments[i].ID == bezl.data.Accounts[x].ID) {
                            bezl.data.Accounts[x].Attachments.push(bezl.data.Attachments[i]);
                        }
                    }
                }

                bezl.vars.loadingAttachments = false;
            }
        }
    }

    function CalcDistance(lat1, lon1, lat2, lon2, unit) {
        var radlat1 = Math.PI * lat1/180
        var radlat2 = Math.PI * lat2/180
        var theta = lon1-lon2
        var radtheta = Math.PI * theta/180
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        dist = Math.acos(dist)
        dist = dist * 180/Math.PI
        dist = dist * 60 * 1.1515
        if (unit=="K") { dist = dist * 1.609344 }
        if (unit=="N") { dist = dist * 0.8684 }
        return Math.round(dist)
    }

    return {
        onDataChange: OnDataChange
    }
});
<|endoftext|>


<commit_before>var ipc = require('electron').ipcMainequire('ipc');

var seen;

function extractData(ss) {
  var id, avatar, sender, subject;

  var p = ss.parentNode.parentNode.parentNode.parentNode.parentNode;
  var a = p.querySelector('[data-action-data]');
  var action = a.dataset.actionData;
  id = /#.+?:([^"]+)/.exec(action)[1];

  subject = (p.querySelector('.lt') || p.querySelector('.qG span')).textContent;

  var brand = ss.getAttribute('brand_name');
  if (brand) {
    sender = brand;
    avatar = ss.getAttribute('brand_avatar_url');
  }
  else {
    sender = p.querySelector('[email]').textContent;
    var img = p.querySelector('img');
    if (img) {
      avatar = img.src;
    }
    else {
      var icon = p.querySelector('.pE');
      var bg = getComputedStyle(icon)['background-image'];
      avatar = bg.replace(/url\((.+)\)/, '$1');
    }
  }

  return {
    id: id,
    subject: subject,
    sender: ss.textContent,
    avatar: avatar
  }
}

function getNew(messages) {
  return messages.filter(function(msg) {
    return !seen[msg.id];
  })
}

function getUnreadMessages() {
  var nodes = Array.prototype.slice.call(document.querySelectorAll('.ss'));
  return nodes.map(extractData);
}

function checkState() {
  var messages = getUnreadMessages();
  var count = messages.length;
  ipc.send('unread', '' + count);

  var firstTime = !seen;
  if (firstTime) seen = {};

  getNew(messages).forEach(function(msg) {
    if (!firstTime) {
      // Don't show notifications upon startup
      new Notification(msg.sender, {
        tag: msg.id,
        body: msg.subject,
        icon: msg.avatar
      });
    }
    seen[msg.id] = true;
  })

  setTimeout(checkState, 1000);
}

checkState();
<commit_msg>fix ipc<commit_after>var electron = require('electron');
var ipc = electron.ipcRenderer;

var seen;

function extractData(ss) {
  var id, avatar, sender, subject;

  var p = ss.parentNode.parentNode.parentNode.parentNode.parentNode;
  var a = p.querySelector('[data-action-data]');
  var action = a.dataset.actionData;
  id = /#.+?:([^"]+)/.exec(action)[1];

  subject = (p.querySelector('.lt') || p.querySelector('.qG span')).textContent;

  var brand = ss.getAttribute('brand_name');
  if (brand) {
    sender = brand;
    avatar = ss.getAttribute('brand_avatar_url');
  }
  else {
    sender = p.querySelector('[email]').textContent;
    var img = p.querySelector('img');
    if (img) {
      avatar = img.src;
    }
    else {
      var icon = p.querySelector('.pE');
      var bg = getComputedStyle(icon)['background-image'];
      avatar = bg.replace(/url\((.+)\)/, '$1');
    }
  }

  return {
    id: id,
    subject: subject,
    sender: ss.textContent,
    avatar: avatar
  }
}

function getNew(messages) {
  return messages.filter(function(msg) {
    return !seen[msg.id];
  })
}

function getUnreadMessages() {
  var nodes = Array.prototype.slice.call(document.querySelectorAll('.ss'));
  return nodes.map(extractData);
}

function checkState() {
  var messages = getUnreadMessages();
  var count = messages.length;
  ipc.send('unread', '' + count);

  var firstTime = !seen;
  if (firstTime) seen = {};

  getNew(messages).forEach(function(msg) {
    if (!firstTime) {
      // Don't show notifications upon startup
      new Notification(msg.sender, {
        tag: msg.id,
        body: msg.subject,
        icon: msg.avatar
      });
    }
    seen[msg.id] = true;
  })

  setTimeout(checkState, 1000);
}

checkState();
<|endoftext|>


<commit_before>define(['./ajax'], function(ajax) {

    ///////////////
   // Webfinger //
  ///////////////

  var options, userAddress, userName, host, templateParts;//this is all a bit messy, but there are a lot of callbacks here, so globals help us with that.
  function getAttributes(ua, setOptions, error, cb){
    options = setOptions;
    userAddress = ua;
    var parts = ua.split('@');
    if(parts.length < 2) {
      error('That is not a user address. There is no @-sign in it');
    } else if(parts.length > 2) {
      error('That is not a user address. There is more than one @-sign in it');
    } else {
      if(!(/^[\.0-9A-Za-z]+$/.test(parts[0]))) {
        error('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');
      } else if(!(/^[\.0-9A-Za-z\-]+$/.test(parts[1]))) {
        error('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');
      } else {
        userName = parts[0];
        host = parts[1];
        //error('So far so good. Looking up https host-meta for '+host);
        ajax.ajax({
          //url: 'https://'+host+'/.well-known/host-meta',
          url: 'http://'+host+'/.well-known/host-meta',
          success: function(data) {
            afterHostmetaSuccess(data, error, cb);
          },
          error: function(data) {
            afterHttpsHostmetaError(data, error, cb);
          },
        })
      }
    }
  }

  function afterHttpsHostmetaError(data, error, cb) {
    if(options.allowHttpWebfinger) {
      console.log('Https Host-meta error. Trying http.');
      ajax.ajax({
        url: 'http://'+host+'/.well-known/host-meta',
        success: function(data) {
          afterHostmetaSuccess(data, error, cb);
        },
        error: function(data) {
          afterHttpHostmetaError(data, error, cb);
        },
      })
    } else {
       afterHttpHostmetaError(data, error, cb);
    }
  }

  function afterHttpHostmetaError(data, error, cb) {
    if(options.allowSingleOriginWebfinger) {
      console.log('Trying single origin webfinger through proxy');
      ajax.ajax({
        url: 'http://useraddress.net/single-origin-webfinger...really?'+userAddress,
        success: function(data) {
          afterLrddSuccess(data, error, cb);
        },
        error: function(data) {
          afterProxyError(data, error, cb);
        }
      });
    } else {
      afterProxyError(data, error, cb);
    }
  }

  function afterProxyError(data, error, cb) {
    if(options.allowFakefinger) {
      console.log('Trying Fakefinger');
      ajax.ajax({
        url: 'http://useraddress.net/fakefinger?userAddress='+userAddress,
        success: function(data) {
          afterLrddSuccess(data, error, cb);
        },
        error: function(data) {
          afterFakefingerError(data, error, cb);
        }
      });
    } else {
      afterFakefingerError(data, error, cb);
    }
  }
  function afterFakefingerError() {
    alert('user address "'+userAddress+'" doesn\'t seem to have remoteStorage linked to it');
  }
  function afterHostmetaSuccess(data, error, cb) {
    data = (new DOMParser()).parseFromString(data, 'text/xml');
    if(!data.getElementsByTagName) {
      error('Host-meta is not an XML document, or doesnt have xml mimetype.');
      return;
    }
    var linkTags = data.getElementsByTagName('Link');
    if(linkTags.length == 0) {
      error('no Link tags found in host-meta');
    } else {
      var lrddFound = false;
      var errorStr = 'none of the Link tags have a lrdd rel-attribute';
      for(var linkTagI = 0; linkTagI < linkTags.length; linkTagI++) {
        for(var attrI = 0; attrI < linkTags[linkTagI].attributes.length; attrI++) {
          var attr = linkTags[linkTagI].attributes[attrI];
          if((attr.name=='rel') && (attr.value=='lrdd')) {
            lrddFound = true;
            errorStr = 'the first Link tag with a lrdd rel-attribute has no template-attribute';
            for(var attrJ = 0; attrJ < linkTags[linkTagI].attributes.length; attrJ++) {
              var attr2 = linkTags[linkTagI].attributes[attrJ];
              if(attr2.name=='template') {
                templateParts = attr2.value.split('{uri}');
                if(templateParts.length == 2) {
                  ajax.ajax({
                    url: templateParts[0]+'acct:'+userAddress+templateParts[1],
                    success: function(data) {afterLrddSuccess(data, error, cb);},
                    error: function(data){afterLrddNoAcctError(data, error, cb);},
                  })
                } else {
                  errorStr = 'the template doesn\'t contain "{uri}"';
                }
                break;
              }
            }
            break;
          }
        }
        if(lrddFound) {
          break;
        }
      }
      if(!lrddFound) {
        error(errorStr);//todo: make this error flow nicer
      }
    }
  }
  function afterLrddNoAcctError() {
    error('the template doesn\'t contain "{uri}"');
  }
  function afterLrddSuccess(data, error, cb) {
    data = (new DOMParser()).parseFromString(data, 'text/xml');
    if(!data.getElementsByTagName) {
      error('Lrdd is not an XML document, or doesnt have xml mimetype.');
      return;
    }
    var linkTags = data.getElementsByTagName('Link');
    if(linkTags.length == 0) {
      error('no Link tags found in lrdd');
    } else {
      var linkFound = false;
      var errorStr = 'none of the Link tags have a remoteStorage rel-attribute';
      for(var linkTagI = 0; linkTagI < linkTags.length; linkTagI++) {
        var attributes = {};
        for(var attrI = 0; attrI < linkTags[linkTagI].attributes.length; attrI++) {
          var attr = linkTags[linkTagI].attributes[attrI];
          if((attr.name=='rel') && (attr.value=='remoteStorage')) {
            linkFound = true;
            errorStr = 'the first Link tag with a dav rel-attribute has no template-attribute';
            for(var attrJ = 0; attrJ < linkTags[linkTagI].attributes.length; attrJ++) {
              var attr2 = linkTags[linkTagI].attributes[attrJ];
              if(attr2.name=='template') {
                attributes.template = attr2.value;
              }
              if(attr2.name=='auth') {
                attributes.auth = attr2.value;
              }
              if(attr2.name=='api') {
                attributes.api = attr2.value;
              }
            }
            break;
          }
        }
        if(linkFound) {
          cb(attributes);
          break;
        }
      }
      if(!linkFound) {
        error(errorStr);
      }
    }
  }
  function resolveTemplate(template, dataCategory) {
    var parts = template.split('{category}');
    if(parts.length != 2) {
      return 'cannot-resolve-template:'+template;
    }
    return parts[0]+dataCategory+parts[1];
  }
  return {
    getAttributes: getAttributes,
    resolveTemplate: resolveTemplate
  }
});
<commit_msg>fix trailing comma errors<commit_after>define(['./ajax'], function(ajax) {

    ///////////////
   // Webfinger //
  ///////////////

  var options, userAddress, userName, host, templateParts;//this is all a bit messy, but there are a lot of callbacks here, so globals help us with that.
  function getAttributes(ua, setOptions, error, cb){
    options = setOptions;
    userAddress = ua;
    var parts = ua.split('@');
    if(parts.length < 2) {
      error('That is not a user address. There is no @-sign in it');
    } else if(parts.length > 2) {
      error('That is not a user address. There is more than one @-sign in it');
    } else {
      if(!(/^[\.0-9A-Za-z]+$/.test(parts[0]))) {
        error('That is not a user address. There are non-dotalphanumeric symbols before the @-sign: "'+parts[0]+'"');
      } else if(!(/^[\.0-9A-Za-z\-]+$/.test(parts[1]))) {
        error('That is not a user address. There are non-dotalphanumeric symbols after the @-sign: "'+parts[1]+'"');
      } else {
        userName = parts[0];
        host = parts[1];
        //error('So far so good. Looking up https host-meta for '+host);
        ajax.ajax({
          //url: 'https://'+host+'/.well-known/host-meta',
          url: 'http://'+host+'/.well-known/host-meta',
          success: function(data) {
            afterHostmetaSuccess(data, error, cb);
          },
          error: function(data) {
            afterHttpsHostmetaError(data, error, cb);
          }
        });
      }
    }
  }

  function afterHttpsHostmetaError(data, error, cb) {
    if(options.allowHttpWebfinger) {
      console.log('Https Host-meta error. Trying http.');
      ajax.ajax({
        url: 'http://'+host+'/.well-known/host-meta',
        success: function(data) {
          afterHostmetaSuccess(data, error, cb);
        },
        error: function(data) {
          afterHttpHostmetaError(data, error, cb);
        }
      });
    } else {
       afterHttpHostmetaError(data, error, cb);
    }
  }

  function afterHttpHostmetaError(data, error, cb) {
    if(options.allowSingleOriginWebfinger) {
      console.log('Trying single origin webfinger through proxy');
      ajax.ajax({
        url: 'http://useraddress.net/single-origin-webfinger...really?'+userAddress,
        success: function(data) {
          afterLrddSuccess(data, error, cb);
        },
        error: function(data) {
          afterProxyError(data, error, cb);
        }
      });
    } else {
      afterProxyError(data, error, cb);
    }
  }

  function afterProxyError(data, error, cb) {
    if(options.allowFakefinger) {
      console.log('Trying Fakefinger');
      ajax.ajax({
        url: 'http://useraddress.net/fakefinger?userAddress='+userAddress,
        success: function(data) {
          afterLrddSuccess(data, error, cb);
        },
        error: function(data) {
          afterFakefingerError(data, error, cb);
        }
      });
    } else {
      afterFakefingerError(data, error, cb);
    }
  }
  function afterFakefingerError() {
    alert('user address "'+userAddress+'" doesn\'t seem to have remoteStorage linked to it');
  }
  function afterHostmetaSuccess(data, error, cb) {
    data = (new DOMParser()).parseFromString(data, 'text/xml');
    if(!data.getElementsByTagName) {
      error('Host-meta is not an XML document, or doesnt have xml mimetype.');
      return;
    }
    var linkTags = data.getElementsByTagName('Link');
    if(linkTags.length == 0) {
      error('no Link tags found in host-meta');
    } else {
      var lrddFound = false;
      var errorStr = 'none of the Link tags have a lrdd rel-attribute';
      for(var linkTagI = 0; linkTagI < linkTags.length; linkTagI++) {
        for(var attrI = 0; attrI < linkTags[linkTagI].attributes.length; attrI++) {
          var attr = linkTags[linkTagI].attributes[attrI];
          if((attr.name=='rel') && (attr.value=='lrdd')) {
            lrddFound = true;
            errorStr = 'the first Link tag with a lrdd rel-attribute has no template-attribute';
            for(var attrJ = 0; attrJ < linkTags[linkTagI].attributes.length; attrJ++) {
              var attr2 = linkTags[linkTagI].attributes[attrJ];
              if(attr2.name=='template') {
                templateParts = attr2.value.split('{uri}');
                if(templateParts.length == 2) {
                  ajax.ajax({
                    url: templateParts[0]+'acct:'+userAddress+templateParts[1],
                    success: function(data) {afterLrddSuccess(data, error, cb);},
                    error: function(data){afterLrddNoAcctError(data, error, cb);}
                  });
                } else {
                  errorStr = 'the template doesn\'t contain "{uri}"';
                }
                break;
              }
            }
            break;
          }
        }
        if(lrddFound) {
          break;
        }
      }
      if(!lrddFound) {
        error(errorStr);//todo: make this error flow nicer
      }
    }
  }
  function afterLrddNoAcctError() {
    error('the template doesn\'t contain "{uri}"');
  }
  function afterLrddSuccess(data, error, cb) {
    data = (new DOMParser()).parseFromString(data, 'text/xml');
    if(!data.getElementsByTagName) {
      error('Lrdd is not an XML document, or doesnt have xml mimetype.');
      return;
    }
    var linkTags = data.getElementsByTagName('Link');
    if(linkTags.length == 0) {
      error('no Link tags found in lrdd');
    } else {
      var linkFound = false;
      var errorStr = 'none of the Link tags have a remoteStorage rel-attribute';
      for(var linkTagI = 0; linkTagI < linkTags.length; linkTagI++) {
        var attributes = {};
        for(var attrI = 0; attrI < linkTags[linkTagI].attributes.length; attrI++) {
          var attr = linkTags[linkTagI].attributes[attrI];
          if((attr.name=='rel') && (attr.value=='remoteStorage')) {
            linkFound = true;
            errorStr = 'the first Link tag with a dav rel-attribute has no template-attribute';
            for(var attrJ = 0; attrJ < linkTags[linkTagI].attributes.length; attrJ++) {
              var attr2 = linkTags[linkTagI].attributes[attrJ];
              if(attr2.name=='template') {
                attributes.template = attr2.value;
              }
              if(attr2.name=='auth') {
                attributes.auth = attr2.value;
              }
              if(attr2.name=='api') {
                attributes.api = attr2.value;
              }
            }
            break;
          }
        }
        if(linkFound) {
          cb(attributes);
          break;
        }
      }
      if(!linkFound) {
        error(errorStr);
      }
    }
  }
  function resolveTemplate(template, dataCategory) {
    var parts = template.split('{category}');
    if(parts.length != 2) {
      return 'cannot-resolve-template:'+template;
    }
    return parts[0]+dataCategory+parts[1];
  }
  return {
    getAttributes: getAttributes,
    resolveTemplate: resolveTemplate
  }
});
<|endoftext|>


<commit_before>const Application = require('./spectron/spectronSetup');
const path = require('path');
let app = new Application({});

describe('Tests for Notification position', () => {

    let originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
    jasmine.DEFAULT_TIMEOUT_INTERVAL = Application.getTimeOut();

    beforeAll((done) => {
        return app.startApplication().then((startedApp) => {
            app = startedApp;
            done();
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    afterAll((done) => {
        if (app && app.isRunning()) {
            jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
            app.stop().then(() => {
                done();
            }).catch((err) => {
                console.log(err);
                done();
            });
        }
    });

    it('should launch the app', (done) => {
        return app.client.waitUntilWindowLoaded().then(() => {
            return app.client.getWindowCount().then((count) => {
                expect(count === 1).toBeTruthy();
                done();
            }).catch((err) => {
                expect(err).toBeNull();
            });
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should load demo html page', () => {
        let filePath;
        if (process.platform === 'win32') {
            filePath = 'file:///' + path.join(__dirname, '..', 'demo/index.html');
        } else {
            filePath = 'file://$(pwd)/' + path.join(__dirname, '..', 'demo/index.html')
        }
        return app.client.url(filePath);
    });

    it('should load demo html', () => {
        return app.client.waitUntilWindowLoaded().then(() => {
            return app.client.getTitle().then((title) => {
                expect(title === '').toBeTruthy();
            }).catch((err) => {
                expect(err).toBeNull();
            });
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should open notification configure window', () => {
        return app.client
            .click('#open-config-win')
            .windowByIndex(1)
            .click('#upper-left')
            .click('#ok-button')
            .windowByIndex(0)
            .click('#notf')
            .windowByIndex(1)
    });

    it('should check notification position', () => {
        return app.browserWindow.getBounds().then((bounds) => {
            expect(bounds.x === 0).toBeTruthy();
            expect(bounds.y > 0).toBeTruthy();
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should change the window', () => {
        return app.client.windowByIndex(0).then(() => {
            return app.browserWindow.getTitle().then((title) => {
                expect(title === 'Symphony | Secure Seamless Communication').toBeTruthy();
            }).catch((err) => {
                expect(err).toBeNull();
            });
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should change notification position to lower-right', () => {
        return app.client
            .click('#open-config-win')
            .windowByIndex(2)
            .click('#lower-right')
            .click('#ok-button')
            .windowByIndex(0)
            .click('#notf')
            .windowByIndex(1).then(() => {
                return app.browserWindow.getTitle().then((title) => {
                    expect(title === 'Electron').toBeTruthy();
                }).catch((err) => {
                    expect(err).toBeNull();
                });
            }).catch((err) => {
                expect(err).toBeNull();
            });
    });

    it('should check notification position and equal to lower-right', () => {
        return app.browserWindow.getBounds().then((bounds) => {
            expect(bounds.x > 0).toBeTruthy();
            expect(bounds.y > 0).toBeTruthy();
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should change the window', () => {
        return app.client.windowByIndex(0).then(() => {
            return app.browserWindow.getTitle().then((title) => {
                expect(title === 'Symphony | Secure Seamless Communication').toBeTruthy();
            }).catch((err) => {
                expect(err).toBeNull();
            });
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should change notification position to upper-right', () => {
        return app.client
            .click('#open-config-win')
            .windowByIndex(2)
            .click('#upper-right')
            .click('#ok-button')
            .windowByIndex(0)
            .click('#notf')
            .windowByIndex(1).then(() => {
                return app.browserWindow.getTitle().then((title) => {
                    expect(title === 'Electron').toBeTruthy();
                }).catch((err) => {
                    expect(err).toBeNull();
                });
            }).catch((err) => {
                expect(err).toBeNull();
            });
    });

    it('should check notification position and equal to upper-right', () => {
        return app.browserWindow.getBounds().then((bounds) => {
            expect(bounds.x > 0).toBeTruthy();
            expect(bounds.y > 0).toBeTruthy();
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should change the window to main', () => {
        return app.client.windowByIndex(0).then(() => {
            return app.browserWindow.getTitle().then((title) => {
                expect(title === 'Symphony | Secure Seamless Communication').toBeTruthy();
            }).catch((err) => {
                expect(err).toBeNull();
            });
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should open notification and close', () => {
        return app.client
            .windowByIndex(0)
            .click('#notf')
            .getWindowCount().then((count) => {
                expect(count === 3).toBeTruthy();
            }).catch((err) => {
                expect(err).toBeNull();
            })
            .windowByIndex(1).then(() => {
                return app.browserWindow.getTitle().then((title) => {
                    expect(title === 'Electron').toBeTruthy();
                }).catch((err) => {
                    expect(err).toBeNull();
                });
            }).catch((err) => {
                expect(err).toBeNull();
            });
    });

});<commit_msg>Electron-90 - Fixed notification position test issue<commit_after>const Application = require('./spectron/spectronSetup');
const path = require('path');
const {isMac} = require('../js/utils/misc');
let app = new Application({});

describe('Tests for Notification position', () => {

    let originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
    jasmine.DEFAULT_TIMEOUT_INTERVAL = Application.getTimeOut();

    beforeAll((done) => {
        return app.startApplication().then((startedApp) => {
            app = startedApp;
            done();
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    afterAll((done) => {
        if (app && app.isRunning()) {
            jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
            app.stop().then(() => {
                done();
            }).catch((err) => {
                console.log(err);
                done();
            });
        }
    });

    it('should launch the app', (done) => {
        return app.client.waitUntilWindowLoaded().then(() => {
            return app.client.getWindowCount().then((count) => {
                expect(count === 1).toBeTruthy();
                done();
            }).catch((err) => {
                expect(err).toBeNull();
            });
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should load demo html page', () => {
        let filePath;
        if (process.platform === 'win32') {
            filePath = 'file:///' + path.join(__dirname, '..', 'demo/index.html');
        } else {
            filePath = 'file://$(pwd)/' + path.join(__dirname, '..', 'demo/index.html')
        }
        return app.client.url(filePath);
    });

    it('should load demo html', () => {
        return app.client.waitUntilWindowLoaded().then(() => {
            return app.client.getTitle().then((title) => {
                expect(title === '').toBeTruthy();
            }).catch((err) => {
                expect(err).toBeNull();
            });
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should open notification configure window', () => {
        return app.client
            .click('#open-config-win')
            .windowByIndex(1)
            .click('#upper-left')
            .click('#ok-button')
            .windowByIndex(0)
            .click('#notf')
            .windowByIndex(1)
    });

    it('should check notification position', () => {
        return app.browserWindow.getBounds().then((bounds) => {
            expect(bounds.x === 0).toBeTruthy();
            if (isMac) {
                expect(bounds.y > 0).toBeTruthy();
            } else {
                expect(bounds.y === 0).toBeTruthy();
            }
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should change the window', () => {
        return app.client.windowByIndex(0).then(() => {
            return app.browserWindow.getTitle().then((title) => {
                expect(title === 'Symphony | Secure Seamless Communication').toBeTruthy();
            }).catch((err) => {
                expect(err).toBeNull();
            });
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should change notification position to lower-right', () => {
        return app.client
            .click('#open-config-win')
            .windowByIndex(2)
            .click('#lower-right')
            .click('#ok-button')
            .windowByIndex(0)
            .click('#notf')
            .windowByIndex(1).then(() => {
                return app.browserWindow.getTitle().then((title) => {
                    expect(title === 'Electron').toBeTruthy();
                }).catch((err) => {
                    expect(err).toBeNull();
                });
            }).catch((err) => {
                expect(err).toBeNull();
            });
    });

    it('should check notification position and equal to lower-right', () => {
        return app.browserWindow.getBounds().then((bounds) => {
            expect(bounds.x > 0).toBeTruthy();
            expect(bounds.y > 0).toBeTruthy();
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should change the window', () => {
        return app.client.windowByIndex(0).then(() => {
            return app.browserWindow.getTitle().then((title) => {
                expect(title === 'Symphony | Secure Seamless Communication').toBeTruthy();
            }).catch((err) => {
                expect(err).toBeNull();
            });
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should change notification position to upper-right', () => {
        return app.client
            .click('#open-config-win')
            .windowByIndex(2)
            .click('#upper-right')
            .click('#ok-button')
            .windowByIndex(0)
            .click('#notf')
            .windowByIndex(1).then(() => {
                return app.browserWindow.getTitle().then((title) => {
                    expect(title === 'Electron').toBeTruthy();
                }).catch((err) => {
                    expect(err).toBeNull();
                });
            }).catch((err) => {
                expect(err).toBeNull();
            });
    });

    it('should check notification position and equal to upper-right', () => {
        return app.browserWindow.getBounds().then((bounds) => {
            expect(bounds.x > 0).toBeTruthy();
            if (isMac) {
                expect(bounds.y > 0).toBeTruthy();
            } else {
                expect(bounds.y === 0).toBeTruthy();
            }
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should change the window to main', () => {
        return app.client.windowByIndex(0).then(() => {
            return app.browserWindow.getTitle().then((title) => {
                expect(title === 'Symphony | Secure Seamless Communication').toBeTruthy();
            }).catch((err) => {
                expect(err).toBeNull();
            });
        }).catch((err) => {
            expect(err).toBeNull();
        });
    });

    it('should open notification and close', () => {
        return app.client
            .windowByIndex(0)
            .click('#notf')
            .getWindowCount().then((count) => {
                expect(count === 3).toBeTruthy();
            }).catch((err) => {
                expect(err).toBeNull();
            })
            .windowByIndex(1).then(() => {
                return app.browserWindow.getTitle().then((title) => {
                    expect(title === 'Electron').toBeTruthy();
                }).catch((err) => {
                    expect(err).toBeNull();
                });
            }).catch((err) => {
                expect(err).toBeNull();
            });
    });

});<|endoftext|>


<commit_before>/**
 * 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.
 */

goog.provide('org_apache_flex_html_beads_DataItemRendererFactoryForArrayData');

goog.require('org_apache_flex_core_IDataProviderItemRendererMapper');
goog.require('org_apache_flex_core_IListPresentationModel');
goog.require('org_apache_flex_events_EventDispatcher');
goog.require('org_apache_flex_html_beads_ListView');
goog.require('org_apache_flex_html_beads_models_ArraySelectionModel');
goog.require('org_apache_flex_html_supportClasses_ButtonBarButtonItemRenderer');

/**
 * @constructor
 * @implements {org_apache_flex_core_IDataProviderItemRendererMapper}
 */
org_apache_flex_html_beads_DataItemRendererFactoryForArrayData =
    function() {
};

/**
 * @expose
 */
org_apache_flex_html_beads_DataItemRendererFactoryForArrayData.prototype.itemRendererFactory = null;

/**
 * Metadata
 *
 * @type {Object.<string, Array.<Object>>}
 */
org_apache_flex_html_beads_DataItemRendererFactoryForArrayData.
    prototype.FLEXJS_CLASS_INFO =
    { names: [{ name: 'DataItemRendererFactoryForArrayData',
                qName: 'org_apache_flex_html_beads_DataItemRendererFactoryForArrayData' }],
      interfaces: [org_apache_flex_core_IDataProviderItemRendererMapper] };

/**
 * @private
 * @type {Object}
 */
org_apache_flex_html_beads_DataItemRendererFactoryForArrayData.
    prototype.itemRendererClass_ = null;

Object.defineProperties(org_apache_flex_html_beads_DataItemRendererFactoryForArrayData.prototype, {
    /** @expose */
    strand: {
        /** @this {org_apache_flex_html_beads_DataItemRendererFactoryForArrayData} */
        set: function(value) {
            this.strand_ = value;

            this.model = value.getBeadByType(
                org_apache_flex_html_beads_models_ArraySelectionModel);

            this.listView = value.getBeadByType(
                org_apache_flex_html_beads_ListView);
            this.dataGroup = this.listView.dataGroup;

            this.model.addEventListener('dataProviderChanged',
                goog.bind(this.dataProviderChangedHandler, this));

            if (org_apache_flex_core_ValuesManager.valuesImpl.getValue && !this.itemRendererFactory_) {
              /**
               * @type {Function}
               */
              var c = /** @type {Function} */ (org_apache_flex_core_ValuesManager.valuesImpl.getValue(this.strand_,
                  'iItemRendererClassFactory'));
              this.itemRendererFactory_ = new c();
              this.strand_.addBead(this.itemRendererFactory_);
            }

            this.dataProviderChangedHandler(null);
        }
    },
    /** @expose */
    itemRendererClass: {
        /** @this {org_apache_flex_html_beads_DataItemRendererFactoryForArrayData} */
        get: function() {
            if (org_apache_flex_core_ValuesManager.valuesImpl.getValue && !this.itemRendererClass_) {
              var c = org_apache_flex_core_ValuesManager.valuesImpl.getValue(this.strand_, 'iItemRenderer');
              if (c) {
                this.itemRendererClass_ = c;
              }
            }
            return this.itemRendererClass_;
        },
        /** @this {org_apache_flex_html_beads_DataItemRendererFactoryForArrayData} */
        set: function(value) {
            this.itemRendererClass_ = value;
        }
    }
});

/**
 * @expose
 * @param {Object} event The event that triggered the dataProvider change.
 */
org_apache_flex_html_beads_DataItemRendererFactoryForArrayData.
    prototype.dataProviderChangedHandler = function(event) {
  var dp, i, n, opt;

  this.dataGroup.removeAllElements();

  var presModel = this.strand_.getBeadByType(org_apache_flex_core_IListPresentationModel);

  dp = this.model.dataProvider;
  n = dp.length;
  for (i = 0; i < n; i++) {
    var ir = this.itemRendererFactory_.createItemRenderer(this.dataGroup);
    ir.index = i;
    ir.labelField = this.model.labelField;
    ir.data = dp[i];
    if (presModel) ir.height = presModel.rowHeight;
  }

  var newEvent = new org_apache_flex_events_Event('itemsCreated');
  this.strand_.dispatchEvent(newEvent);
};
<commit_msg>Safety test in case dataProvider isn't available at the time of execution due to timing issues.<commit_after>/**
 * 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.
 */

goog.provide('org_apache_flex_html_beads_DataItemRendererFactoryForArrayData');

goog.require('org_apache_flex_core_IDataProviderItemRendererMapper');
goog.require('org_apache_flex_core_IListPresentationModel');
goog.require('org_apache_flex_events_EventDispatcher');
goog.require('org_apache_flex_html_beads_ListView');
goog.require('org_apache_flex_html_beads_models_ArraySelectionModel');
goog.require('org_apache_flex_html_supportClasses_ButtonBarButtonItemRenderer');

/**
 * @constructor
 * @implements {org_apache_flex_core_IDataProviderItemRendererMapper}
 */
org_apache_flex_html_beads_DataItemRendererFactoryForArrayData =
    function() {
};

/**
 * @expose
 */
org_apache_flex_html_beads_DataItemRendererFactoryForArrayData.prototype.itemRendererFactory = null;

/**
 * Metadata
 *
 * @type {Object.<string, Array.<Object>>}
 */
org_apache_flex_html_beads_DataItemRendererFactoryForArrayData.
    prototype.FLEXJS_CLASS_INFO =
    { names: [{ name: 'DataItemRendererFactoryForArrayData',
                qName: 'org_apache_flex_html_beads_DataItemRendererFactoryForArrayData' }],
      interfaces: [org_apache_flex_core_IDataProviderItemRendererMapper] };

/**
 * @private
 * @type {Object}
 */
org_apache_flex_html_beads_DataItemRendererFactoryForArrayData.
    prototype.itemRendererClass_ = null;

Object.defineProperties(org_apache_flex_html_beads_DataItemRendererFactoryForArrayData.prototype, {
    /** @expose */
    strand: {
        /** @this {org_apache_flex_html_beads_DataItemRendererFactoryForArrayData} */
        set: function(value) {
            this.strand_ = value;

            this.model = value.getBeadByType(
                org_apache_flex_html_beads_models_ArraySelectionModel);

            this.listView = value.getBeadByType(
                org_apache_flex_html_beads_ListView);
            this.dataGroup = this.listView.dataGroup;

            this.model.addEventListener('dataProviderChanged',
                goog.bind(this.dataProviderChangedHandler, this));

            if (org_apache_flex_core_ValuesManager.valuesImpl.getValue && !this.itemRendererFactory_) {
              /**
               * @type {Function}
               */
              var c = /** @type {Function} */ (org_apache_flex_core_ValuesManager.valuesImpl.getValue(this.strand_,
                  'iItemRendererClassFactory'));
              this.itemRendererFactory_ = new c();
              this.strand_.addBead(this.itemRendererFactory_);
            }

            this.dataProviderChangedHandler(null);
        }
    },
    /** @expose */
    itemRendererClass: {
        /** @this {org_apache_flex_html_beads_DataItemRendererFactoryForArrayData} */
        get: function() {
            if (org_apache_flex_core_ValuesManager.valuesImpl.getValue && !this.itemRendererClass_) {
              var c = org_apache_flex_core_ValuesManager.valuesImpl.getValue(this.strand_, 'iItemRenderer');
              if (c) {
                this.itemRendererClass_ = c;
              }
            }
            return this.itemRendererClass_;
        },
        /** @this {org_apache_flex_html_beads_DataItemRendererFactoryForArrayData} */
        set: function(value) {
            this.itemRendererClass_ = value;
        }
    }
});

/**
 * @expose
 * @param {Object} event The event that triggered the dataProvider change.
 */
org_apache_flex_html_beads_DataItemRendererFactoryForArrayData.
    prototype.dataProviderChangedHandler = function(event) {
  var dp, i, n, opt;

  this.dataGroup.removeAllElements();

  var presModel = this.strand_.getBeadByType(org_apache_flex_core_IListPresentationModel);

  dp = this.model.dataProvider;
  if (dp == undefined) return;

  n = dp.length;
  for (i = 0; i < n; i++) {
    var ir = this.itemRendererFactory_.createItemRenderer(this.dataGroup);
    ir.index = i;
    ir.labelField = this.model.labelField;
    ir.data = dp[i];
    if (presModel) ir.height = presModel.rowHeight;
  }

  var newEvent = new org_apache_flex_events_Event('itemsCreated');
  this.strand_.dispatchEvent(newEvent);
};
<|endoftext|>


<commit_before>var Benchmark = require('benchmark')
var suite = new Benchmark.Suite()

var Parser = require('./../')
var ParserOLD = require('./old/parser')

function returnError (error) {
  error = null
}

function checkReply () {}

function shuffle (array) {
  var currentIndex = array.length
  var temporaryValue
  var randomIndex

  // While there remain elements to shuffle...
  while (currentIndex !== 0) {
    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex)
    currentIndex -= 1

    // And swap it with the current element.
    temporaryValue = array[currentIndex]
    array[currentIndex] = array[randomIndex]
    array[randomIndex] = temporaryValue
  }

  return array
}

var startBuffer = new Buffer('$100\r\nabcdefghij')
var chunkBuffer = new Buffer('abcdefghijabcdefghijabcdefghij')
var stringBuffer = new Buffer('+testing a simple string\r\n')
var integerBuffer = new Buffer(':1237884\r\n')
var bigIntegerBuffer = new Buffer(':18446744073709551617\r\n') // 2^64 + 1
var errorBuffer = new Buffer('-Error ohnoesitbroke\r\n')
var arrayBuffer = new Buffer('*1\r\n*1\r\n$1\r\na\r\n')
var endBuffer = new Buffer('\r\n')
var lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, ' +
  'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ' +
  'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ' +
  'ut aliquip ex ea commodo consequat. Duis aute irure dolor in' // 256 chars
var bigStringArray = (new Array(Math.pow(2, 16) / lorem.length).join(lorem + ' ')).split(' ') // Math.pow(2, 16) chars long
var startBigBuffer = new Buffer('$' + (4 * 1024 * 1024) + '\r\n')
var chunks = new Array(64)
for (var i = 0; i < 64; i++) {
  chunks[i] = new Buffer(shuffle(bigStringArray).join(' ') + '.') // Math.pow(2, 16) chars long
}

var bigArraySize = 100
var bigArray = '*' + bigArraySize + '\r\n'
for (i = 0; i < bigArraySize; i++) {
  bigArray += '$'
  var size = (Math.random() * 10 | 0) + 1
  bigArray += size + '\r\n' + lorem.slice(0, size) + '\r\n'
}

var bigArrayBuffer = new Buffer(bigArray)
var chunkedStringPart1 = new Buffer('+foobar')
var chunkedStringPart2 = new Buffer('bazEND\r\n')

var parserOld = new ParserOLD({
  returnReply: checkReply,
  returnError: returnError,
  returnFatalError: returnError,
  name: 'javascript'
})

var parserHiRedis = new Parser({
  returnReply: checkReply,
  returnError: returnError,
  returnFatalError: returnError,
  name: 'hiredis'
})

var parser = new Parser({
  returnReply: checkReply,
  returnError: returnError,
  returnFatalError: returnError
})

// BULK STRINGS

suite.add('OLD CODE: multiple chunks in a bulk string', function () {
  parserOld.execute(startBuffer)
  parserOld.execute(chunkBuffer)
  parserOld.execute(chunkBuffer)
  parserOld.execute(chunkBuffer)
  parserOld.execute(endBuffer)
})

suite.add('HIREDIS: multiple chunks in a bulk string', function () {
  parserHiRedis.execute(startBuffer)
  parserHiRedis.execute(chunkBuffer)
  parserHiRedis.execute(chunkBuffer)
  parserHiRedis.execute(chunkBuffer)
  parserHiRedis.execute(endBuffer)
})

suite.add('NEW CODE: multiple chunks in a bulk string', function () {
  parser.execute(startBuffer)
  parser.execute(chunkBuffer)
  parser.execute(chunkBuffer)
  parser.execute(chunkBuffer)
  parser.execute(endBuffer)
})

// CHUNKED STRINGS

suite.add('\nOLD CODE: multiple chunks in a string', function () {
  parserOld.execute(chunkedStringPart1)
  parserOld.execute(chunkedStringPart2)
})

suite.add('HIREDIS: multiple chunks in a string', function () {
  parserHiRedis.execute(chunkedStringPart1)
  parserHiRedis.execute(chunkedStringPart2)
})

suite.add('NEW CODE: multiple chunks in a string', function () {
  parser.execute(chunkedStringPart1)
  parser.execute(chunkedStringPart2)
})

// BIG BULK STRING

suite.add('\nOLD CODE: 4mb bulk string', function () {
  parserOld.execute(startBigBuffer)
  for (var i = 0; i < 64; i++) {
    parserOld.execute(chunks[i])
  }
  parserOld.execute(endBuffer)
})

suite.add('HIREDIS: 4mb bulk string', function () {
  parserHiRedis.execute(startBigBuffer)
  for (var i = 0; i < 64; i++) {
    parserHiRedis.execute(chunks[i])
  }
  parserHiRedis.execute(endBuffer)
})

suite.add('NEW CODE: 4mb bulk string', function () {
  parser.execute(startBigBuffer)
  for (var i = 0; i < 64; i++) {
    parser.execute(chunks[i])
  }
  parser.execute(endBuffer)
})

// STRINGS

suite.add('\nOLD CODE: + simple string', function () {
  parserOld.execute(stringBuffer)
})

suite.add('HIREDIS: + simple string', function () {
  parserHiRedis.execute(stringBuffer)
})

suite.add('NEW CODE: + simple string', function () {
  parser.execute(stringBuffer)
})

// INTEGERS

suite.add('\nOLD CODE: + integer', function () {
  parserOld.execute(integerBuffer)
})

suite.add('HIREDIS: + integer', function () {
  parserHiRedis.execute(integerBuffer)
})

suite.add('NEW CODE: + integer', function () {
  parser.execute(integerBuffer)
})

// BIG INTEGER

suite.add('\nOLD CODE: + big integer', function () {
  parserOld.execute(bigIntegerBuffer)
})

suite.add('HIREDIS: + big integer', function () {
  parserHiRedis.execute(bigIntegerBuffer)
})

suite.add('NEW CODE: + big integer', function () {
  parser.execute(bigIntegerBuffer)
})

// ARRAYS

suite.add('\nOLD CODE: * array', function () {
  parserOld.execute(arrayBuffer)
})

suite.add('HIREDIS: * array', function () {
  parserHiRedis.execute(arrayBuffer)
})

suite.add('NEW CODE: * array', function () {
  parser.execute(arrayBuffer)
})

// BIG ARRAYS

suite.add('\nOLD CODE: * bigArray', function () {
  parserOld.execute(bigArrayBuffer)
})

suite.add('HIREDIS: * bigArray', function () {
  parserHiRedis.execute(bigArrayBuffer)
})

suite.add('NEW CODE: * bigArray', function () {
  parser.execute(bigArrayBuffer)
})

// ERRORS

suite.add('\nOLD CODE: * error', function () {
  parserOld.execute(errorBuffer)
})

suite.add('HIREDIS: * error', function () {
  parserHiRedis.execute(errorBuffer)
})

suite.add('NEW CODE: * error', function () {
  parser.execute(errorBuffer)
})

// add listeners
suite.on('cycle', function (event) {
  console.log(String(event.target))
})

suite.on('complete', function () {
  console.log('\n\nFastest is ' + this.filter('fastest').map('name'))
})

suite.run({ delay: 1, minSamples: 150 })
<commit_msg>Add additional benchmarks for returning buffers and stringNumbers<commit_after>var Benchmark = require('benchmark')
var suite = new Benchmark.Suite()

var Parser = require('./../')
var ParserOLD = require('./old/parser')

function returnError (error) {
  error = null
}

function checkReply () {}

function shuffle (array) {
  var currentIndex = array.length
  var temporaryValue
  var randomIndex

  // While there remain elements to shuffle...
  while (currentIndex !== 0) {
    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex)
    currentIndex -= 1

    // And swap it with the current element.
    temporaryValue = array[currentIndex]
    array[currentIndex] = array[randomIndex]
    array[randomIndex] = temporaryValue
  }

  return array
}

var startBuffer = new Buffer('$100\r\nabcdefghij')
var chunkBuffer = new Buffer('abcdefghijabcdefghijabcdefghij')
var stringBuffer = new Buffer('+testing a simple string\r\n')
var integerBuffer = new Buffer(':1237884\r\n')
var bigIntegerBuffer = new Buffer(':18446744073709551617\r\n') // 2^64 + 1
var errorBuffer = new Buffer('-Error ohnoesitbroke\r\n')
var arrayBuffer = new Buffer('*1\r\n*1\r\n$1\r\na\r\n')
var endBuffer = new Buffer('\r\n')
var lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, ' +
  'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ' +
  'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ' +
  'ut aliquip ex ea commodo consequat. Duis aute irure dolor in' // 256 chars
var bigStringArray = (new Array(Math.pow(2, 16) / lorem.length).join(lorem + ' ')).split(' ') // Math.pow(2, 16) chars long
var startBigBuffer = new Buffer('$' + (4 * 1024 * 1024) + '\r\n')
var chunks = new Array(64)
for (var i = 0; i < 64; i++) {
  chunks[i] = new Buffer(shuffle(bigStringArray).join(' ') + '.') // Math.pow(2, 16) chars long
}

var bigArraySize = 100
var bigArray = '*' + bigArraySize + '\r\n'
for (i = 0; i < bigArraySize; i++) {
  bigArray += '$'
  var size = (Math.random() * 10 | 0) + 1
  bigArray += size + '\r\n' + lorem.slice(0, size) + '\r\n'
}

var bigArrayBuffer = new Buffer(bigArray)
var chunkedStringPart1 = new Buffer('+foobar')
var chunkedStringPart2 = new Buffer('bazEND\r\n')

var parserOld = new ParserOLD({
  returnReply: checkReply,
  returnError: returnError,
  returnFatalError: returnError,
  name: 'javascript'
})

var parserHiRedis = new Parser({
  returnReply: checkReply,
  returnError: returnError,
  returnFatalError: returnError,
  name: 'hiredis'
})

var parser = new Parser({
  returnReply: checkReply,
  returnError: returnError,
  returnFatalError: returnError
})

var parserBuffer = new Parser({
  returnReply: checkReply,
  returnError: returnError,
  returnFatalError: returnError,
  returnBuffers: true
})

var parserStr = new Parser({
  returnReply: checkReply,
  returnError: returnError,
  returnFatalError: returnError,
  stringNumbers: true
})

// BULK STRINGS

suite.add('OLD CODE: multiple chunks in a bulk string', function () {
  parserOld.execute(startBuffer)
  parserOld.execute(chunkBuffer)
  parserOld.execute(chunkBuffer)
  parserOld.execute(chunkBuffer)
  parserOld.execute(endBuffer)
})

suite.add('HIREDIS: multiple chunks in a bulk string', function () {
  parserHiRedis.execute(startBuffer)
  parserHiRedis.execute(chunkBuffer)
  parserHiRedis.execute(chunkBuffer)
  parserHiRedis.execute(chunkBuffer)
  parserHiRedis.execute(endBuffer)
})

suite.add('NEW CODE: multiple chunks in a bulk string', function () {
  parser.execute(startBuffer)
  parser.execute(chunkBuffer)
  parser.execute(chunkBuffer)
  parser.execute(chunkBuffer)
  parser.execute(endBuffer)
})

suite.add('NEW BUF: multiple chunks in a bulk string', function () {
  parserBuffer.execute(startBuffer)
  parserBuffer.execute(chunkBuffer)
  parserBuffer.execute(chunkBuffer)
  parserBuffer.execute(chunkBuffer)
  parserBuffer.execute(endBuffer)
})

// CHUNKED STRINGS

suite.add('\nOLD CODE: multiple chunks in a string', function () {
  parserOld.execute(chunkedStringPart1)
  parserOld.execute(chunkedStringPart2)
})

suite.add('HIREDIS: multiple chunks in a string', function () {
  parserHiRedis.execute(chunkedStringPart1)
  parserHiRedis.execute(chunkedStringPart2)
})

suite.add('NEW CODE: multiple chunks in a string', function () {
  parser.execute(chunkedStringPart1)
  parser.execute(chunkedStringPart2)
})

suite.add('NEW BUF: multiple chunks in a string', function () {
  parserBuffer.execute(chunkedStringPart1)
  parserBuffer.execute(chunkedStringPart2)
})

// BIG BULK STRING

suite.add('\nOLD CODE: 4mb bulk string', function () {
  parserOld.execute(startBigBuffer)
  for (var i = 0; i < 64; i++) {
    parserOld.execute(chunks[i])
  }
  parserOld.execute(endBuffer)
})

suite.add('HIREDIS: 4mb bulk string', function () {
  parserHiRedis.execute(startBigBuffer)
  for (var i = 0; i < 64; i++) {
    parserHiRedis.execute(chunks[i])
  }
  parserHiRedis.execute(endBuffer)
})

suite.add('NEW CODE: 4mb bulk string', function () {
  parser.execute(startBigBuffer)
  for (var i = 0; i < 64; i++) {
    parser.execute(chunks[i])
  }
  parser.execute(endBuffer)
})

suite.add('NEW BUF: 4mb bulk string', function () {
  parserBuffer.execute(startBigBuffer)
  for (var i = 0; i < 64; i++) {
    parserBuffer.execute(chunks[i])
  }
  parserBuffer.execute(endBuffer)
})

// STRINGS

suite.add('\nOLD CODE: + simple string', function () {
  parserOld.execute(stringBuffer)
})

suite.add('HIREDIS: + simple string', function () {
  parserHiRedis.execute(stringBuffer)
})

suite.add('NEW CODE: + simple string', function () {
  parser.execute(stringBuffer)
})

suite.add('NEW BUF: + simple string', function () {
  parserBuffer.execute(stringBuffer)
})

// INTEGERS

suite.add('\nOLD CODE: + integer', function () {
  parserOld.execute(integerBuffer)
})

suite.add('HIREDIS: + integer', function () {
  parserHiRedis.execute(integerBuffer)
})

suite.add('NEW CODE: + integer', function () {
  parser.execute(integerBuffer)
})

suite.add('NEW STR: + integer', function () {
  parserStr.execute(integerBuffer)
})

// BIG INTEGER

suite.add('\nOLD CODE: + big integer', function () {
  parserOld.execute(bigIntegerBuffer)
})

suite.add('HIREDIS: + big integer', function () {
  parserHiRedis.execute(bigIntegerBuffer)
})

suite.add('NEW CODE: + big integer', function () {
  parser.execute(bigIntegerBuffer)
})

suite.add('NEW STR: + big integer', function () {
  parserStr.execute(bigIntegerBuffer)
})

// ARRAYS

suite.add('\nOLD CODE: * array', function () {
  parserOld.execute(arrayBuffer)
})

suite.add('HIREDIS: * array', function () {
  parserHiRedis.execute(arrayBuffer)
})

suite.add('NEW CODE: * array', function () {
  parser.execute(arrayBuffer)
})

suite.add('NEW BUF: * array', function () {
  parserBuffer.execute(arrayBuffer)
})

// BIG ARRAYS

suite.add('\nOLD CODE: * bigArray', function () {
  parserOld.execute(bigArrayBuffer)
})

suite.add('HIREDIS: * bigArray', function () {
  parserHiRedis.execute(bigArrayBuffer)
})

suite.add('NEW CODE: * bigArray', function () {
  parser.execute(bigArrayBuffer)
})

suite.add('NEW BUF: * bigArray', function () {
  parserBuffer.execute(bigArrayBuffer)
})

// ERRORS

suite.add('\nOLD CODE: * error', function () {
  parserOld.execute(errorBuffer)
})

suite.add('HIREDIS: * error', function () {
  parserHiRedis.execute(errorBuffer)
})

suite.add('NEW CODE: * error', function () {
  parser.execute(errorBuffer)
})

// add listeners
suite.on('cycle', function (event) {
  console.log(String(event.target))
})

suite.on('complete', function () {
  console.log('\n\nFastest is ' + this.filter('fastest').map('name'))
})

suite.run({ delay: 1, minSamples: 150 })
<|endoftext|>


<commit_before>/**
 * API requests for WA Updater app or other uses
 */

 /**
  * Get latest versions
  */
server.get('api/addons', (req, res, next) => {
  res.send(global.addonUpdates)
})

/**
  * Wago multi WA lookup
  */
 server.get('/api/check/weakauras', (req, res, next) => {
  if (!req.query.ids) {
    return res.send(404, {error: "page_not_found"})
  }

  var ids = req.query.ids.split(',').slice(0, 200)
  var wagos = []
  WagoItem.find({'$or' : [{_id: ids}, {custom_slug: ids}], deleted: false, type: ['WEAKAURAS', 'WEAKAURAS2']})
  .populate('_userId')
  .then((docs) => {
    async.forEachOf(docs, (doc, k, done) => {
      if (doc.private && (!req.user || !req.user._id.equals(doc._userId))) {
        return done()
      }
      var wago = {}
      wago._id = doc._id
      wago.name = doc.name
      wago.slug = doc.custom_slug || doc._id
      wago.url = doc.url
      wago.created = doc.created
      wago.modified = doc.modified
      wago.forkOf = doc.fork_of
      wago.username = doc._userId.account.username

      // if requested by WA Companion App, update installed count
      if (req.headers['identifier'] && req.headers['user-agent'].match(/Electron/)) {
        const ipAddress = req.headers['x-forwarded-for'] ||
          req.connection.remoteAddress ||
          req.socket.remoteAddress ||
          (req.connection.socket ? req.connection.socket.remoteAddress : null)
        WagoFavorites.addInstall(doc, 'WA-Updater-' + req.headers['identifier'], ipAddress)
      }

      if (doc.latestVersion.iteration && typeof doc.latestVersion.changelog !== 'string') {
        wago.version = doc.latestVersion.iteration
        wago.versionString = doc.latestVersion.versionString
        if (typeof doc.latestVersion.changelog === 'string') {
          doc.latestVersion.changelog = JSON.parse(doc.latestVersion.changelog)
        }
        wago.changelog = doc.latestVersion.changelog
        wagos.push(wago)
        return done()
      }

      WagoCode.lookup(wago._id).then((code) => {
        wago.version = code.version
        var versionString = code.versionString
        if (versionString !== '1.0.' + (code.version + 1) && versionString !== '0.0.' + code.version) {
          versionString = versionString + '-' + code.version
        }
        wago.versionString = versionString
        wago.changelog = code.changelog
        wagos.push(wago)

        doc.latestVersion.iteration = code.version
        doc.latestVersion.versionString = versionString
        doc.latestVersion.changelog = code.changelog
        doc.save()
        done()
      })
    }, function() {
      res.send(wagos)
    })
  })
})

/*
 * Get raw data
 */
server.get('/api/raw/encoded', (req, res) => {
  if (!req.params.id) {
    return res.send(404, {error: "page_not_found"})
  }

  WagoItem.lookup(req.params.id).then((wago) => {
    if (!wago) {
      return res.send(404, {error: "page_not_found"})
    }
    else if (wago.private && (!req.user || !req.user._id.equals(wago._userId))) {
      return res.send(401, {error: "import_is_private"})
    }
    WagoCode.lookup(wago._id, req.params.version).then((code) => {
      if (!code || !code.encoded) {
        return res.send(404, {error: "page_not_found"})
      }
      res.set('Content-Type', 'text/plain')

      if (wago.type === 'WEAKAURA' && code.json && code.json.match(commonRegex.WeakAuraBlacklist)) {
        return res.send(403, '')
      }
      if (wago.type === 'WEAKAURA' && !code.encoded.match(/^!/)) {
        lua.JSON2WeakAura(code.json, (error, result) => {
          code.encoded = result.stdout
          res.send(code.encoded)
        })
      }
      else {
        res.send(code.encoded)
      }
    })
  })
})

/**
 * Some companion stats?
 */
server.get('/api/wa-companion-stats', (req, res) => {
  WagoFavorites.find().distinct('appID').then((num) => {
    res.send({Installs: num.length - 1}) // don't count null appID
  })
})<commit_msg>fix non-user api lookup<commit_after>/**
 * API requests for WA Updater app or other uses
 */

 /**
  * Get latest versions
  */
server.get('api/addons', (req, res, next) => {
  res.send(global.addonUpdates)
})

/**
  * Wago multi WA lookup
  */
 server.get('/api/check/weakauras', (req, res, next) => {
  if (!req.query.ids) {
    return res.send(404, {error: "page_not_found"})
  }

  var ids = req.query.ids.split(',').slice(0, 200)
  var wagos = []
  WagoItem.find({'$or' : [{_id: ids}, {custom_slug: ids}], deleted: false, type: ['WEAKAURAS', 'WEAKAURAS2']})
  .populate('_userId')
  .then((docs) => {
    async.forEachOf(docs, (doc, k, done) => {
      if (doc.private && (!req.user || !req.user._id.equals(doc._userId))) {
        return done()
      }
      var wago = {}
      wago._id = doc._id
      wago.name = doc.name
      wago.slug = doc.custom_slug || doc._id
      wago.url = doc.url
      wago.created = doc.created
      wago.modified = doc.modified
      wago.forkOf = doc.fork_of
      if (doc._userId) {
        wago.username = doc._userId.account.username
      }

      // if requested by WA Companion App, update installed count
      if (req.headers['identifier'] && req.headers['user-agent'].match(/Electron/)) {
        const ipAddress = req.headers['x-forwarded-for'] ||
          req.connection.remoteAddress ||
          req.socket.remoteAddress ||
          (req.connection.socket ? req.connection.socket.remoteAddress : null)
        WagoFavorites.addInstall(doc, 'WA-Updater-' + req.headers['identifier'], ipAddress)
      }

      if (doc.latestVersion.iteration && typeof doc.latestVersion.changelog !== 'string') {
        wago.version = doc.latestVersion.iteration
        wago.versionString = doc.latestVersion.versionString
        if (typeof doc.latestVersion.changelog === 'string') {
          doc.latestVersion.changelog = JSON.parse(doc.latestVersion.changelog)
        }
        wago.changelog = doc.latestVersion.changelog
        wagos.push(wago)
        return done()
      }

      WagoCode.lookup(wago._id).then((code) => {
        wago.version = code.version
        var versionString = code.versionString
        if (versionString !== '1.0.' + (code.version + 1) && versionString !== '0.0.' + code.version) {
          versionString = versionString + '-' + code.version
        }
        wago.versionString = versionString
        wago.changelog = code.changelog
        wagos.push(wago)

        doc.latestVersion.iteration = code.version
        doc.latestVersion.versionString = versionString
        doc.latestVersion.changelog = code.changelog
        doc.save()
        done()
      })
    }, function() {
      res.send(wagos)
    })
  })
})

/*
 * Get raw data
 */
server.get('/api/raw/encoded', (req, res) => {
  if (!req.params.id) {
    return res.send(404, {error: "page_not_found"})
  }

  WagoItem.lookup(req.params.id).then((wago) => {
    if (!wago) {
      return res.send(404, {error: "page_not_found"})
    }
    else if (wago.private && (!req.user || !req.user._id.equals(wago._userId))) {
      return res.send(401, {error: "import_is_private"})
    }
    WagoCode.lookup(wago._id, req.params.version).then((code) => {
      if (!code || !code.encoded) {
        return res.send(404, {error: "page_not_found"})
      }
      res.set('Content-Type', 'text/plain')

      if (wago.type === 'WEAKAURA' && code.json && code.json.match(commonRegex.WeakAuraBlacklist)) {
        return res.send(403, '')
      }
      if (wago.type === 'WEAKAURA' && !code.encoded.match(/^!/)) {
        lua.JSON2WeakAura(code.json, (error, result) => {
          code.encoded = result.stdout
          res.send(code.encoded)
        })
      }
      else {
        res.send(code.encoded)
      }
    })
  })
})

/**
 * Some companion stats?
 */
server.get('/api/wa-companion-stats', (req, res) => {
  WagoFavorites.find().distinct('appID').then((num) => {
    res.send({Installs: num.length - 1}) // don't count null appID
  })
})<|endoftext|>


<commit_before>/* eslint-env mocha */
import { expect } from 'chai'
import utils from './utils'

describe('application launch', function () {
  this.timeout(30000)
  beforeEach(utils.beforeEach)
  afterEach(utils.afterEach)
  it('root component is mounted', async function () {
    const { app } = this
    await app.client.waitUntilWindowLoaded()
    const exists = await app.client.isExisting('#root')
    expect(exists).to.be.true
  })

  it('ipfs is started', function (done) {
    const { app } = this
    const { ipcRenderer, remote } = this.app.electron
    app.client.waitUntilWindowLoaded()
      .then(() => {
        if (remote.getGlobal('ipfsLoaded')) {
          done()
        } else {
          ipcRenderer.on('ipfs-ready', (event, message) => {
            done()
          })
        }
      })
  })

  it('app component is mounted', async function () {
    const { app } = this
    await app.client.waitUntilWindowLoaded()
    // TODO: await app.window.ipfsStarted()
    await utils.asyncTimeout(20000)
    const exists = await app.client.isExisting('#app')
    expect(exists).to.be.true
  })
})
<commit_msg>new tests (broken)<commit_after>/* eslint-env mocha */
import { expect } from 'chai'
import utils from './utils'

describe('application launch', function () {
  this.timeout(30000)
  beforeEach(utils.beforeEach)
  afterEach(utils.afterEach)
  it('root component is mounted', async function () {
    const { app } = this
    await app.client.waitUntilWindowLoaded()
    const exists = await app.client.isExisting('#root')
    expect(exists).to.be.true
  })

  it('ipfs is started', function (done) {
    const { app } = this
    const { ipcRenderer, remote } = app.electron
    app.client.waitUntilWindowLoaded()
      .then(() => {
        if (remote.getGlobal('ipfsLoaded')) {
          done()
        } else {
          ipcRenderer.on('ipfs-ready', (event, message) => {
            done()
          })
        }
      })
  })

  it('ipfs daemon is started', function (done) {
    const { app } = this
    app.client.waitUntilWindowLoaded()
      .then(() => {
        app
          .electron
          .remote
          .getGlobal('ipfsDaemon')(({ ready }) => {
            console.log(ready)
            if (ready === null) return
            if (ready) done()
          })
      })
  })

  it('app component is mounted', async function () {
    const { app } = this
    await app.client.waitUntilWindowLoaded()
    await app.remote.getGlobal()
    await utils.asyncTimeout(20000)
    const exists = await app.client.isExisting('#app')
    expect(exists).to.be.true
  })
})
<|endoftext|>