<commit_before>// --
// Copyright (C) 2001-2017 OTRS AG, http://otrs.com/
// --
// This software comes with ABSOLUTELY NO WARRANTY. For details, see
// the enclosed file COPYING for license information (AGPL). If you
// did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
// --

"use strict";

var Core = Core || {};
Core.Agent = Core.Agent || {};
Core.Agent.Admin = Core.Agent.Admin || {};

/**
 * @namespace Core.Agent.Admin
 * @memberof Core.Agent.Admin
 * @author OTRS AG
 * @description
 *      This namespace contains the special module functions for the admin overview module.
 */
Core.Agent.Admin = (function (TargetNS) {
    /**
     * @name Init
     * @memberof Core.Agent.Admin
     * @function
     * @description
     *      Initializes Overview screen.
     */
    TargetNS.Init = function () {

        var Favourites = Core.Config.Get('Favourites');

        $('.SidebarColumn #Filter').focus();

        $('.AddAsFavourite').on('click', function(Event) {
            var $TriggerObj = $(this),
                Module = $(this).data('module');

            Event.stopPropagation();
            $(this).addClass('Clicked');
            Favourites.push(Module);
            Core.Agent.PreferencesUpdate('AdminNavigationBarFavourites', JSON.stringify(Favourites), function() {

                var FavouriteHTML = '';

                if ($('#ToggleView').hasClass('Grid')) {

                    // also add the entry to the sidebar favourites list dynamically
                    FavouriteHTML = Core.Template.Render('Agent/Admin/Favourite', {
                        'Link'  : $TriggerObj.closest('a').attr('href'),
                        'Name'  : $TriggerObj.closest('a').find('span.Title').text(),
                        'Module': Module
                    });

                    // Fade the original icon out and display a success icon
                    $TriggerObj.find('i').fadeOut(function() {
                        $(this).closest('li').find('.AddAsFavourite').append('').find('i').fadeIn().delay(1000).fadeOut(function() {
                            $(this)
                                .closest('.AddAsFavourite')
                                .remove();
                            $('.GridView, .ListView').find('[data-module="' + Module + '"]').addClass('IsFavourite');
                        });
                        $(this).remove();
                    });
                }
                else {

                    // also add the entry to the sidebar favourites list dynamically
                    FavouriteHTML = Core.Template.Render('Agent/Admin/Favourite', {
                        'Link'  : $TriggerObj.closest('tr').find('a.ModuleLink').attr('href'),
                        'Name'  : $TriggerObj.closest('tr').find('a.ModuleLink').text(),
                        'Module': Module
                    });

                    // Fade the original icon out and display a success icon
                    $('.GridView, .ListView').find('[data-module="' + Module + '"]').addClass('IsFavourite');
                }

                $('.DataTable.Favourites').append($(FavouriteHTML));
                $('.DataTable.Favourites').show();

            });
            return false;
        });

        $('.DataTable.Favourites').on('click', '.RemoveFromFavourites', function() {
            var Module = $(this).data('module'),
                Index = Favourites.indexOf(Module),
                $TriggerObj = $(this);

            if (Index > -1) {
                Favourites.splice(Index, 1);
                Core.Agent.PreferencesUpdate('AdminNavigationBarFavourites', JSON.stringify(Favourites), function() {
                    $TriggerObj.closest('tr').fadeOut(function() {
                        var $TableObj = $(this).closest('table');
                        $(this).remove();
                        if (!$TableObj.find('tr').length) {
                            $TableObj.hide();
                        }

                        // also remove the corresponding class from the entry in the grid
                        $('.GridView, .ListView').find('[data-module="' + Module + '"]').removeClass('IsFavourite');
                    });
                });
            }

            return false;
        });

        $('#ToggleView').on('click', function() {
            if ($(this).hasClass('Grid')) {
                Core.Agent.PreferencesUpdate('AdminNavigationBarView', 'List');
                $('.GridView').fadeOut();
                $('.ListView').fadeIn(function() {

                    // check if the "no matches found" message is the only visible entry
                    if ($('.ListView .DataTable tbody tr:visible').length == 1 && $('.ListView .DataTable tbody tr:visible').hasClass('FilterMessage')) {
                        $('.ListView .DataTable tr.FilterMessage').removeClass('Hidden');
                    }
                    else {
                        $('.ListView .DataTable tr.FilterMessage').hide();
                    }
                    $('#ToggleView').removeClass('Grid').addClass('List');
                });
            }
            else {
                Core.Agent.PreferencesUpdate('AdminNavigationBarView', 'Grid');
                $('.ListView').fadeOut();
                $('.GridView').fadeIn(function() {
                    $('#ToggleView').removeClass('List').addClass('Grid');
                });
            }
        });

        Core.UI.Table.InitTableFilter($('#Filter'), $('.Filterable'));

    };

    Core.Init.RegisterNamespace(TargetNS, 'APP_MODULE');

    return TargetNS;
}(Core.Agent.Admin || {}));
<commit_msg>Fixed an issue where the invisible text would get added to the list of favourites, too.<commit_after>// --
// Copyright (C) 2001-2017 OTRS AG, http://otrs.com/
// --
// This software comes with ABSOLUTELY NO WARRANTY. For details, see
// the enclosed file COPYING for license information (AGPL). If you
// did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
// --

"use strict";

var Core = Core || {};
Core.Agent = Core.Agent || {};
Core.Agent.Admin = Core.Agent.Admin || {};

/**
 * @namespace Core.Agent.Admin
 * @memberof Core.Agent.Admin
 * @author OTRS AG
 * @description
 *      This namespace contains the special module functions for the admin overview module.
 */
Core.Agent.Admin = (function (TargetNS) {
    /**
     * @name Init
     * @memberof Core.Agent.Admin
     * @function
     * @description
     *      Initializes Overview screen.
     */
    TargetNS.Init = function () {

        var Favourites = Core.Config.Get('Favourites');

        $('.SidebarColumn #Filter').focus();

        $('.AddAsFavourite').off('click.AddAsFavourite').on('click.AddAsFavourite', function(Event) {
            var $TriggerObj = $(this),
                Module = $(this).data('module');

            Event.stopPropagation();
            $(this).addClass('Clicked');
            Favourites.push(Module);
            Core.Agent.PreferencesUpdate('AdminNavigationBarFavourites', JSON.stringify(Favourites), function() {

                var FavouriteHTML = '';

                if ($('#ToggleView').hasClass('Grid')) {

                    // also add the entry to the sidebar favourites list dynamically
                    FavouriteHTML = Core.Template.Render('Agent/Admin/Favourite', {
                        'Link'  : $TriggerObj.closest('a').attr('href'),
                        'Name'  : $TriggerObj.closest('a').find('span.Title').clone().children().remove().end().text(),
                        'Module': Module
                    });

                    // Fade the original icon out and display a success icon
                    $TriggerObj.find('i').fadeOut(function() {
                        $(this).closest('li').find('.AddAsFavourite').append('').find('i').fadeIn().delay(1000).fadeOut(function() {
                            $(this)
                                .closest('.AddAsFavourite')
                                .remove();
                            $('.GridView, .ListView').find('[data-module="' + Module + '"]').addClass('IsFavourite');
                        });
                        $(this).remove();
                    });
                }
                else {

                    // also add the entry to the sidebar favourites list dynamically
                    FavouriteHTML = Core.Template.Render('Agent/Admin/Favourite', {
                        'Link'  : $TriggerObj.closest('tr').find('a.ModuleLink').attr('href'),
                        'Name'  : $TriggerObj.closest('tr').find('a.ModuleLink').clone().children().remove().end().text(),
                        'Module': Module
                    });

                    // Fade the original icon out and display a success icon
                    $('.GridView, .ListView').find('[data-module="' + Module + '"]').addClass('IsFavourite');
                }

                $('.DataTable.Favourites').append($(FavouriteHTML));
                $('.DataTable.Favourites').show();

            });
            return false;
        });

        $('.DataTable.Favourites').on('click', '.RemoveFromFavourites', function() {
            var Module = $(this).data('module'),
                Index = Favourites.indexOf(Module),
                $TriggerObj = $(this);

            if (Index > -1) {
                Favourites.splice(Index, 1);
                Core.Agent.PreferencesUpdate('AdminNavigationBarFavourites', JSON.stringify(Favourites), function() {
                    $TriggerObj.closest('tr').fadeOut(function() {
                        var $TableObj = $(this).closest('table');
                        $(this).remove();
                        if (!$TableObj.find('tr').length) {
                            $TableObj.hide();
                        }

                        // also remove the corresponding class from the entry in the grid
                        $('.GridView, .ListView').find('[data-module="' + Module + '"]').removeClass('IsFavourite');
                    });
                });
            }

            return false;
        });

        $('#ToggleView').on('click', function() {
            if ($(this).hasClass('Grid')) {
                Core.Agent.PreferencesUpdate('AdminNavigationBarView', 'List');
                $('.GridView').fadeOut();
                $('.ListView').fadeIn(function() {

                    // check if the "no matches found" message is the only visible entry
                    if ($('.ListView .DataTable tbody tr:visible').length == 1 && $('.ListView .DataTable tbody tr:visible').hasClass('FilterMessage')) {
                        $('.ListView .DataTable tr.FilterMessage').removeClass('Hidden');
                    }
                    else {
                        $('.ListView .DataTable tr.FilterMessage').hide();
                    }
                    $('#ToggleView').removeClass('Grid').addClass('List');
                });
            }
            else {
                Core.Agent.PreferencesUpdate('AdminNavigationBarView', 'Grid');
                $('.ListView').fadeOut();
                $('.GridView').fadeIn(function() {
                    $('#ToggleView').removeClass('List').addClass('Grid');
                });
            }
        });

        Core.UI.Table.InitTableFilter($('#Filter'), $('.Filterable'));

    };

    Core.Init.RegisterNamespace(TargetNS, 'APP_MODULE');

    return TargetNS;
}(Core.Agent.Admin || {}));
<|endoftext|>


<commit_before>OpenLayers.Control.MouseDefaults = Class.create();
OpenLayers.Control.MouseDefaults.prototype =
  Object.extend( new OpenLayers.Control(), {

    initialize: function() {
        OpenLayers.Control.prototype.initialize.apply(this, arguments);
    },

    draw: function() {
        this.map.events.register( "dblclick", this, this.defaultDblClick );
        this.map.events.register( "mousedown", this, this.defaultMouseDown );
        this.map.events.register( "mouseup", this, this.defaultMouseUp );
        this.map.events.register( "mousemove", this, this.defaultMouseMove );
        //this.map.events.register( "mouseout", this, this.defaultMouseUp );
    },

    /**
    * @param {Event} evt
    */
    defaultDblClick: function (evt) {
        var newCenter = this.map.getLonLatFromPixel( evt.xy );
        this.map.setCenter(newCenter, this.map.zoom + 1);
    },

    /**
    * @param {Event} evt
    */
    defaultMouseDown: function (evt) {
        this.mouseDragStart = evt.xy.copyOf();
        if (evt.shiftKey) {
            this.map.div.style.cursor = "crosshair";
            this.zoomBox = OpenLayers.Util.createDiv('zoomBox');
            this.zoomBox.style.border = '1px solid red';
            this.zoomBox.style.position="absolute";
            this.zoomBox.style.zIndex=1000;
            this.zoomBox.style.top=this.mouseDragStart.y;
            this.zoomBox.style.left=this.mouseDragStart.x;
            this.map.viewPortDiv.appendChild(this.zoomBox);
        } else {
            this.map.div.style.cursor = "move";
        }
        Event.stop(evt);
    },

    /**
    * @param {Event} evt
    */
    defaultMouseMove: function (evt) {
        if (this.mouseDragStart != null) {
            if (this.zoomBox) {
		if (!evt.shiftKey) {
		    this.defaultMouseUp(evt);
                    return;
                }
                var deltaX = Math.abs(this.mouseDragStart.x - evt.xy.x);
                var deltaY = Math.abs(this.mouseDragStart.y - evt.xy.y);
                this.zoomBox.style.width = deltaX+"px";
                this.zoomBox.style.height = deltaY+"px";
                if (evt.xy.x < this.mouseDragStart.x) {
                    this.zoomBox.style.left = evt.xy.x+"px";
                }
                if (evt.xy.y < this.mouseDragStart.y) {
                    this.zoomBox.style.top = evt.xy.y+"px";
                }
            } else {
                var deltaX = this.map.mouseDragStart.x - evt.xy.x;
                var deltaY = this.map.mouseDragStart.y - evt.xy.y;
                var size = this.map.getSize();
                var newXY = new OpenLayers.Pixel(size.w / 2 + deltaX,
                                                 size.h / 2 + deltaY);
                var newCenter = this.map.getLonLatFromPixel( newXY );
                this.map.setCenter(newCenter);
                this.map.mouseDragStart = evt.xy.copyOf();
            }
        }
    },

    /**
    * @param {Event} evt
    */
    defaultMouseUp: function (evt) {
        if (this.zoomBox) {
	    if (evt.shiftKey) {
		var start = this.map.getLonLatFromPixel( this.mouseDragStart );
		var end = this.map.getLonLatFromPixel( evt.xy );
		var top = Math.max(start.lat, end.lat);
		var bottom = Math.min(start.lat, end.lat);
		var left = Math.min(start.lon, end.lon);
		var right = Math.max(start.lon, end.lon);
		var bounds = new OpenLayers.Bounds(left, bottom, right, top);
		var zoom = this.map.getZoomForExtent(bounds);
		this.map.setCenter(new OpenLayers.LonLat(
		  (start.lon + end.lon) / 2,
		  (start.lat + end.lat) / 2
		 ), zoom);
            }
            this.map.viewPortDiv.removeChild(document.getElementById("zoomBox"));
            this.zoomBox = null;
        }
        this.mouseDragStart = null;
        this.map.div.style.cursor = "default";
    }

});

<commit_msg>Missed a switch from this.map -> this on mouseDefaults. Dragging was  broken.<commit_after>OpenLayers.Control.MouseDefaults = Class.create();
OpenLayers.Control.MouseDefaults.prototype =
  Object.extend( new OpenLayers.Control(), {

    initialize: function() {
        OpenLayers.Control.prototype.initialize.apply(this, arguments);
    },

    draw: function() {
        this.map.events.register( "dblclick", this, this.defaultDblClick );
        this.map.events.register( "mousedown", this, this.defaultMouseDown );
        this.map.events.register( "mouseup", this, this.defaultMouseUp );
        this.map.events.register( "mousemove", this, this.defaultMouseMove );
        //this.map.events.register( "mouseout", this, this.defaultMouseUp );
    },

    /**
    * @param {Event} evt
    */
    defaultDblClick: function (evt) {
        var newCenter = this.map.getLonLatFromPixel( evt.xy );
        this.map.setCenter(newCenter, this.map.zoom + 1);
    },

    /**
    * @param {Event} evt
    */
    defaultMouseDown: function (evt) {
        this.mouseDragStart = evt.xy.copyOf();
        if (evt.shiftKey) {
            this.map.div.style.cursor = "crosshair";
            this.zoomBox = OpenLayers.Util.createDiv('zoomBox');
            this.zoomBox.style.border = '1px solid red';
            this.zoomBox.style.position="absolute";
            this.zoomBox.style.zIndex=1000;
            this.zoomBox.style.top=this.mouseDragStart.y;
            this.zoomBox.style.left=this.mouseDragStart.x;
            this.map.viewPortDiv.appendChild(this.zoomBox);
        } else {
            this.map.div.style.cursor = "move";
        }
        Event.stop(evt);
    },

    /**
    * @param {Event} evt
    */
    defaultMouseMove: function (evt) {
        if (this.mouseDragStart != null) {
            if (this.zoomBox) {
		if (!evt.shiftKey) {
		    this.defaultMouseUp(evt);
                    return;
                }
                var deltaX = Math.abs(this.mouseDragStart.x - evt.xy.x);
                var deltaY = Math.abs(this.mouseDragStart.y - evt.xy.y);
                this.zoomBox.style.width = deltaX+"px";
                this.zoomBox.style.height = deltaY+"px";
                if (evt.xy.x < this.mouseDragStart.x) {
                    this.zoomBox.style.left = evt.xy.x+"px";
                }
                if (evt.xy.y < this.mouseDragStart.y) {
                    this.zoomBox.style.top = evt.xy.y+"px";
                }
            } else {
                var deltaX = this.mouseDragStart.x - evt.xy.x;
                var deltaY = this.mouseDragStart.y - evt.xy.y;
                var size = this.map.getSize();
                var newXY = new OpenLayers.Pixel(size.w / 2 + deltaX,
                                                 size.h / 2 + deltaY);
                var newCenter = this.map.getLonLatFromPixel( newXY );
                this.map.setCenter(newCenter);
                this.mouseDragStart = evt.xy.copyOf();
            }
        }
    },

    /**
    * @param {Event} evt
    */
    defaultMouseUp: function (evt) {
        if (this.zoomBox) {
	    if (evt.shiftKey) {
		var start = this.map.getLonLatFromPixel( this.mouseDragStart );
		var end = this.map.getLonLatFromPixel( evt.xy );
		var top = Math.max(start.lat, end.lat);
		var bottom = Math.min(start.lat, end.lat);
		var left = Math.min(start.lon, end.lon);
		var right = Math.max(start.lon, end.lon);
		var bounds = new OpenLayers.Bounds(left, bottom, right, top);
		var zoom = this.map.getZoomForExtent(bounds);
		this.map.setCenter(new OpenLayers.LonLat(
		  (start.lon + end.lon) / 2,
		  (start.lat + end.lat) / 2
		 ), zoom);
            }
            this.map.viewPortDiv.removeChild(document.getElementById("zoomBox"));
            this.zoomBox = null;
        }
        this.mouseDragStart = null;
        this.map.div.style.cursor = "default";
    }

});

<|endoftext|>


<commit_before>'use strict';

var
  Promise = require('bluebird'),
  Deque = require('denque'),
  MemoryStorageController = require('./memoryStorageController'),
  WriteController = require('./writeController'),
  ReadController = require('./readController'),
  SubscribeController = require('./subscribeController'),
  BulkController = require('./bulkController'),
  AdminController = require('./adminController'),
  SecurityController = require('./securityController'),
  AuthController = require('./authController'),
  BadRequestError = require('kuzzle-common-objects').errors.BadRequestError,
  UnauthorizedError = require('kuzzle-common-objects').errors.UnauthorizedError,
  ForbiddenError = require('kuzzle-common-objects').errors.ForbiddenError,
  ServiceUnavailableError = require('kuzzle-common-objects').errors.ServiceUnavailableError,
  Request = require('kuzzle-common-objects').Request;

const MIN_TIME_BEFORE_DUMP_PREV_ERROR = 60000;

class CacheItem {
  constructor(request, callback) {
    this.request = request;
    this.callback = callback;
  }
}

/**
 * @property {object} controllers
 * @param {Kuzzle} kuzzle
 */
function FunnelController (kuzzle) {
  this.overloaded = false;
  this.concurrentRequests = 0;
  this.controllers = {};
  this.requestsCache = new Deque();
  this.cachedItems = 0;
  this.lastOverloadTime = 0;
  this.overloadWarned = false;
  this.lastWarningTime = 0;

  this.lastDumpedErrors = {};

  // used only for core-dump analysis
  this.pendingRequests = {};

  // used only for core-dump analysis
  this.requestHistory = new Deque();
  this.historized = 0;

  this.init = function funnelInit () {
    this.controllers.admin = new AdminController(kuzzle);
    this.controllers.auth = new AuthController(kuzzle);
    this.controllers.bulk = new BulkController(kuzzle);
    this.controllers.memoryStorage = this.controllers.ms = new MemoryStorageController(kuzzle);
    this.controllers.read = new ReadController(kuzzle);
    this.controllers.security = new SecurityController(kuzzle);
    this.controllers.subscribe = new SubscribeController(kuzzle);
    this.controllers.write = new WriteController(kuzzle);

    kuzzle.pluginsManager.injectControllers();
  };

  /**
   * Execute the right controller/action
   *
   * @param {Request} request
   * @param {Function} callback
   */
  this.execute = function funnelExecute (request, callback) {
    if (this.overloaded) {
      let now = Date.now();

      if ((this.cachedItems > kuzzle.config.server.warningRetainedRequestsLimit) && (this.lastWarningTime === 0 || this.lastWarningTime < now - 500)) {
        let overloadPercentage = Math.round(10000 * this.cachedItems / kuzzle.config.server.maxRetainedRequests) / 100;
        kuzzle.pluginsManager.trigger('server:overload', overloadPercentage);
        kuzzle.pluginsManager.trigger('log:warn', '[!WARNING!] Kuzzle overloaded: ' + overloadPercentage + '%. Delaying requests...');

        this.overloadWarned = true;
        this.lastWarningTime = now;
      }
    }

    // execute the request immediately if kuzzle is not overloaded
    if (this.concurrentRequests < kuzzle.config.server.maxConcurrentRequests) {
      this.concurrentRequests++;

      this.pendingRequests[request.id] = request;

      processRequest(kuzzle, this, request)
        .then(processResult => callback(null, processResult))
        .catch(err => {
          kuzzle.pluginsManager.trigger('log:error', err);

          request.setError(err);
          callback(err, request);

          this.handleErrorDump(err);

          return null;
        })
        .finally(() => {
          this.concurrentRequests--;
          delete this.pendingRequests[request.id];
        });

      return null;
    }

    if (this.cachedItems >= kuzzle.config.server.maxRetainedRequests) {
      const error = new ServiceUnavailableError('Request discarded: Kuzzle Server is temporarily overloaded');

      kuzzle.pluginsManager.trigger('log:error', error);
      request.setError(error);
      callback(error, request);
      return null;
    }

    this.cachedItems++;
    this.requestsCache.push(new CacheItem(request, callback));

    /*
     If kuzzle is overloaded, check the requests cache.
     There are two possibilities:
     1- the cache limit has not been reached. A warning is emitted, and the
     request is cached and will be played as soon as the maxConcurrentRequests
     property allows it

     2- the number of cached requests is equal to the maxRetainedRequests property.
     The request is then discarded and an error is returned to the sender
     */
    if (!this.overloaded) {
      this.overloaded = true;

      /*
       /!\ Invoking this function here with setTimeout() leads to V8 deoptimizing
       the entire funnelExecute method (as of node.js 6.9.1),
       because of an "out of bounds" heuristic error (caused by node's
       setTimeout code written in JS? this needs further investigations)

       We get better performances executing this function once for nothing each
       time we start overload mode by keeping this method optimized by crankshaft.
       */
      playCachedRequests(kuzzle, this);
    }
  };

  this.handleErrorDump = function funnelHandleErrorDump (err) {
    if (kuzzle.config.dump.enabled && kuzzle.config.dump.handledErrors.enabled) {
      setImmediate(() => {
        var
          lastSeen = Date.now(),
          request,
          errorType,
          errorMessage;

        errorType = typeof err === 'object' && err.name ? err.name : typeof err;

        if (kuzzle.config.dump.handledErrors.whitelist.indexOf(errorType) > -1) {
          request = new Request({
            controller: 'actions',
            action: 'dump',
            body: {}
          });

          // simplify error message to use it in folder dump name
          errorMessage = err.message;
          if (errorMessage.indexOf('\n') > -1) {
            errorMessage = errorMessage.split('\n')[0];
          }
          errorMessage = errorMessage.toLowerCase().replace(/[^a-zA-Z0-9-_]/g, '-').replace(/[-]+/g, '-').split('-');
          errorMessage = errorMessage.filter(value => value !== '').join('-');

          request.data.body.suffix = 'handled-'.concat(errorType.toLowerCase(), '-', errorMessage);

          if (!this.lastDumpedErrors[request.data.body.suffix] || this.lastDumpedErrors[request.data.body.suffix] < lastSeen - MIN_TIME_BEFORE_DUMP_PREV_ERROR) {
            kuzzle.cliController.actions.dump(request);
            this.lastDumpedErrors[request.data.body.suffix] = lastSeen;
          }
        }
      });
    }
  };
}

/**
 * Execute the request immediately
 * @param {Kuzzle} kuzzle
 * @param {FunnelController} funnel
 * @param {Request} request
 */
function processRequest(kuzzle, funnel, request) {
  var controllers = funnel.controllers;

  kuzzle.statistics.startRequest(request);

  if (funnel.historized > kuzzle.config.server.maxRequestHistorySize) {
    funnel.requestHistory.shift();
  }
  else {
    funnel.historized++;
  }

  funnel.requestHistory.push(request);

  if (
    !controllers[request.input.controller]
    || !controllers[request.input.controller][request.input.action]
    || typeof controllers[request.input.controller][request.input.action] !== 'function'
  ) {
    return Promise.reject(new BadRequestError(`No corresponding action ${request.input.action} in controller ${request.input.controller}`));
  }

  return kuzzle.repositories.token.verifyToken(request.input.jwt)
    .then(userToken => {
      request.context.token = userToken;
      return kuzzle.repositories.user.load(request.context.token.userId);
    })
    .then(user => user.isActionAllowed(request, kuzzle))
    .then(isAllowed => {
      var
        modifiedRequest,
        input = request.input,
        beforeEvent = getEventName(input.controller, 'before', input.action),
        afterEvent = getEventName(input.controller, 'after', input.action);

      if (!isAllowed) {
        // anonymous user => we throw a 401 (Unauthorised) error
        if (request.context.token.userId === -1) {
          return Promise.reject(new UnauthorizedError(
            `Unauthorized action [${input.index}/${input.collection}/${input.controller}/${input.action}] for anonymous user`)
          );
        }
        // logged-in user with insufficient permissions => we throw a 403 (Forbidden) error
        return Promise.reject(new ForbiddenError(
          `Forbidden action [${input.index}/${input.collection}/${input.controller}/${input.action}] for user ${request.context.token.userId}`)
        );
      }

      return kuzzle.pluginsManager.trigger(beforeEvent, request)
        .then(newRequest => {
          modifiedRequest = newRequest;

          return controllers[request.input.controller][request.input.action](newRequest);
        })
        .then(responseData => {
          modifiedRequest.setResult(responseData, request.status === 102 ? 200 : request.status);

          return kuzzle.pluginsManager.trigger(afterEvent, modifiedRequest);
        });
    })
    .then(newRequest => {
      kuzzle.statistics.completedRequest(request);

      return newRequest;
    })
    .catch(error => {
      kuzzle.statistics.failedRequest(request);
      return Promise.reject(error);
    });
}

/**
 * Background task. Checks if there are any requests in cache, and replay them
 * if Kuzzle is not overloaded anymore,
 *
 * @param kuzzle
 * @param {FunnelController} funnel
 */
function playCachedRequests(kuzzle, funnel) {
  // If there is room to play bufferized requests, do it now. If not, retry later
  let quantityToInject = funnel.cachedItems > 0 ?
    Math.min(funnel.cachedItems, kuzzle.config.server.maxConcurrentRequests - funnel.concurrentRequests)
    : 0;

  for(let i = 0; i < quantityToInject; i++) {
    let cachedItem = funnel.requestsCache.shift();
    funnel.execute(cachedItem.request, cachedItem.callback);
  }

  funnel.cachedItems -= quantityToInject;

  if (funnel.cachedItems > 0) {
    setTimeout(() => playCachedRequests(kuzzle, funnel), 0);
  } else {
    let now = Date.now();
    // No request remaining in cache => stop the background task and return to normal behavior
    funnel.overloaded = false;

    if (funnel.overloadWarned && (funnel.lastOverloadTime === 0 || funnel.lastOverloadTime < now - 500)) {
      funnel.overloadWarned = false;
      kuzzle.pluginsManager.trigger('log:info', 'End of overloaded state. Resuming normal activity.');
      funnel.lastOverloadTime = now;
    }
  }
}

function getEventName(controller, prefix, action) {
  return controller + ':' + prefix + capitalizeFirstLetter(action);
}

/**
 * @param {string} string
 * @returns {string}
 */
function capitalizeFirstLetter(string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
}

module.exports = FunnelController;
<commit_msg>fixed comment<commit_after>'use strict';

var
  Promise = require('bluebird'),
  Deque = require('denque'),
  MemoryStorageController = require('./memoryStorageController'),
  WriteController = require('./writeController'),
  ReadController = require('./readController'),
  SubscribeController = require('./subscribeController'),
  BulkController = require('./bulkController'),
  AdminController = require('./adminController'),
  SecurityController = require('./securityController'),
  AuthController = require('./authController'),
  BadRequestError = require('kuzzle-common-objects').errors.BadRequestError,
  UnauthorizedError = require('kuzzle-common-objects').errors.UnauthorizedError,
  ForbiddenError = require('kuzzle-common-objects').errors.ForbiddenError,
  ServiceUnavailableError = require('kuzzle-common-objects').errors.ServiceUnavailableError,
  Request = require('kuzzle-common-objects').Request;

const MIN_TIME_BEFORE_DUMP_PREV_ERROR = 60000;

class CacheItem {
  constructor(request, callback) {
    this.request = request;
    this.callback = callback;
  }
}

/**
 * @property {object} controllers
 * @param {Kuzzle} kuzzle
 */
function FunnelController (kuzzle) {
  this.overloaded = false;
  this.concurrentRequests = 0;
  this.controllers = {};
  this.requestsCache = new Deque();
  this.cachedItems = 0;
  this.lastOverloadTime = 0;
  this.overloadWarned = false;
  this.lastWarningTime = 0;

  this.lastDumpedErrors = {};

  // used only for core-dump analysis
  this.pendingRequests = {};

  // used only for core-dump analysis
  this.requestHistory = new Deque();
  this.historized = 0;

  this.init = function funnelInit () {
    this.controllers.admin = new AdminController(kuzzle);
    this.controllers.auth = new AuthController(kuzzle);
    this.controllers.bulk = new BulkController(kuzzle);
    this.controllers.memoryStorage = this.controllers.ms = new MemoryStorageController(kuzzle);
    this.controllers.read = new ReadController(kuzzle);
    this.controllers.security = new SecurityController(kuzzle);
    this.controllers.subscribe = new SubscribeController(kuzzle);
    this.controllers.write = new WriteController(kuzzle);

    kuzzle.pluginsManager.injectControllers();
  };

  /**
   * Execute the right controller/action
   *
   * @param {Request} request
   * @param {Function} callback
   */
  this.execute = function funnelExecute (request, callback) {
    if (this.overloaded) {
      let now = Date.now();

      if ((this.cachedItems > kuzzle.config.server.warningRetainedRequestsLimit) && (this.lastWarningTime === 0 || this.lastWarningTime < now - 500)) {
        let overloadPercentage = Math.round(10000 * this.cachedItems / kuzzle.config.server.maxRetainedRequests) / 100;
        kuzzle.pluginsManager.trigger('server:overload', overloadPercentage);
        kuzzle.pluginsManager.trigger('log:warn', '[!WARNING!] Kuzzle overloaded: ' + overloadPercentage + '%. Delaying requests...');

        this.overloadWarned = true;
        this.lastWarningTime = now;
      }
    }

    // execute the request immediately if kuzzle is not overloaded
    if (this.concurrentRequests < kuzzle.config.server.maxConcurrentRequests) {
      this.concurrentRequests++;

      this.pendingRequests[request.id] = request;

      processRequest(kuzzle, this, request)
        .then(processResult => callback(null, processResult))
        .catch(err => {
          kuzzle.pluginsManager.trigger('log:error', err);

          request.setError(err);
          callback(err, request);

          this.handleErrorDump(err);

          return null;
        })
        .finally(() => {
          this.concurrentRequests--;
          delete this.pendingRequests[request.id];
        });

      return null;
    }

    /*
     If kuzzle is overloaded, check the requests cache.
     There are two possibilities:

     1- the cache limit has not been reached: the request is cached
     and will be played as soon as the maxConcurrentRequests
     property allows it

     2- the number of cached requests is equal to the maxRetainedRequests property.
     The request is then discarded and an error is returned to the sender
     */
    if (this.cachedItems >= kuzzle.config.server.maxRetainedRequests) {
      const error = new ServiceUnavailableError('Request discarded: Kuzzle Server is temporarily overloaded');

      kuzzle.pluginsManager.trigger('log:error', error);
      request.setError(error);
      callback(error, request);
      return null;
    }

    this.cachedItems++;
    this.requestsCache.push(new CacheItem(request, callback));

    if (!this.overloaded) {
      this.overloaded = true;

      /*
       /!\ Invoking this function here with setTimeout() leads to V8 deoptimizing
       the entire funnelExecute method (as of node.js 6.9.1),
       because of an "out of bounds" heuristic error (caused by node's
       setTimeout code written in JS? this needs further investigations)

       We get better performances executing this function once for nothing each
       time we start overload mode by keeping this method optimized by crankshaft.
       */
      playCachedRequests(kuzzle, this);
    }
  };

  this.handleErrorDump = function funnelHandleErrorDump (err) {
    if (kuzzle.config.dump.enabled && kuzzle.config.dump.handledErrors.enabled) {
      setImmediate(() => {
        var
          lastSeen = Date.now(),
          request,
          errorType,
          errorMessage;

        errorType = typeof err === 'object' && err.name ? err.name : typeof err;

        if (kuzzle.config.dump.handledErrors.whitelist.indexOf(errorType) > -1) {
          request = new Request({
            controller: 'actions',
            action: 'dump',
            body: {}
          });

          // simplify error message to use it in folder dump name
          errorMessage = err.message;
          if (errorMessage.indexOf('\n') > -1) {
            errorMessage = errorMessage.split('\n')[0];
          }
          errorMessage = errorMessage.toLowerCase().replace(/[^a-zA-Z0-9-_]/g, '-').replace(/[-]+/g, '-').split('-');
          errorMessage = errorMessage.filter(value => value !== '').join('-');

          request.data.body.suffix = 'handled-'.concat(errorType.toLowerCase(), '-', errorMessage);

          if (!this.lastDumpedErrors[request.data.body.suffix] || this.lastDumpedErrors[request.data.body.suffix] < lastSeen - MIN_TIME_BEFORE_DUMP_PREV_ERROR) {
            kuzzle.cliController.actions.dump(request);
            this.lastDumpedErrors[request.data.body.suffix] = lastSeen;
          }
        }
      });
    }
  };
}

/**
 * Execute the request immediately
 * @param {Kuzzle} kuzzle
 * @param {FunnelController} funnel
 * @param {Request} request
 */
function processRequest(kuzzle, funnel, request) {
  var controllers = funnel.controllers;

  kuzzle.statistics.startRequest(request);

  if (funnel.historized > kuzzle.config.server.maxRequestHistorySize) {
    funnel.requestHistory.shift();
  }
  else {
    funnel.historized++;
  }

  funnel.requestHistory.push(request);

  if (
    !controllers[request.input.controller]
    || !controllers[request.input.controller][request.input.action]
    || typeof controllers[request.input.controller][request.input.action] !== 'function'
  ) {
    return Promise.reject(new BadRequestError(`No corresponding action ${request.input.action} in controller ${request.input.controller}`));
  }

  return kuzzle.repositories.token.verifyToken(request.input.jwt)
    .then(userToken => {
      request.context.token = userToken;
      return kuzzle.repositories.user.load(request.context.token.userId);
    })
    .then(user => user.isActionAllowed(request, kuzzle))
    .then(isAllowed => {
      var
        modifiedRequest,
        input = request.input,
        beforeEvent = getEventName(input.controller, 'before', input.action),
        afterEvent = getEventName(input.controller, 'after', input.action);

      if (!isAllowed) {
        // anonymous user => we throw a 401 (Unauthorised) error
        if (request.context.token.userId === -1) {
          return Promise.reject(new UnauthorizedError(
            `Unauthorized action [${input.index}/${input.collection}/${input.controller}/${input.action}] for anonymous user`)
          );
        }
        // logged-in user with insufficient permissions => we throw a 403 (Forbidden) error
        return Promise.reject(new ForbiddenError(
          `Forbidden action [${input.index}/${input.collection}/${input.controller}/${input.action}] for user ${request.context.token.userId}`)
        );
      }

      return kuzzle.pluginsManager.trigger(beforeEvent, request)
        .then(newRequest => {
          modifiedRequest = newRequest;

          return controllers[request.input.controller][request.input.action](newRequest);
        })
        .then(responseData => {
          modifiedRequest.setResult(responseData, request.status === 102 ? 200 : request.status);

          return kuzzle.pluginsManager.trigger(afterEvent, modifiedRequest);
        });
    })
    .then(newRequest => {
      kuzzle.statistics.completedRequest(request);

      return newRequest;
    })
    .catch(error => {
      kuzzle.statistics.failedRequest(request);
      return Promise.reject(error);
    });
}

/**
 * Background task. Checks if there are any requests in cache, and replay them
 * if Kuzzle is not overloaded anymore,
 *
 * @param kuzzle
 * @param {FunnelController} funnel
 */
function playCachedRequests(kuzzle, funnel) {
  // If there is room to play bufferized requests, do it now. If not, retry later
  let quantityToInject = funnel.cachedItems > 0 ?
    Math.min(funnel.cachedItems, kuzzle.config.server.maxConcurrentRequests - funnel.concurrentRequests)
    : 0;

  for(let i = 0; i < quantityToInject; i++) {
    let cachedItem = funnel.requestsCache.shift();
    funnel.execute(cachedItem.request, cachedItem.callback);
  }

  funnel.cachedItems -= quantityToInject;

  if (funnel.cachedItems > 0) {
    setTimeout(() => playCachedRequests(kuzzle, funnel), 0);
  } else {
    let now = Date.now();
    // No request remaining in cache => stop the background task and return to normal behavior
    funnel.overloaded = false;

    if (funnel.overloadWarned && (funnel.lastOverloadTime === 0 || funnel.lastOverloadTime < now - 500)) {
      funnel.overloadWarned = false;
      kuzzle.pluginsManager.trigger('log:info', 'End of overloaded state. Resuming normal activity.');
      funnel.lastOverloadTime = now;
    }
  }
}

function getEventName(controller, prefix, action) {
  return controller + ':' + prefix + capitalizeFirstLetter(action);
}

/**
 * @param {string} string
 * @returns {string}
 */
function capitalizeFirstLetter(string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
}

module.exports = FunnelController;
<|endoftext|>


<commit_before>var
    esPhinx;

(function($) {
    "use strict";

    var
        nodes = [],
        mappedListeners = {},

        mapped = function(node) {
            var
                index = nodes.indexOfEquivalence(node);

            return mappedListeners[index];
        },

        mapEventListener = function(node, eventName, runOnListener) {
            var
                index,
                mappedNode = mapped(node),
                map = {};

            if (runOnListener) {
                map[eventName] = [runOnListener];
                if (mappedNode) {
                    if (mappedNode[eventName]) {
                        mappedNode[eventName].push(runOnListener);
                    } else {
                        mappedNode[eventName] = map[eventName];
                    }
                    return mappedNode[eventName];
                } else {
                    nodes.push(node);
                    index = nodes.length - 1;
                    mappedListeners[index] = map;
                    return mappedListeners[index][eventName];
                }
            } else {
                if (mappedNode) {
                    return mappedNode[eventName];
                } else {
                    return [];
                }
            }
        },

        removeListener = function(node, eventName, runOnListener) {
            var
                mappedNode = mapped(node),
                callbacks = mappedNode[eventName];

            callbacks.delete(runOnListener);
        },

        removeListeners = function(node, eventName) {
            var
                mappedNode = mapped(node);

            delete mappedNode[eventName];
        },

        mapEach = function(eventName, runOnListener, callback) {
            var
                iteratorBlock = function(node) {
                    if (node instanceof window.Node || node == window ||
                        node == document) {
                        mapEventListener(node, eventName, runOnListener);
                        callback.call(node);
                    }
                };

            this.each(iteratorBlock);
        },

        // qual seria o evento neste caso, para, por exemplo, usar o stopPropagation?
        onChangeNode = function(runOnListener) {
            var
                added,
                self = this,

                callback = function(mutation) {
                    added = $(mutation.addedNodes).elements();
                    if (added.some()) {
                        runOnListener.call(self, added.asArray());
                    }
                },

                observeCallback = function(mutations) {
                    mutations.forEach(callback);

                };

            mapEach.call(self, "changeNode", runOnListener,
                         function() {
                            $(this).observe(observeCallback);
                        }
            );

        },

        // will see how to unbind the node event
        // offChangeNode = function(runOnListener) {
        //     // disconnect
        // },

        on = function(eventName, capture, runOnListener) {
            var
                cloned,
                runOnLoad,
                imgs,
                self = this,
                html = $("html"),
                clone = self.clone(true),

                callback = function(node) {
                    cloned = $(node);
                    cloned.hide();
                    html.prepend(node);

                    node.addEventListener(eventName, runOnLoad, capture);
                },

                iteratorBlock = function(node) {
                    node.removeEventListener(eventName, runOnLoad, capture);
                };

            if (typeof capture == "function") {
                runOnListener = capture;
                capture = false;
            } else if (typeof capture != "boolean") {
                capture = false;
            }

            switch (eventName) {
                case "changeNode":
                    return onChangeNode.call(self, runOnListener);
                case "load":
                    imgs = clone.find("img");
                    if (imgs.some()) {
                        clone = imgs;
                    }

                    runOnLoad = function(e) {
                        runOnListener.call(this, e);
                        html.remove(clone);

                        clone.each(iteratorBlock);
                    };

                    clone.each(callback);
                break;

                default:
                    mapEach.call(self, eventName, runOnListener,
                                 function() {
                        this.addEventListener(eventName, runOnListener,
                                              capture);
                    });
            }
        };

    $.prototype.extend(true, {

        events: function() {
            var
                mappedNode = mapped(this.asNode());

            if (mappedNode) {
                return Object.clone(mappedNode);
            }

            return {};
        },

        on: function(eventName, capture, runOnListener) {
            on.call(this, eventName, capture, runOnListener);

            return this;
        },

        off: function(eventName, capture, runOnListener) {
            var
                callback,
                node,

                iteratorBlock = function(runOnListener) {
                    var
                        booleanIteratorBlock = function(capture) {
                            node.removeEventListener(eventName, runOnListener,
                                                     capture);
                        };

                    [true, false].forEach(booleanIteratorBlock);
                    removeListeners(node, eventName);
                };

            if (typeof capture == "function") {
                runOnListener = capture;
                capture = false;
            } else if (typeof capture != "boolean") {
                capture = false;
            }

            if (runOnListener) {
                callback = function(n) {
                    node = n;
                    node.removeEventListener(eventName, runOnListener, capture);
                    removeListener(node, eventName, runOnListener);
                };
            } else {
                callback = function(n) {
                    node = n;
                    if (mapped(node)) {
                        mapEventListener(node, eventName)
                            .forEach(iteratorBlock);
                    }
                };
            }

            this.each(callback);

            return this;
        },

        attachedEvent: function(eventName) {
            return Object.hasAttribute(this.events(), eventName);
        }

    });

})(esPhinx);
<commit_msg>fix event map<commit_after>var
    esPhinx;

(function($) {
    "use strict";

    var
        nodes = [],
        mappedListeners = {},

        mapped = function(node) {
            var
                index = nodes.indexOfEquivalence(node);

            return mappedListeners[index];
        },

        mapEventListener = function(node, eventName, runOnListener) {
            var
                index,
                mappedNode = mapped(node),
                map = {};

            if (runOnListener) {
                map[eventName] = [runOnListener];
                if (mappedNode) {
                    if (mappedNode[eventName]) {
                        mappedNode[eventName].push(runOnListener);
                    } else {
                        mappedNode[eventName] = map[eventName];
                    }
                    return mappedNode[eventName];
                } else {
                    nodes.push(node);
                    index = nodes.length - 1;
                    mappedListeners[index] = map;
                    return mappedListeners[index][eventName];
                }
            } else {
                if (mappedNode && mappedNode[eventName]) {
                    return mappedNode[eventName];
                } else {
                    return [];
                }
            }
        },

        removeListener = function(node, eventName, runOnListener) {
            var
                mappedNode = mapped(node),
                callbacks = mappedNode[eventName];

            callbacks.delete(runOnListener);
        },

        removeListeners = function(node, eventName) {
            var
                mappedNode = mapped(node);

            delete mappedNode[eventName];
        },

        mapEach = function(eventName, runOnListener, callback) {
            var
                iteratorBlock = function(node) {
                    if (node instanceof window.Node || node == window ||
                        node == document) {
                        mapEventListener(node, eventName, runOnListener);
                        callback.call(node);
                    }
                };

            this.each(iteratorBlock);
        },

        // qual seria o evento neste caso, para, por exemplo, usar o stopPropagation?
        onChangeNode = function(runOnListener) {
            var
                added,
                self = this,

                callback = function(mutation) {
                    added = $(mutation.addedNodes).elements();
                    if (added.some()) {
                        runOnListener.call(self, added.asArray());
                    }
                },

                observeCallback = function(mutations) {
                    mutations.forEach(callback);

                };

            mapEach.call(self, "changeNode", runOnListener,
                         function() {
                            $(this).observe(observeCallback);
                        }
            );

        },

        // will see how to unbind the node event
        // offChangeNode = function(runOnListener) {
        //     // disconnect
        // },

        on = function(eventName, capture, runOnListener) {
            var
                cloned,
                runOnLoad,
                imgs,
                self = this,
                html = $("html"),
                clone = self.clone(true),

                callback = function(node) {
                    cloned = $(node);
                    cloned.hide();
                    html.prepend(node);

                    node.addEventListener(eventName, runOnLoad, capture);
                },

                iteratorBlock = function(node) {
                    node.removeEventListener(eventName, runOnLoad, capture);
                };

            if (typeof capture == "function") {
                runOnListener = capture;
                capture = false;
            } else if (typeof capture != "boolean") {
                capture = false;
            }

            switch (eventName) {
                case "changeNode":
                    return onChangeNode.call(self, runOnListener);
                case "load":
                    imgs = clone.find("img");
                    if (imgs.some()) {
                        clone = imgs;
                    }

                    runOnLoad = function(e) {
                        runOnListener.call(this, e);
                        html.remove(clone);

                        clone.each(iteratorBlock);
                    };

                    clone.each(callback);
                break;

                default:
                    mapEach.call(self, eventName, runOnListener,
                                 function() {
                        this.addEventListener(eventName, runOnListener,
                                              capture);
                    });
            }
        };

    $.prototype.extend(true, {

        events: function() {
            var
                mappedNode = mapped(this.asNode());

            if (mappedNode) {
                return Object.clone(mappedNode);
            }

            return {};
        },

        on: function(eventName, capture, runOnListener) {
            on.call(this, eventName, capture, runOnListener);

            return this;
        },

        off: function(eventName, capture, runOnListener) {
            var
                callback,
                node,

                iteratorBlock = function(runOnListener) {
                    var
                        booleanIteratorBlock = function(capture) {
                            node.removeEventListener(eventName, runOnListener,
                                                     capture);
                        };

                    [true, false].forEach(booleanIteratorBlock);
                    removeListeners(node, eventName);
                };

            if (typeof capture == "function") {
                runOnListener = capture;
                capture = false;
            } else if (typeof capture != "boolean") {
                capture = false;
            }

            if (runOnListener) {
                callback = function(n) {
                    node = n;
                    node.removeEventListener(eventName, runOnListener, capture);
                    removeListener(node, eventName, runOnListener);
                };
            } else {
                callback = function(n) {
                    node = n;
                    if (mapped(node)) {
                        // debugger
                        mapEventListener(node, eventName)
                            .forEach(iteratorBlock);
                    }
                };
            }

            this.each(callback);

            return this;
        },

        attachedEvent: function(eventName) {
            return Object.hasAttribute(this.events(), eventName);
        }

    });

})(esPhinx);
<|endoftext|>


<commit_before>var
    esPhinx;

(function($) {
    "use strict";

    $.prototype.extend({

        each: function(callback) {
            $($.each(this, callback));
        },

        selectEach: function(callback) {
            // delegate
            return $($.select(this, callback));
        },

        selectInBreadth: function(callback) {
            return $($.selectInBreadth(this, callback));
        },

        filterText: function(text) {
            var
                callback = function(node) {
                    return $(node).text().trim() == text.trim();
                };

            return this.selectInBreadth(callback);
        },

        asArray: function() {
            return Array.from(this);
        },

        includes: function(nodes) {
            var
                item,
                self = this,
                items = Array.from(arguments).uniq(),
                count = 0,

                callback = function(node) {
                    if (node.isEqualNode(item)) {
                        count++;
                    }
                },

                itemsIteratorBlock = function(i) {
                    item = i;
                    self.each(callback);
                };

            items.forEach(itemsIteratorBlock);

            return count >= items.length;
        },

        sort: function(compareFunction) {
            return $($.Collection.new(this).sort(compareFunction));
        },

        orderTextNodeByAsc: function() {
            var
                callback = function(node1, node2) {
                    return $(node1).text() > $(node2).text();
                };

            return this.sort(callback);
        },

        orderTextNodeByDesc: function() {
            var
                callback = function(node1, node2) {
                    return $(node1).text() < $(node2).text();
                };

            return this.sort(callback);
        },

        push: function() {
            var
                index,
                mainReference = this,

                callback = function(node) {
                    index = mainReference.lastIndex() + 1;
                    mainReference[index] = node;
                };

            Array.from(arguments).forEach(callback);

            this.length = Object.count(this);

            return this;
        },

        concat: function(replace) {
            var
                concatened,
                args = Array.from(arguments),

                collectionIteratorBlock = function(node) {
                    concatened.push(node);
                },

                callback = function(collection) {
                    collection = Array.from(collection);
                    collection.forEach(collectionIteratorBlock);
                };

            if (typeof replace == "boolean" && replace) {
                concatened = this;
                args = args.slice(1, args.length);
            } else {
                concatened = this.copy();
            }

            args.forEach(callback);

            return concatened;
        },

        elements: function() {
            var
                elements = $(),

                callback = function(node) {
                    if ($(node).isA(window.Element)) {
                        elements.push(node);
                    }
                };

            this.each(callback);

            return elements;
        },

        some: function() {
            return this.length;
        },

        firstNode: function() {
            var
                childNodes,
                firstNodes = $(),

                callback = function(node) {
                    childNodes = $(node).childNodes();
                    if (childNodes.some()) {
                        firstNodes.push(childNodes.asNode());
                    }
                };

            this.each(callback);

            return firstNodes;
        },

        firstElement: function() {
            var
                childElements,
                firstElements = $(),

                callback = function(node) {
                    childElements = $(node).childElements();
                    if (childElements.some()) {
                        firstElements.push(childElements.asNode());
                    }
                };

            this.each(callback);

            return firstElements;
        },

        previous: function(filter) {
            var
                query,
                sibling,
                siblings = $(),

                siblingsIteratorBlock = function(node) {
                    return $(node).is(query);
                },

                callback = function(node) {
                    sibling = node.previousElementSibling;
                    if (sibling && sibling instanceof window.Node) {
                        siblings.push(sibling);
                    }
                };

            if (filter) {
                query = this.parent().find(filter);

                if (query.some()) {
                    siblings = this.previousSiblings()
                        .filter(siblingsIteratorBlock);
                }
            } else {
                this.each(callback);
            }

            return siblings;
        },

        next: function(filter) {
            var
                query,
                sibling,
                siblings = $(),

                siblingsIteratorBlock = function(node) {
                    return $(node).is(query);
                },

                callback = function(node) {
                    sibling = node.nextSibling;
                    if (sibling && sibling instanceof window.Node) {
                        siblings.push(sibling);
                    }
                };

            if (filter) {
                query = this.parent().find(filter);

                if (query.some()) {
                    siblings = this.nextSiblings()
                        .filter(siblingsIteratorBlock);
                }
            } else {
                this.each(callback);
            }

            return siblings;
        },

        asNode: function() {
            if (this.some()) {
                return this.first()[0];
            }
            return null;
        },

        count: function() {
            return this.length;
        },

        find: function(query) {
            return $(query, this);
        },

        filter: function(callback) {
            var
                self = this,
                filtered = $(),

                iteratorBlock = function(node, i) {
                    // if (callback.call($(node), node, i, this)) {
                    if (callback.call(self, node, i)) {
                        filtered.push(node);
                    }
                };

            this.each(iteratorBlock);

            return filtered;
        },

        filterInBreadth: function(callback) {
            var
                filtered = $(),

                iteratorBlock = function(node, i) {
                    if (callback.call($(node), node, i, this)) {
                        filtered.push(node);
                    }
                };

            this.selectInBreadth(iteratorBlock);

            return filtered;
        },

        clone: function(copyChildren) {
            if (typeof copyChildren != "boolean")  { copyChildren = false; }

            var
                cloned = $(),

                callback = function(node) {
                    if (node instanceof window.Element) {
                        cloned.push(node.cloneNode(copyChildren));
                    }
                };

            this.each(callback);

            return cloned;
        },

        copy: function() {
            var
                copy = $();

            Object.assign(copy, this);
            copy.length = Object.count(copy);

            return copy;
        },

        first: function() {
            return $(this[0]);
        },

        last: function() {
            return $(this[this.lastIndex()]);
        },

        asString: function() {
            var
                string = "",

                callback = function(node) {
                    if (node instanceof window.Element) {
                        string += node.outerHTML + "\n";
                    } else if (node instanceof window.Text) {
                        string += node.wholeText + "\n";
                    }
                };

            this.each(callback);

            return string;
        },

        findHasNotAttr: function(query, attr) {
            return this.find(query + ":not([" + attr + "])");
        },

        findByAttr: function(query, attr, value) {
            return this.find(query + "[" + attr + "=\"" + value + "\"]");
        },

        textContentsAsArray: function() {
            var
                array = [],

                callback = function(node) {
                    array.push($(node).text().trim());
                };

            this.each(callback);

            return array;
        },

        item: function(index) {
            return $(this[index]);
        }

    });

}(esPhinx));
<commit_msg>reorganize functions<commit_after>var
    esPhinx;

(function($) {
    "use strict";

    $.prototype.extend({

        each: function(callback) {
            $($.each(this, callback));
        },

        selectEach: function(callback) {
            // delegate
            return $($.select(this, callback));
        },

        selectInBreadth: function(callback) {
            return $($.selectInBreadth(this, callback));
        },

        filter: function(callback) {
            var
                self = this,
                filtered = $(),

                iteratorBlock = function(node, i) {
                    // if (callback.call($(node), node, i, this)) {
                    if (callback.call(self, node, i)) {
                        filtered.push(node);
                    }
                };

            this.each(iteratorBlock);

            return filtered;
        },

        filterInBreadth: function(callback) {
            var
                filtered = $(),

                iteratorBlock = function(node, i) {
                    if (callback.call($(node), node, i, this)) {
                        filtered.push(node);
                    }
                };

            this.selectInBreadth(iteratorBlock);

            return filtered;
        },

        filterText: function(text) {
            var
                callback = function(node) {
                    return $(node).text().trim() == text.trim();
                };

            return this.selectInBreadth(callback);
        },

        asArray: function() {
            return Array.from(this);
        },

        includes: function(nodes) {
            var
                item,
                self = this,
                items = Array.from(arguments).uniq(),
                count = 0,

                callback = function(node) {
                    if (node.isEqualNode(item)) {
                        count++;
                    }
                },

                itemsIteratorBlock = function(i) {
                    item = i;
                    self.each(callback);
                };

            items.forEach(itemsIteratorBlock);

            return count >= items.length;
        },

        sort: function(compareFunction) {
            return $($.Collection.new(this).sort(compareFunction));
        },

        orderTextNodeByAsc: function() {
            var
                callback = function(node1, node2) {
                    return $(node1).text() > $(node2).text();
                };

            return this.sort(callback);
        },

        orderTextNodeByDesc: function() {
            var
                callback = function(node1, node2) {
                    return $(node1).text() < $(node2).text();
                };

            return this.sort(callback);
        },

        push: function() {
            var
                index,
                mainReference = this,

                callback = function(node) {
                    index = mainReference.lastIndex() + 1;
                    mainReference[index] = node;
                };

            Array.from(arguments).forEach(callback);

            this.length = Object.count(this);

            return this;
        },

        concat: function(replace) {
            var
                concatened,
                args = Array.from(arguments),

                collectionIteratorBlock = function(node) {
                    concatened.push(node);
                },

                callback = function(collection) {
                    collection = Array.from(collection);
                    collection.forEach(collectionIteratorBlock);
                };

            if (typeof replace == "boolean" && replace) {
                concatened = this;
                args = args.slice(1, args.length);
            } else {
                concatened = this.copy();
            }

            args.forEach(callback);

            return concatened;
        },

        elements: function() {
            var
                elements = $(),

                callback = function(node) {
                    if ($(node).isA(window.Element)) {
                        elements.push(node);
                    }
                };

            this.each(callback);

            return elements;
        },

        some: function() {
            return this.length;
        },

        firstNode: function() {
            var
                childNodes,
                firstNodes = $(),

                callback = function(node) {
                    childNodes = $(node).childNodes();
                    if (childNodes.some()) {
                        firstNodes.push(childNodes.asNode());
                    }
                };

            this.each(callback);

            return firstNodes;
        },

        firstElement: function() {
            var
                childElements,
                firstElements = $(),

                callback = function(node) {
                    childElements = $(node).childElements();
                    if (childElements.some()) {
                        firstElements.push(childElements.asNode());
                    }
                };

            this.each(callback);

            return firstElements;
        },

        previous: function(filter) {
            var
                query,
                sibling,
                siblings = $(),

                siblingsIteratorBlock = function(node) {
                    return $(node).is(query);
                },

                callback = function(node) {
                    sibling = node.previousElementSibling;
                    if (sibling && sibling instanceof window.Node) {
                        siblings.push(sibling);
                    }
                };

            if (filter) {
                query = this.parent().find(filter);

                if (query.some()) {
                    siblings = this.previousSiblings()
                        .filter(siblingsIteratorBlock);
                }
            } else {
                this.each(callback);
            }

            return siblings;
        },

        next: function(filter) {
            var
                query,
                sibling,
                siblings = $(),

                siblingsIteratorBlock = function(node) {
                    return $(node).is(query);
                },

                callback = function(node) {
                    sibling = node.nextSibling;
                    if (sibling && sibling instanceof window.Node) {
                        siblings.push(sibling);
                    }
                };

            if (filter) {
                query = this.parent().find(filter);

                if (query.some()) {
                    siblings = this.nextSiblings()
                        .filter(siblingsIteratorBlock);
                }
            } else {
                this.each(callback);
            }

            return siblings;
        },

        asNode: function() {
            if (this.some()) {
                return this.first()[0];
            }
            return null;
        },

        count: function() {
            return this.length;
        },

        find: function(query) {
            return $(query, this);
        },

        clone: function(copyChildren) {
            if (typeof copyChildren != "boolean")  { copyChildren = false; }

            var
                cloned = $(),

                callback = function(node) {
                    if (node instanceof window.Element) {
                        cloned.push(node.cloneNode(copyChildren));
                    }
                };

            this.each(callback);

            return cloned;
        },

        copy: function() {
            var
                copy = $();

            Object.assign(copy, this);
            copy.length = Object.count(copy);

            return copy;
        },

        first: function() {
            return $(this[0]);
        },

        last: function() {
            return $(this[this.lastIndex()]);
        },

        asString: function() {
            var
                string = "",

                callback = function(node) {
                    if (node instanceof window.Element) {
                        string += node.outerHTML + "\n";
                    } else if (node instanceof window.Text) {
                        string += node.wholeText + "\n";
                    }
                };

            this.each(callback);

            return string;
        },

        findHasNotAttr: function(query, attr) {
            return this.find(query + ":not([" + attr + "])");
        },

        findByAttr: function(query, attr, value) {
            return this.find(query + "[" + attr + "=\"" + value + "\"]");
        },

        textContentsAsArray: function() {
            var
                array = [],

                callback = function(node) {
                    array.push($(node).text().trim());
                };

            this.each(callback);

            return array;
        },

        item: function(index) {
            return $(this[index]);
        }

    });

}(esPhinx));
<|endoftext|>


<commit_before>var OptionButton=function(){
    this.routeNew='_admin_inscripcion_new';
    this.routeSave='_admin_inscripcion_save';
    this.WizardIndex=0;

}
OptionButton.prototype={
    ValidateTerminos:function(){
        var terminos=$("#chkTerminos").is(':checked');
        if(terminos){
            $("#btn-inscripcion-save").removeClass("disabled");
        }else{
            $("#btn-inscripcion-save").addClass("disabled");
        }

    },
    ActiveWizard:function(index){
        for (var i = 1; i <= 3; i++) {
             $("#wizard"+i).removeClass('active');
             $("#wizard"+i).addClass('disabled');
        };
        $("#wizard"+(index+1)).addClass('active');
         $("#wizard"+(index+1)).removeClass('disabled');
        $('#tabWizard li:eq('+index+') a').tab('show');
    },
    NextWizard:function(){
        var terminos=$("#chkTerminos").is(':checked');
        console.log(terminos);
        this.WizardIndex++;
        if(terminos){

            switch(this.WizardIndex){
                case 0:
                    $("#btn-inscripcion-save").html("Continuar");
                    this.ActiveWizard(0);
                    break;
                case 1:
                    $("#btn-inscripcion-save").html("Inscribirme");
                    this.ActiveWizard(1);
                    break;
                case 2:
                    this.Save();
                    $("#btn-inscripcion-save").html("Finalizar");
                    this.ActiveWizard(2);
                    break;
                case 3:
                    this.Window.Hide();
                    setTimeout(this.Refresh,2000,this.idConcurso);
                    break;
            }
        }

    },
    New:function(id){
        this.idConcurso=id;
        this.WizardIndex=0;
        this.Window=new BootstrapWindow({id:"winForm",title:"Nueva Inscripción"});
        this.Window.setWidth(1000);
        //this.Window.setHeight(300);
        var url=Routing.generate(this.routeNew,{id:id});
        this.Window.Load(url,"");
        this.Window.Show();
         var parent=this;
        this.Window.AddButton('btn-inscripcion-cancel',{
            label:'Cancelar',
            'class':'btn-default',
            fn:function(){

                parent.Window.Hide();
                setTimeout(parent.Refresh,2000,parent.idConcurso);
            }

        })

        this.Window.AddButton('btn-inscripcion-save',{
            label:'Continuar',
            'class':'btn-success',
            fn:function(){
                parent.NextWizard();
                //parent.Window.Hide();
            }
        });
         $("#btn-inscripcion-save").addClass("disabled");

    },
    Save:function(){
            var parent=this;
            var url=Routing.generate(this.routeSave,{id:this.idConcurso});
            params = $('#myform').serializeObject();
            console.log(params);

            $.ajax({
                    type:'POST',
                    url:url,
                    data:params,
                    dataType:"html",
                    success:function(datos){
                            //parent.Refresh();
                            //parent.Window.AddHTML(datos);
                            //new OptionButton().Refresh();
                    },
                    error:function(objeto, quepaso, otroobj){

                    }
            });

    },
    Refresh:function(idConcurso){
        new Concurso().Detail(idConcurso);
    }
}

$(document).ready(function() {

  $("button[data-type='inscripcion']").click(function(){
    var url=Routing.generate("_admin_concurso_showInscripcion");
    new jAjax().Load(url,"main-body","GET","","")
});

});<commit_msg>se corrigio inscripcion de postulante<commit_after>var OptionButton=function(){
    this.routeNew='_admin_inscripcion_new';
    this.routeSave='_admin_inscripcion_save';
    this.WizardIndex=0;

}
OptionButton.prototype={
    ValidateTerminos:function(){
        var terminos=$("#chkTerminos").is(':checked');
        if(terminos){
            $("#btn-inscripcion-save").removeClass("disabled");
        }else{
            $("#btn-inscripcion-save").addClass("disabled");
        }

    },
    ActiveWizard:function(index){
        for (var i = 1; i <= 3; i++) {
             $("#wizard"+i).removeClass('active');
             $("#wizard"+i).addClass('disabled');
        };
        $("#wizard"+(index+1)).addClass('active');
         $("#wizard"+(index+1)).removeClass('disabled');
        $('#tabWizard li:eq('+index+') a').tab('show');
    },
    NextWizard:function(){
        var terminos=$("#chkTerminos").is(':checked');
        console.log(terminos);
        this.WizardIndex++;
        if(terminos){

            switch(this.WizardIndex){
                case 0:
                    $("#btn-inscripcion-save").html("Continuar");
                    this.ActiveWizard(0);
                    break;
                case 1:
                    $("#btn-inscripcion-save").html("Inscribirme");
                    this.ActiveWizard(1);
                    break;
                case 2:
                    this.Save();
                    $("#btn-inscripcion-save").html("Finalizar");
                    this.ActiveWizard(2);
                    break;
                case 3:
                    this.Window.Hide();
                    setTimeout(this.Refresh,2000,this.idConcurso);
                    break;
            }
        }

    },
    New:function(id){
        this.idConcurso=id;
        this.WizardIndex=0;
        this.Window=new BootstrapWindow({id:"winForm",title:"Nueva Inscripción"});
        this.Window.setWidth(1000);
        //this.Window.setHeight(300);
        var url=Routing.generate(this.routeNew,{id:id});
        this.Window.Load(url,"");
        this.Window.Show();
         var parent=this;
        this.Window.AddButton('btn-inscripcion-cancel',{
            label:'Cancelar',
            'class':'btn-default',
            fn:function(){

                parent.Window.Hide();
                if(parent.WizardIndex>0)
                    setTimeout(parent.Refresh,2000,parent.idConcurso);
            }

        })

        this.Window.AddButton('btn-inscripcion-save',{
            label:'Continuar',
            'class':'btn-success',
            fn:function(){
                parent.NextWizard();
                //parent.Window.Hide();
            }
        });
         $("#btn-inscripcion-save").addClass("disabled");

    },
    Save:function(){
            var parent=this;
            var url=Routing.generate(this.routeSave,{id:this.idConcurso});
            params = $('#myform').serializeObject();
            console.log(params);

            $.ajax({
                    type:'POST',
                    url:url,
                    data:params,
                    dataType:"html",
                    success:function(datos){
                            //parent.Refresh();
                            //parent.Window.AddHTML(datos);
                            //new OptionButton().Refresh();
                    },
                    error:function(objeto, quepaso, otroobj){

                    }
            });

    },
    Refresh:function(idConcurso){
        new Concurso().Detail(idConcurso);
    }
}

$(document).ready(function() {

  $("button[data-type='inscripcion']").click(function(){
    var url=Routing.generate("_admin_concurso_showInscripcion");
    new jAjax().Load(url,"main-body","GET","","")
});

});<|endoftext|>


<commit_before>// Inject info about users to env (~ manual join)
//
"use strict";

var _ = require('lodash');

var users_in_fields = [
  '_id',
  'hid',
  '_uname',
  '_uname_short'
];

module.exports = function (N) {

  // fetch and prepare users info
  // fired after each controllers
  // list of user id should be prepared in controller
  N.wire.after('server:*', { priority: 50 }, function users_join(env, callback) {
    var user_id_list, result, UserModel;

    if (!_.isArray(env.data.users) || !env.data.users.length) {
      callback();
      return;
    }

    // There can be some garbage:
    // - empty ids (just because we push data without checks)
    // - duplicated ids(the same users from different objects)
    //
    // We remove dummy elements, but let mongo filter unique values,
    // because it's more fast.
    user_id_list = _.compact(env.data.users);

    env.extras.puncher.start('Users join', { count: user_id_list.length });

    result = env.response.data.users = {};

    // uncomment to imitate empty users (to check template & speed)
    //    env.extras.puncher.stop();
    //    return callback();

    UserModel = N.models.users.User;

    UserModel
        .where('_id').in(user_id_list)
        .select(users_in_fields.join(' '))
        .setOptions({ lean: true }).exec(function (err, user_list) {

      user_list.forEach(function (user) {
        // only registered users can see full name
        if (!env.runtime.is_member) {
          user._uname = user._uname_short;
        }

        result[user._id] = user;
      });

      env.extras.puncher.stop();

      callback();
    });
  });
};
<commit_msg>Protected from duplicated users join on subcalls & code cleanup<commit_after>// Inject info about users to env (~ manual join)
//
"use strict";

var _ = require('lodash');

var user_fields = [
  '_id',
  'hid',
  '_uname',
  '_uname_short'
];

module.exports = function (N) {

  // fetch and prepare users info
  // fired after each controllers
  // list of user id should be prepared in controller
  N.wire.after('server:*', { priority: 50 }, function users_join(env, callback) {

    if (!_.isArray(env.data.users) || !env.data.users.length) {
      callback();
      return;
    }

    // There can be some garbage:
    // - empty ids (just because we push data without checks)
    // - duplicated ids(the same users from different objects)
    //
    // We remove dummy elements, but let mongo filter unique values,
    // because it's more fast.
    var user_ids = _.compact(env.data.users);

    env.extras.puncher.start('Users join', { count: user_ids.length });

    env.response.data.users = env.response.data.users || {};

    // uncomment to imitate empty users (to check template & speed)
    //    env.extras.puncher.stop();
    //    return callback();

    N.models.users.User
      .where('_id').in(user_ids)
      .select(user_fields.join(' '))
      .setOptions({ lean: true })
      .exec(function (err, user_list) {

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

      user_list.forEach(function (user) {
        // only registered users can see full name
        if (!env.runtime.is_member) {
          user._uname = user._uname_short;
        }

        env.response.data.users[user._id] = user;
      });

      env.extras.puncher.stop();

      // reset pending list to avoid multiple joins on server subrequests
      env.data.users = [];

      callback();
    });
  });
};
<|endoftext|>


<commit_before>'use strict';

angular.module('dmpApp')
  .controller('SchemaCtrl', ['$scope', '$http', 'schemaParser', '$q', function ($scope, $http, schemaParser, $q) {
    $scope.internalName = 'Source Target Schema Mapper'

    $scope.sourceSchema = {};
    $scope.targetSchema = {};

    var sourceSchema = $http.get('/data/schema.json')
        , targetSchema = $http.get('/data/targetschema.json')
        , allPromise = $q.all([sourceSchema, targetSchema]);

    allPromise.then(function (result) {
        var sourceSchema = result[0]['data']
            , targetSchema = result[1]['data'];

        $scope.sourceSchema = schemaParser.mapData(sourceSchema['title'], sourceSchema);
        $scope.targetSchema = schemaParser.mapData(targetSchema['title'], targetSchema);

    });

  }]);
<commit_msg>add target schema to schema mapper & update test<commit_after>'use strict';

angular.module('dmpApp')
  .controller('SchemaCtrl', ['$scope', '$http', 'schemaParser', '$q', function ($scope, $http, schemaParser, $q) {
    $scope.internalName = 'Source Target Schema Mapper'

    $scope.sourceSchema = {};
    $scope.targetSchema = {};

    var sourceSchema = $http.get('/data/schema.json')
        , targetSchema = $http.get('/data/targetschema.json')
        , allPromise = $q.all([sourceSchema, targetSchema]);

    allPromise.then(function (result) {
        var sourceSchema = result[0]['data']
            , targetSchema = result[1]['data'];

        $scope.sourceSchema = schemaParser.mapData(sourceSchema['title'], sourceSchema);
        $scope.targetSchema = schemaParser.mapData(targetSchema['title'], targetSchema);

    });
  }]);
<|endoftext|>