<commit_before>angular.module('auction')
  .factory('AuctionUtils', ['$filter', '$timeout', '$log', '$window', function ($filter, $timeout, $log, $window) {
    // Format msg for timer
    'use strict';
    function pad(d) {
        return (d < 10) ? '0' + d.toString() : d.toString();
    }

    function prepare_info_timer_data(current_time, auction, bidder_id, Rounds) {
      var i;
      if (auction.current_stage === -100) {
        return {
          'countdown': false,
          'start_time': true,
          'msg': 'Tender cancelled'
        };
      }
      if (auction.current_stage === -1) {
        return {
          'countdown': ((new Date(auction.stages[0].start) - current_time) / 1000),
          'start_time': false,
          'msg': 'until the auction starts'
        };
      }
      if (auction.current_stage === (auction.stages.length - 1)) {
        var client_time = new Date();
        var ends_time = new Date(auction.stages[auction.current_stage].start);
        if (client_time < ends_time) {
          ends_time = client_time;
        }
        return {
          'countdown': false,
          'start_time': ends_time,
          'msg': 'Аuction was completed'
        };
      }
      if (bidder_id) {
        if (auction.stages[auction.current_stage].bidder_id === bidder_id) {
          return {
            'countdown': ((new Date(auction.stages[auction.current_stage + 1].start) - current_time) / 1000),
            'start_time': false,
            'msg': 'until your turn ends'
          };
        }
        var all_rounds = Rounds.concat(auction.stages.length - 1);
        for (i in all_rounds) {
          if (auction.current_stage < all_rounds[i]) {
            for (var index = auction.current_stage; index <= all_rounds[i]; index++) {
              if ((auction.stages[index].bidder_id) && (auction.stages[index].bidder_id === bidder_id)) {
                return {
                  'countdown': ((new Date(auction.stages[index].start) - current_time) / 1000),
                  'start_time': false,
                  'msg': 'until your turn'
                };
              }
            }
            break;
          }
        }
      }
      for (i in Rounds) {
        if (auction.current_stage == Rounds[i]) {
          return {
            'countdown': ((new Date(auction.stages[auction.current_stage + 1].start) - current_time) / 1000),
            'start_time': false,
            'msg': 'until the round starts'
          };
        }
        if (auction.current_stage < Rounds[i]) {
          return {
            'countdown': ((new Date(auction.stages[Rounds[i]].start) - current_time) / 1000),
            'start_time': false,
            'msg': 'until the round ends'
          };
        }
      }
      if (auction.current_stage < (auction.stages.length - 1)) {
        return {
          'countdown': ((new Date(auction.stages[auction.stages.length - 1].start) - current_time) / 1000),
          'start_time': false,
          'msg': 'until the results announcement'
        };
      }
    }

    function prepare_progress_timer_data(current_time, auction) {
      if ((auction.current_stage === (auction.stages.length - 1))||(auction.current_stage === -100)) {
        return {
          'countdown_seconds': false,
          'rounds_seconds': 0,
        };
      }
      if (auction.current_stage === -1) {
        return {
          'countdown_seconds': ((new Date(auction.stages[0].start) - current_time) / 1000),
          'rounds_seconds': ((new Date(auction.stages[0].start) - current_time) / 1000),
        };
      }
      return {
        'countdown_seconds': ((new Date(auction.stages[auction.current_stage + 1].start) - current_time) / 1000),
        'rounds_seconds': ((new Date(auction.stages[auction.current_stage + 1].start) - new Date(auction.stages[auction.current_stage].start)) / 1000),
      };

    }

    function prepare_title_ending_data(auction, lang) {
      var ending = auction.tenderID + " - " + (auction['title_'+ lang]||auction['title']||auction['title_en']||auction['title_ru']||"");
      ending += " - ";
      ending += auction.procuringEntity['name_'+ lang]||auction.procuringEntity['name']||auction.procuringEntity['name_en']||auction.procuringEntity['name_ru']||"";
      return ending;
    }
      // Get bidder_id from query
    function get_bidder_id() {
      var query = window.location.search.substring(1);
      var vars = query.split('&');
      for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split('=');
        if (decodeURIComponent(pair[0]) == 'bidder_id') {
          return decodeURIComponent(pair[1]);
        }
      }
    }
      // Format date with traslations
    function format_date(date, lang, format) {
      var temp_date = moment(date).locale(lang);
      if (typeof temp_date.format === 'function'){
        return temp_date.format(format);
      }
      return "";
    }

    // Get round data
    function get_round_data(pause_index, auction_doc, Rounds) {
        if (pause_index == -1){
          return {
            'type': 'waiting'
          };
        }
        if (pause_index <= Rounds[0]) {
          return {
            'type': 'pause',
            'data': ['', '1', ]
          };
        }
        for (var i in Rounds) {
          if (pause_index < Rounds[i]) {
            return {
              'type': 'round',
              'data': parseInt(i)
            };
          } else if (pause_index == Rounds[i]) {
            return {
              'type': 'pause',
              'data': [(parseInt(i)).toString(), (parseInt(i) + 1).toString(), ]
            };
          }
        }

        if (pause_index < (auction_doc.stages.length - 1)) {
          return {
            'type': 'round',
            'data': Rounds.length
          };
        } else {
          return {
            'type': 'finish'
          };
        }
      }
      // Scroll functionality
    function scroll_to_stage(auction_doc, Rounds) {
      $timeout(function () {
        var current_round = 0;
        for (var index in Rounds){
          if ((auction_doc.current_stage >= Rounds[index]) && (auction_doc.current_stage <= (Rounds[index] + auction_doc.initial_bids.length))){
            current_round = parseInt(index) + 1;
            break;
          }
        }
        if (auction_doc.current_stage >= 0) {
          if (current_round){
            var round_elem = document.getElementById('round-header-' + current_round.toString());
          } else {
            var round_elem = document.getElementById('results-header');
          };
        }
        if (round_elem) {
          $log.debug('Scroll to:', round_elem);
          round_elem.scrollIntoView();
          var round_elem_dimensions = round_elem.getBoundingClientRect();
          $window.scrollBy(0, round_elem_dimensions.top - 75);

          if (($window.innerHeight - 169) < round_elem_dimensions.height) {
            var stage_elem = document.getElementById('stage-' + auction_doc.current_stage.toString());
            if (stage_elem){
              stage_elem.scrollIntoView(false);
              var stage_elem_dimensions = stage_elem.getBoundingClientRect();
              $window.scrollBy(0, stage_elem_dimensions.top + 96);
            }
          }
        }
      }, 0);
    }

    function parseQueryString(str) {
      if (typeof str !== 'string') {
        return {};
      }

      str = str.trim().replace(/^(\?|#)/, '');

      if (!str) {
        return {};
      }

      return str.trim().split('&').reduce(function (ret, param) {
        var parts = param.replace(/\+/g, ' ').split('=');
        var key = parts[0];
        var val = parts[1];
        key = decodeURIComponent(key);
        val = val === undefined ? null : decodeURIComponent(val);
        if (!ret.hasOwnProperty(key)) {
          ret[key] = val;
        } else if (Array.isArray(ret[key])) {
          ret[key].push(val);
        } else {
          ret[key] = [ret[key], val];
        }
        return ret;
      }, {});
    }

    function stringifyQueryString(obj) {
      return obj ? Object.keys(obj).map(function (key) {
        var val = obj[key];
        if (Array.isArray(val)) {
          return val.map(function (val2) {
            return encodeURIComponent(key) + '=' + encodeURIComponent(val2);
          }).join('&');
        }
        return encodeURIComponent(key) + '=' + encodeURIComponent(val);
      }).join('&') : '';
    }

    function inIframe () {
        try {
            return window.self !== window.top;
        } catch (e) {
            return true;
        }
    }

    function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
      var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

      return {
        x: centerX + (radius * Math.cos(angleInRadians)),
        y: centerY + (radius * Math.sin(angleInRadians))
      };
    }

    return {
      'prepare_info_timer_data': prepare_info_timer_data,
      'prepare_progress_timer_data': prepare_progress_timer_data,
      'get_bidder_id': get_bidder_id,
      'format_date': format_date,
      'get_round_data': get_round_data,
      'scroll_to_stage': scroll_to_stage,
      'parseQueryString': parseQueryString,
      'stringifyQueryString': stringifyQueryString,
      'prepare_title_ending_data': prepare_title_ending_data,
      'pad': pad,
      'inIframe': inIframe,
      'polarToCartesian': polarToCartesian
    };
  }]);

angular.module('auction')
  .factory('aside', ['$modal', function ($modal) {

    var asideFactory = {
      open: function (config) {
        var options = angular.extend({}, config);
        // check placement is set correct
        // set aside classes
        options.windowClass = 'ng-aside horizontal left' + (options.windowClass ? ' ' + options.windowClass : '');
        delete options.placement
        return $modal.open(options);
      }
    };
    return angular.extend({}, $modal, asideFactory);
  }]);<commit_msg>Fixed scroll to round for small screen<commit_after>angular.module('auction')
  .factory('AuctionUtils', ['$filter', '$timeout', '$log', '$window', function ($filter, $timeout, $log, $window) {
    // Format msg for timer
    'use strict';
    function pad(d) {
        return (d < 10) ? '0' + d.toString() : d.toString();
    }

    function prepare_info_timer_data(current_time, auction, bidder_id, Rounds) {
      var i;
      if (auction.current_stage === -100) {
        return {
          'countdown': false,
          'start_time': true,
          'msg': 'Tender cancelled'
        };
      }
      if (auction.current_stage === -1) {
        return {
          'countdown': ((new Date(auction.stages[0].start) - current_time) / 1000),
          'start_time': false,
          'msg': 'until the auction starts'
        };
      }
      if (auction.current_stage === (auction.stages.length - 1)) {
        var client_time = new Date();
        var ends_time = new Date(auction.stages[auction.current_stage].start);
        if (client_time < ends_time) {
          ends_time = client_time;
        }
        return {
          'countdown': false,
          'start_time': ends_time,
          'msg': 'Аuction was completed'
        };
      }
      if (bidder_id) {
        if (auction.stages[auction.current_stage].bidder_id === bidder_id) {
          return {
            'countdown': ((new Date(auction.stages[auction.current_stage + 1].start) - current_time) / 1000),
            'start_time': false,
            'msg': 'until your turn ends'
          };
        }
        var all_rounds = Rounds.concat(auction.stages.length - 1);
        for (i in all_rounds) {
          if (auction.current_stage < all_rounds[i]) {
            for (var index = auction.current_stage; index <= all_rounds[i]; index++) {
              if ((auction.stages[index].bidder_id) && (auction.stages[index].bidder_id === bidder_id)) {
                return {
                  'countdown': ((new Date(auction.stages[index].start) - current_time) / 1000),
                  'start_time': false,
                  'msg': 'until your turn'
                };
              }
            }
            break;
          }
        }
      }
      for (i in Rounds) {
        if (auction.current_stage == Rounds[i]) {
          return {
            'countdown': ((new Date(auction.stages[auction.current_stage + 1].start) - current_time) / 1000),
            'start_time': false,
            'msg': 'until the round starts'
          };
        }
        if (auction.current_stage < Rounds[i]) {
          return {
            'countdown': ((new Date(auction.stages[Rounds[i]].start) - current_time) / 1000),
            'start_time': false,
            'msg': 'until the round ends'
          };
        }
      }
      if (auction.current_stage < (auction.stages.length - 1)) {
        return {
          'countdown': ((new Date(auction.stages[auction.stages.length - 1].start) - current_time) / 1000),
          'start_time': false,
          'msg': 'until the results announcement'
        };
      }
    }

    function prepare_progress_timer_data(current_time, auction) {
      if ((auction.current_stage === (auction.stages.length - 1))||(auction.current_stage === -100)) {
        return {
          'countdown_seconds': false,
          'rounds_seconds': 0,
        };
      }
      if (auction.current_stage === -1) {
        return {
          'countdown_seconds': ((new Date(auction.stages[0].start) - current_time) / 1000),
          'rounds_seconds': ((new Date(auction.stages[0].start) - current_time) / 1000),
        };
      }
      return {
        'countdown_seconds': ((new Date(auction.stages[auction.current_stage + 1].start) - current_time) / 1000),
        'rounds_seconds': ((new Date(auction.stages[auction.current_stage + 1].start) - new Date(auction.stages[auction.current_stage].start)) / 1000),
      };

    }

    function prepare_title_ending_data(auction, lang) {
      var ending = auction.tenderID + " - " + (auction['title_'+ lang]||auction['title']||auction['title_en']||auction['title_ru']||"");
      ending += " - ";
      ending += auction.procuringEntity['name_'+ lang]||auction.procuringEntity['name']||auction.procuringEntity['name_en']||auction.procuringEntity['name_ru']||"";
      return ending;
    }
      // Get bidder_id from query
    function get_bidder_id() {
      var query = window.location.search.substring(1);
      var vars = query.split('&');
      for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split('=');
        if (decodeURIComponent(pair[0]) == 'bidder_id') {
          return decodeURIComponent(pair[1]);
        }
      }
    }
      // Format date with traslations
    function format_date(date, lang, format) {
      var temp_date = moment(date).locale(lang);
      if (typeof temp_date.format === 'function'){
        return temp_date.format(format);
      }
      return "";
    }

    // Get round data
    function get_round_data(pause_index, auction_doc, Rounds) {
        if (pause_index == -1){
          return {
            'type': 'waiting'
          };
        }
        if (pause_index <= Rounds[0]) {
          return {
            'type': 'pause',
            'data': ['', '1', ]
          };
        }
        for (var i in Rounds) {
          if (pause_index < Rounds[i]) {
            return {
              'type': 'round',
              'data': parseInt(i)
            };
          } else if (pause_index == Rounds[i]) {
            return {
              'type': 'pause',
              'data': [(parseInt(i)).toString(), (parseInt(i) + 1).toString(), ]
            };
          }
        }

        if (pause_index < (auction_doc.stages.length - 1)) {
          return {
            'type': 'round',
            'data': Rounds.length
          };
        } else {
          return {
            'type': 'finish'
          };
        }
      }
      // Scroll functionality
    function scroll_to_stage(auction_doc, Rounds) {
      $timeout(function () {
        var current_round = 0;
        for (var index in Rounds){
          if ((auction_doc.current_stage >= Rounds[index]) && (auction_doc.current_stage <= (Rounds[index] + auction_doc.initial_bids.length))){
            current_round = parseInt(index) + 1;
            break;
          }
        }
        if (auction_doc.current_stage >= 0) {
          if (current_round){
            var round_elem = document.getElementById('round-header-' + current_round.toString());
          } else {
            var round_elem = document.getElementById('results-header');
          };
        }
        if (round_elem) {
          var round_elem_dimensions = round_elem.getBoundingClientRect();
          if (($window.innerHeight - 169) < round_elem_dimensions.height) {
            var stage_elem = document.getElementById('stage-' + auction_doc.current_stage.toString());
            if (stage_elem){
              stage_elem.scrollIntoView(true);
              var stage_elem_dimensions = stage_elem.getBoundingClientRect();
              $window.scrollBy(0, stage_elem_dimensions.top - 96);
            }
          } else {
            round_elem.scrollIntoView();
            $window.scrollBy(0, round_elem_dimensions.top - 75);
          }
        }
      }, 0);
    }

    function parseQueryString(str) {
      if (typeof str !== 'string') {
        return {};
      }

      str = str.trim().replace(/^(\?|#)/, '');

      if (!str) {
        return {};
      }

      return str.trim().split('&').reduce(function (ret, param) {
        var parts = param.replace(/\+/g, ' ').split('=');
        var key = parts[0];
        var val = parts[1];
        key = decodeURIComponent(key);
        val = val === undefined ? null : decodeURIComponent(val);
        if (!ret.hasOwnProperty(key)) {
          ret[key] = val;
        } else if (Array.isArray(ret[key])) {
          ret[key].push(val);
        } else {
          ret[key] = [ret[key], val];
        }
        return ret;
      }, {});
    }

    function stringifyQueryString(obj) {
      return obj ? Object.keys(obj).map(function (key) {
        var val = obj[key];
        if (Array.isArray(val)) {
          return val.map(function (val2) {
            return encodeURIComponent(key) + '=' + encodeURIComponent(val2);
          }).join('&');
        }
        return encodeURIComponent(key) + '=' + encodeURIComponent(val);
      }).join('&') : '';
    }

    function inIframe () {
        try {
            return window.self !== window.top;
        } catch (e) {
            return true;
        }
    }

    function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
      var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

      return {
        x: centerX + (radius * Math.cos(angleInRadians)),
        y: centerY + (radius * Math.sin(angleInRadians))
      };
    }

    return {
      'prepare_info_timer_data': prepare_info_timer_data,
      'prepare_progress_timer_data': prepare_progress_timer_data,
      'get_bidder_id': get_bidder_id,
      'format_date': format_date,
      'get_round_data': get_round_data,
      'scroll_to_stage': scroll_to_stage,
      'parseQueryString': parseQueryString,
      'stringifyQueryString': stringifyQueryString,
      'prepare_title_ending_data': prepare_title_ending_data,
      'pad': pad,
      'inIframe': inIframe,
      'polarToCartesian': polarToCartesian
    };
  }]);

angular.module('auction')
  .factory('aside', ['$modal', function ($modal) {

    var asideFactory = {
      open: function (config) {
        var options = angular.extend({}, config);
        // check placement is set correct
        // set aside classes
        options.windowClass = 'ng-aside horizontal left' + (options.windowClass ? ' ' + options.windowClass : '');
        delete options.placement
        return $modal.open(options);
      }
    };
    return angular.extend({}, $modal, asideFactory);
  }]);<|endoftext|>


<commit_before>'use strict';

const util = require('util');
const assert = require('assert');
const wrapEmitter = require('emitter-listener');
const asyncHook = require('async-hook');

const CONTEXTS_SYMBOL = 'cls@contexts';
const ERROR_SYMBOL = 'error@context';

//const trace = [];

const invertedProviders = [];
for (let key in asyncHook.providers) {
  invertedProviders[asyncHook.providers[key]] = key;
}

const DEBUG_CLS_HOOKED = process.env.DEBUG_CLS_HOOKED;

let currentUid = -1;

module.exports = {
  getNamespace: getNamespace,
  createNamespace: createNamespace,
  destroyNamespace: destroyNamespace,
  reset: reset,
  //trace: trace,
  ERROR_SYMBOL: ERROR_SYMBOL
};

function Namespace(name) {
  this.name = name;
  // changed in 2.7: no default context
  this.active = null;
  this._set = [];
  this.id = null;
  this._contexts = new Map();
}

Namespace.prototype.set = function set(key, value) {
  if (!this.active) {
    throw new Error('No context available. ns.run() or ns.bind() must be called first.');
  }

  if (DEBUG_CLS_HOOKED) {
    debug2('    SETTING KEY:' + key + '=' + value + ' in ns:' + this.name + ' uid:' + currentUid + ' active:' + util.inspect(this.active, true));
  }
  this.active[key] = value;
  return value;
};

Namespace.prototype.get = function get(key) {
  if (!this.active) {
    if (DEBUG_CLS_HOOKED) {
      debug2('    GETTING KEY:' + key + '=undefined' + ' ' + this.name + ' uid:' + currentUid + ' active:' + util.inspect(this.active, true));
    }
    return undefined;
  }
  if (DEBUG_CLS_HOOKED) {
    debug2('    GETTING KEY:' + key + '=' + this.active[key] + ' ' + this.name + ' uid:' + currentUid + ' active:' + util.inspect(this.active, true));
  }
  return this.active[key];
};

Namespace.prototype.createContext = function createContext() {
  if (DEBUG_CLS_HOOKED) {
    debug2('   CREATING Context: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + ' active:' + util.inspect(this.active, true, 2, true));
  }

  let context = Object.create(this.active ? this.active : Object.prototype);
  context._ns_name = this.name;
  context.id = currentUid;

  if (DEBUG_CLS_HOOKED) {
    debug2('   CREATED Context: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + ' context:' + util.inspect(context, true, 2, true));
  }

  return context;
};

Namespace.prototype.run = function run(fn) {
  let context = this.createContext();
  this.enter(context);
  try {
    if (DEBUG_CLS_HOOKED) {
      debug2(' BEFORE RUN: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + util.inspect(context));
    }
    fn(context);
    return context;
  }
  catch (exception) {
    if (exception) {
      exception[ERROR_SYMBOL] = context;
    }
    throw exception;
  }
  finally {
    if (DEBUG_CLS_HOOKED) {
      debug2(' AFTER RUN: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + util.inspect(context));
    }
    this.exit(context);
  }
};

Namespace.prototype.runAndReturn = function (fn) {
  var value;
  this.run(function (context) {
    value = fn(context);
  });
  return value;
};

Namespace.prototype.bind = function bindFactory(fn, context) {
  if (!context) {
    if (!this.active) {
      context = this.createContext();
    }
    else {
      context = this.active;
    }
  }

  let self = this;
  return function clsBind() {
    self.enter(context);
    try {
      return fn.apply(this, arguments);
    }
    catch (exception) {
      if (exception) {
        exception[ERROR_SYMBOL] = context;
      }
      throw exception;
    }
    finally {
      self.exit(context);
    }
  };
};

Namespace.prototype.enter = function enter(context) {
  assert.ok(context, 'context must be provided for entering');
  if (DEBUG_CLS_HOOKED) {
    debug2('  ENTER ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' context: ' + util.inspect(context));
  }

  this._set.push(this.active);
  this.active = context;
};

Namespace.prototype.exit = function exit(context) {
  assert.ok(context, 'context must be provided for exiting');
  if (DEBUG_CLS_HOOKED) {
    debug2('  EXIT ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' context: ' + util.inspect(context));
  }

  // Fast path for most exits that are at the top of the stack
  if (this.active === context) {
    assert.ok(this._set.length, 'can\'t remove top context');
    this.active = this._set.pop();
    return;
  }

  // Fast search in the stack using lastIndexOf
  let index = this._set.lastIndexOf(context);

  if (index < 0) {
    if (DEBUG_CLS_HOOKED) {
      debug2('??ERROR?? context exiting but not entered - ignoring: ' + util.inspect(context));
    }
    assert.ok(index >= 0, 'context not currently entered; can\'t exit. \n' + util.inspect(this) + '\n' + util.inspect(context));
  } else {
    assert.ok(index, 'can\'t remove top context');
    this._set.splice(index, 1);
  }
};

Namespace.prototype.bindEmitter = function bindEmitter(emitter) {
  assert.ok(emitter.on && emitter.addListener && emitter.emit, 'can only bind real EEs');

  let namespace = this;
  let thisSymbol = 'context@' + this.name;

  // Capture the context active at the time the emitter is bound.
  function attach(listener) {
    if (!listener) {
      return;
    }
    if (!listener[CONTEXTS_SYMBOL]) {
      listener[CONTEXTS_SYMBOL] = Object.create(null);
    }

    listener[CONTEXTS_SYMBOL][thisSymbol] = {
      namespace: namespace,
      context: namespace.active
    };
  }

  // At emit time, bind the listener within the correct context.
  function bind(unwrapped) {
    if (!(unwrapped && unwrapped[CONTEXTS_SYMBOL])) {
      return unwrapped;
    }

    let wrapped = unwrapped;
    let unwrappedContexts = unwrapped[CONTEXTS_SYMBOL];
    Object.keys(unwrappedContexts).forEach(function(name) {
      let thunk = unwrappedContexts[name];
      wrapped = thunk.namespace.bind(wrapped, thunk.context);
    });
    return wrapped;
  }

  wrapEmitter(emitter, attach, bind);
};

/**
 * If an error comes out of a namespace, it will have a context attached to it.
 * This function knows how to find it.
 *
 * @param {Error} exception Possibly annotated error.
 */
Namespace.prototype.fromException = function fromException(exception) {
  return exception[ERROR_SYMBOL];
};

function getNamespace(name) {
  return process.namespaces[name];
}

function createNamespace(name) {
  assert.ok(name, 'namespace must be given a name.');

  if (DEBUG_CLS_HOOKED) {
    debug2('CREATING NAMESPACE ' + name);
  }
  let namespace = new Namespace(name);
  namespace.id = currentUid;

  asyncHook.addHooks({
    init(uid, handle, provider, parentUid, parentHandle) {
      //parentUid = parentUid || currentUid;  // Suggested usage but appears to work better for tracing modules.
      currentUid = uid;

      //CHAIN Parent's Context onto child if none exists. This is needed to pass net-events.spec
      if (parentUid) {
        namespace._contexts.set(uid, namespace._contexts.get(parentUid));
        if (DEBUG_CLS_HOOKED) {
          debug2('PARENTID: ' + name + ' uid:' + uid + ' parent:' + parentUid + ' provider:' + provider);
        }
      } else {
        namespace._contexts.set(currentUid, namespace.active);
      }

      if (DEBUG_CLS_HOOKED) {
        debug2('INIT ' + name + ' uid:' + uid + ' parent:' + parentUid + ' provider:' + invertedProviders[provider]
          + ' active:' + util.inspect(namespace.active, true));
      }

    },
    pre(uid, handle) {
      currentUid = uid;
      let context = namespace._contexts.get(uid);
      if (context) {
        if (DEBUG_CLS_HOOKED) {
          debug2(' PRE ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle) + ' context:' + util.inspect(context));
        }

        namespace.enter(context);
      } else {
        if (DEBUG_CLS_HOOKED) {
          debug2(' PRE MISSING CONTEXT ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle));
        }
      }
    },
    post(uid, handle) {
      currentUid = uid;
      let context = namespace._contexts.get(uid);
      if (context) {
        if (DEBUG_CLS_HOOKED) {
          debug2(' POST ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle) + ' context:' + util.inspect(context));
        }

        namespace.exit(context);
      } else {
        if (DEBUG_CLS_HOOKED) {
          debug2(' POST MISSING CONTEXT ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle));
        }
      }
    },
    destroy(uid) {
      currentUid = uid;

      if (DEBUG_CLS_HOOKED) {
        debug2('DESTROY ' + name + ' uid:' + uid + ' context:' + util.inspect(namespace._contexts.get(currentUid))
          + ' active:' + util.inspect(namespace.active, true));
      }

      namespace._contexts.delete(uid);
    }
  });

  process.namespaces[name] = namespace;
  return namespace;
}

function destroyNamespace(name) {
  let namespace = getNamespace(name);

  assert.ok(namespace, 'can\'t delete nonexistent namespace! "' + name + '"');
  assert.ok(namespace.id, 'don\'t assign to process.namespaces directly! ' + util.inspect(namespace));

  process.namespaces[name] = null;
}

function reset() {
  // must unregister async listeners
  if (process.namespaces) {
    Object.keys(process.namespaces).forEach(function(name) {
      destroyNamespace(name);
    });
  }
  process.namespaces = Object.create(null);
}

process.namespaces = {};

if (asyncHook._state && !asyncHook._state.enabled) {
  asyncHook.enable();
}

function debug2(msg) {
  if (process.env.DEBUG) {
    process._rawDebug(msg);
  }
}

/*function debug(from, ns) {
 process._rawDebug('DEBUG: ' + util.inspect({
 from: from,
 currentUid: currentUid,
 context: ns ? ns._contexts.get(currentUid) : 'no ns'
 }, true, 2, true));
 }*/

function getFunctionName(fn) {
  if (!fn) {
    return fn;
  }
  if (typeof fn === 'function') {
    if (fn.name) {
      return fn.name;
    }
    return (fn.toString().trim().match(/^function\s*([^\s(]+)/) || [])[1];
  } else if (fn.constructor && fn.constructor.name) {
    return fn.constructor.name;
  }
}

// Add back to callstack
if (DEBUG_CLS_HOOKED) {
  var stackChain = require('stack-chain');
  for (var modifier in stackChain.filter._modifiers) {
    stackChain.filter.deattach(modifier);
  }
}
<commit_msg>adding runPromise - WIP<commit_after>'use strict';

const util = require('util');
const assert = require('assert');
const wrapEmitter = require('emitter-listener');
const asyncHook = require('async-hook');

const CONTEXTS_SYMBOL = 'cls@contexts';
const ERROR_SYMBOL = 'error@context';

//const trace = [];

const invertedProviders = [];
for (let key in asyncHook.providers) {
  invertedProviders[asyncHook.providers[key]] = key;
}

const DEBUG_CLS_HOOKED = process.env.DEBUG_CLS_HOOKED;

let currentUid = -1;

module.exports = {
  getNamespace: getNamespace,
  createNamespace: createNamespace,
  destroyNamespace: destroyNamespace,
  reset: reset,
  //trace: trace,
  ERROR_SYMBOL: ERROR_SYMBOL
};

function Namespace(name) {
  this.name = name;
  // changed in 2.7: no default context
  this.active = null;
  this._set = [];
  this.id = null;
  this._contexts = new Map();
}

Namespace.prototype.set = function set(key, value) {
  if (!this.active) {
    throw new Error('No context available. ns.run() or ns.bind() must be called first.');
  }

  if (DEBUG_CLS_HOOKED) {
    debug2('    SETTING KEY:' + key + '=' + value + ' in ns:' + this.name + ' uid:' + currentUid + ' active:' + util.inspect(this.active, true));
  }
  this.active[key] = value;
  return value;
};

Namespace.prototype.get = function get(key) {
  if (!this.active) {
    if (DEBUG_CLS_HOOKED) {
      debug2('    GETTING KEY:' + key + '=undefined' + ' ' + this.name + ' uid:' + currentUid + ' active:' + util.inspect(this.active, true));
    }
    return undefined;
  }
  if (DEBUG_CLS_HOOKED) {
    debug2('    GETTING KEY:' + key + '=' + this.active[key] + ' ' + this.name + ' uid:' + currentUid + ' active:' + util.inspect(this.active, true));
  }
  return this.active[key];
};

Namespace.prototype.createContext = function createContext() {
  if (DEBUG_CLS_HOOKED) {
    debug2('   CREATING Context: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + ' active:' + util.inspect(this.active, true, 2, true));
  }

  let context = Object.create(this.active ? this.active : Object.prototype);
  context._ns_name = this.name;
  context.id = currentUid;

  if (DEBUG_CLS_HOOKED) {
    debug2('   CREATED Context: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + ' context:' + util.inspect(context, true, 2, true));
  }

  return context;
};

Namespace.prototype.run = function run(fn) {
  let context = this.createContext();
  this.enter(context);
  try {
    if (DEBUG_CLS_HOOKED) {
      debug2(' BEFORE RUN: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + util.inspect(context));
    }
    fn(context);
    return context;
  }
  catch (exception) {
    if (exception) {
      exception[ERROR_SYMBOL] = context;
    }
    throw exception;
  }
  finally {
    if (DEBUG_CLS_HOOKED) {
      debug2(' AFTER RUN: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + util.inspect(context));
    }
    this.exit(context);
  }
};

Namespace.prototype.runAndReturn = function runAndReturn(fn) {
  var value;
  this.run(function (context) {
    value = fn(context);
  });
  return value;
};

/**
 * Uses global Promise and assumes Promise is cls friendly or wrapped already.
 * @param {function} fn
 * @returns {*}
 */
Namespace.prototype.runPromise = function runPromise(fn) {
  let context = this.createContext();
  this.enter(context);
  try {
    if (DEBUG_CLS_HOOKED) {
      debug2(' BEFORE runPromise: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + util.inspect(context));
    }
    return fn(context);
  }
  catch (exception) {
    if (exception) {
      exception[ERROR_SYMBOL] = context;
    }
    throw exception;
  }
  finally {
    if (DEBUG_CLS_HOOKED) {
      debug2(' AFTER runPromise: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + util.inspect(context));
    }
    this.exit(context);
  }
};

Namespace.prototype.bind = function bindFactory(fn, context) {
  if (!context) {
    if (!this.active) {
      context = this.createContext();
    }
    else {
      context = this.active;
    }
  }

  let self = this;
  return function clsBind() {
    self.enter(context);
    try {
      return fn.apply(this, arguments);
    }
    catch (exception) {
      if (exception) {
        exception[ERROR_SYMBOL] = context;
      }
      throw exception;
    }
    finally {
      self.exit(context);
    }
  };
};

Namespace.prototype.enter = function enter(context) {
  assert.ok(context, 'context must be provided for entering');
  if (DEBUG_CLS_HOOKED) {
    debug2('  ENTER ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' context: ' + util.inspect(context));
  }

  this._set.push(this.active);
  this.active = context;
};

Namespace.prototype.exit = function exit(context) {
  assert.ok(context, 'context must be provided for exiting');
  if (DEBUG_CLS_HOOKED) {
    debug2('  EXIT ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' context: ' + util.inspect(context));
  }

  // Fast path for most exits that are at the top of the stack
  if (this.active === context) {
    assert.ok(this._set.length, 'can\'t remove top context');
    this.active = this._set.pop();
    return;
  }

  // Fast search in the stack using lastIndexOf
  let index = this._set.lastIndexOf(context);

  if (index < 0) {
    if (DEBUG_CLS_HOOKED) {
      debug2('??ERROR?? context exiting but not entered - ignoring: ' + util.inspect(context));
    }
    assert.ok(index >= 0, 'context not currently entered; can\'t exit. \n' + util.inspect(this) + '\n' + util.inspect(context));
  } else {
    assert.ok(index, 'can\'t remove top context');
    this._set.splice(index, 1);
  }
};

Namespace.prototype.bindEmitter = function bindEmitter(emitter) {
  assert.ok(emitter.on && emitter.addListener && emitter.emit, 'can only bind real EEs');

  let namespace = this;
  let thisSymbol = 'context@' + this.name;

  // Capture the context active at the time the emitter is bound.
  function attach(listener) {
    if (!listener) {
      return;
    }
    if (!listener[CONTEXTS_SYMBOL]) {
      listener[CONTEXTS_SYMBOL] = Object.create(null);
    }

    listener[CONTEXTS_SYMBOL][thisSymbol] = {
      namespace: namespace,
      context: namespace.active
    };
  }

  // At emit time, bind the listener within the correct context.
  function bind(unwrapped) {
    if (!(unwrapped && unwrapped[CONTEXTS_SYMBOL])) {
      return unwrapped;
    }

    let wrapped = unwrapped;
    let unwrappedContexts = unwrapped[CONTEXTS_SYMBOL];
    Object.keys(unwrappedContexts).forEach(function(name) {
      let thunk = unwrappedContexts[name];
      wrapped = thunk.namespace.bind(wrapped, thunk.context);
    });
    return wrapped;
  }

  wrapEmitter(emitter, attach, bind);
};

/**
 * If an error comes out of a namespace, it will have a context attached to it.
 * This function knows how to find it.
 *
 * @param {Error} exception Possibly annotated error.
 */
Namespace.prototype.fromException = function fromException(exception) {
  return exception[ERROR_SYMBOL];
};

function getNamespace(name) {
  return process.namespaces[name];
}

function createNamespace(name) {
  assert.ok(name, 'namespace must be given a name.');

  if (DEBUG_CLS_HOOKED) {
    debug2('CREATING NAMESPACE ' + name);
  }
  let namespace = new Namespace(name);
  namespace.id = currentUid;

  asyncHook.addHooks({
    init(uid, handle, provider, parentUid, parentHandle) {
      //parentUid = parentUid || currentUid;  // Suggested usage but appears to work better for tracing modules.
      currentUid = uid;

      //CHAIN Parent's Context onto child if none exists. This is needed to pass net-events.spec
      if (parentUid) {
        namespace._contexts.set(uid, namespace._contexts.get(parentUid));
        if (DEBUG_CLS_HOOKED) {
          debug2('PARENTID: ' + name + ' uid:' + uid + ' parent:' + parentUid + ' provider:' + provider);
        }
      } else {
        namespace._contexts.set(currentUid, namespace.active);
      }

      if (DEBUG_CLS_HOOKED) {
        debug2('INIT ' + name + ' uid:' + uid + ' parent:' + parentUid + ' provider:' + invertedProviders[provider]
          + ' active:' + util.inspect(namespace.active, true));
      }

    },
    pre(uid, handle) {
      currentUid = uid;
      let context = namespace._contexts.get(uid);
      if (context) {
        if (DEBUG_CLS_HOOKED) {
          debug2(' PRE ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle) + ' context:' + util.inspect(context));
        }

        namespace.enter(context);
      } else {
        if (DEBUG_CLS_HOOKED) {
          debug2(' PRE MISSING CONTEXT ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle));
        }
      }
    },
    post(uid, handle) {
      currentUid = uid;
      let context = namespace._contexts.get(uid);
      if (context) {
        if (DEBUG_CLS_HOOKED) {
          debug2(' POST ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle) + ' context:' + util.inspect(context));
        }

        namespace.exit(context);
      } else {
        if (DEBUG_CLS_HOOKED) {
          debug2(' POST MISSING CONTEXT ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle));
        }
      }
    },
    destroy(uid) {
      currentUid = uid;

      if (DEBUG_CLS_HOOKED) {
        debug2('DESTROY ' + name + ' uid:' + uid + ' context:' + util.inspect(namespace._contexts.get(currentUid))
          + ' active:' + util.inspect(namespace.active, true));
      }

      namespace._contexts.delete(uid);
    }
  });

  process.namespaces[name] = namespace;
  return namespace;
}

function destroyNamespace(name) {
  let namespace = getNamespace(name);

  assert.ok(namespace, 'can\'t delete nonexistent namespace! "' + name + '"');
  assert.ok(namespace.id, 'don\'t assign to process.namespaces directly! ' + util.inspect(namespace));

  process.namespaces[name] = null;
}

function reset() {
  // must unregister async listeners
  if (process.namespaces) {
    Object.keys(process.namespaces).forEach(function(name) {
      destroyNamespace(name);
    });
  }
  process.namespaces = Object.create(null);
}

process.namespaces = {};

if (asyncHook._state && !asyncHook._state.enabled) {
  asyncHook.enable();
}

function debug2(msg) {
  if (process.env.DEBUG) {
    process._rawDebug(msg);
  }
}

/*function debug(from, ns) {
 process._rawDebug('DEBUG: ' + util.inspect({
 from: from,
 currentUid: currentUid,
 context: ns ? ns._contexts.get(currentUid) : 'no ns'
 }, true, 2, true));
 }*/

function getFunctionName(fn) {
  if (!fn) {
    return fn;
  }
  if (typeof fn === 'function') {
    if (fn.name) {
      return fn.name;
    }
    return (fn.toString().trim().match(/^function\s*([^\s(]+)/) || [])[1];
  } else if (fn.constructor && fn.constructor.name) {
    return fn.constructor.name;
  }
}

// Add back to callstack
if (DEBUG_CLS_HOOKED) {
  var stackChain = require('stack-chain');
  for (var modifier in stackChain.filter._modifiers) {
    stackChain.filter.deattach(modifier);
  }
}
<|endoftext|>


<commit_before>
module.exports = {

  VERSION: "Mr Bazinga version 0.1",

  bet_request: function(game_state) {
    return 100;
  },

  showdown: function(game_state) {

  }
};
<commit_msg>more toss<commit_after>
module.exports = {

  VERSION: "Mr Bazinga version 0.1",

  bet_request: function(game_state) {
    return 101;
  },

  showdown: function(game_state) {

  }
};
<|endoftext|>


<commit_before>const sass = require('gulp-sass');
const named = require('vinyl-named');
const rename = require('gulp-rename');
const path = require('path');
const fs = require('fs');
const merge = require('merge-stream');
const gulpIf = require('gulp-if');
const sourcemaps = require('gulp-sourcemaps');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const header = require('gulp-header');
const autoprefixer = require('gulp-autoprefixer');

const browserSync = require('browser-sync').create();

const isDevelopment = !process.env.NODE_ENV || process.env.NODE_ENV == 'development';

module.exports = {
    assign: sassTask
};

function sassTask (gulp, options) {
    /*
    var series = options.sassFiles.map(function (sassFile) {
        return function (callback) {
            return gulp.src({cwd: 'shortcode/*'}, '')
                .pipe(sass().on('error', sass.logError))
                .pipe(gulp.dest('bundle'));
        };
    });
    */

    function getFolders(dir) {
        return fs.readdirSync(dir)
            .filter(function(file) {
                return fs.statSync(path.join(dir, file)).isDirectory();
            });
    }

    var series = options.sassFiles.map(function (entry) {
        if (entry.forEachFolderIn) {
            var folders = getFolders(entry.forEachFolderIn);

            var tasks = folders.map(function (folder) {
                return function () {
                    return sassProcess(
                        path.join(entry.forEachFolderIn, folder, entry.input),
                        path.join(entry.forEachFolderIn, folder, entry.output),
                        entry
                    );
                }
            });

            return gulp.series(tasks);
        }

        return function () {
            return sassProcess(entry.input, entry.output, entry);
        }
    });

    function sassProcess (input, output, entry) {
        return gulp.src(input, {allowEmpty: true})
            .pipe(plumber({
                errorHandler: notify.onError(err => ({
                    title:   'Styles',
                    message: err.message
                }))
            }))
            .pipe(gulpIf(isDevelopment, sourcemaps.init()))
            .pipe(autoprefixer('last 2 version', '> 1%', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
            .pipe(sass({
                outputStyle: isDevelopment ? 'nested' : 'compressed',
                includePaths: [
                    'bower_components',
                    'node_modules'
                ].concat(
                    options.sassIncludePaths
                )
            }).on('error', sass.logError))
            .pipe(gulpIf(entry.header, header(
                (entry.header || {}).template,
                (entry.header || {}).values
            )))
            .pipe(gulpIf(isDevelopment, sourcemaps.write()))
            .pipe(gulp.dest(output))
            .pipe(gulpIf(isDevelopment, browserSync.stream()));
    }

    gulp.task('sass', gulp.series(series));

    gulp.task('sass:watch', gulp.series(
        'sass',
        function (done) {
            if (!isDevelopment) {
                done();
                return;
            }

            var toWatch = options.sassFiles.map((sassFile) => {
                if (sassFile.forEachFolderIn) {
                    return path.join(
                        sassFile.forEachFolderIn,
                        '*',
                        sassFile.input
                    );
                }

                return sassFile.input;
            }).concat(
                options.sassWatch
            );

            browserSync.init({
                logSnippet: false,
                port: 9669
            });

            gulp.watch(options.watchFilesAndReload).on('change', browserSync.reload)

            gulp.watch(
                toWatch,
                gulp.series('sass')
            );
        }
    ))
}
<commit_msg>don't fail when giving nothing as input for sass<commit_after>const sass = require('gulp-sass');
const named = require('vinyl-named');
const rename = require('gulp-rename');
const path = require('path');
const fs = require('fs');
const merge = require('merge-stream');
const gulpIf = require('gulp-if');
const sourcemaps = require('gulp-sourcemaps');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const header = require('gulp-header');
const autoprefixer = require('gulp-autoprefixer');

const browserSync = require('browser-sync').create();

const isDevelopment = !process.env.NODE_ENV || process.env.NODE_ENV == 'development';

module.exports = {
    assign: sassTask
};

function sassTask (gulp, options) {
    /*
    var series = options.sassFiles.map(function (sassFile) {
        return function (callback) {
            return gulp.src({cwd: 'shortcode/*'}, '')
                .pipe(sass().on('error', sass.logError))
                .pipe(gulp.dest('bundle'));
        };
    });
    */

    function getFolders(dir) {
        return fs.readdirSync(dir)
            .filter(function(file) {
                return fs.statSync(path.join(dir, file)).isDirectory();
            });
    }

    var series = options.sassFiles.map(function (entry) {
        if (entry.forEachFolderIn) {
            var folders = getFolders(entry.forEachFolderIn);

            var tasks = folders.map(function (folder) {
                return function () {
                    return sassProcess(
                        path.join(entry.forEachFolderIn, folder, entry.input),
                        path.join(entry.forEachFolderIn, folder, entry.output),
                        entry
                    );
                }
            });

            return gulp.series(tasks);
        }

        return function () {
            return sassProcess(entry.input, entry.output, entry);
        }
    });

    function sassProcess (input, output, entry) {
        return gulp.src(input, {allowEmpty: true})
            .pipe(plumber({
                errorHandler: notify.onError(err => ({
                    title:   'Styles',
                    message: err.message
                }))
            }))
            .pipe(gulpIf(isDevelopment, sourcemaps.init()))
            .pipe(autoprefixer('last 2 version', '> 1%', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
            .pipe(sass({
                outputStyle: isDevelopment ? 'nested' : 'compressed',
                includePaths: [
                    'bower_components',
                    'node_modules'
                ].concat(
                    options.sassIncludePaths
                )
            }).on('error', sass.logError))
            .pipe(gulpIf(entry.header, header(
                (entry.header || {}).template,
                (entry.header || {}).values
            )))
            .pipe(gulpIf(isDevelopment, sourcemaps.write()))
            .pipe(gulp.dest(output))
            .pipe(gulpIf(isDevelopment, browserSync.stream()));
    }

    gulp.task(
        'sass',
        series.length > 0 ? gulp.series(series) : function (done) {done()}
    );

    gulp.task('sass:watch', gulp.series(
        'sass',
        function (done) {
            if (!isDevelopment) {
                done();
                return;
            }

            var toWatch = options.sassFiles.map((sassFile) => {
                if (sassFile.forEachFolderIn) {
                    return path.join(
                        sassFile.forEachFolderIn,
                        '*',
                        sassFile.input
                    );
                }

                return sassFile.input;
            }).concat(
                options.sassWatch
            );

            browserSync.init({
                logSnippet: false,
                port: 9669
            });

            gulp.watch(options.watchFilesAndReload).on('change', browserSync.reload)

            gulp.watch(
                toWatch,
                gulp.series('sass')
            );
        }
    ))
}
<|endoftext|>


<commit_before>function loadComponent() {
	var config = {
		component: document.getElementById('component_input').value,
		location: document.getElementById('location_input').value
	};
	chrome.tabs.getSelected(function(tab) {
		config.tab = tab;
		chrome.tabs.executeScript(null, {
			code: "var config = " + JSON.stringify(config)
		}, function () {
			chrome.tabs.executeScript(null, {
				file: 'scripts/loadComponent.js',
			});
		})
	});
	window.close();
}

function loadComponentOnEnter(event) {
	if(event.keyCode == 13) {
        loadComponent();
    }
}

function init() {
	document.getElementById('load_button').addEventListener('click', loadComponent);
	document.body.addEventListener('keyup', loadComponentOnEnter);
}

document.addEventListener('DOMContentLoaded', init);<commit_msg>move window.close of popup in callback when executing loadComponent script<commit_after>function loadComponent() {
	var config = {
		component: document.getElementById('component_input').value,
		location: document.getElementById('location_input').value
	};
	chrome.tabs.getSelected(function(tab) {
		config.tab = tab;
		chrome.tabs.executeScript(null, {
			code: "var config = " + JSON.stringify(config)
		}, function () {
			chrome.tabs.executeScript(null, {
				file: 'scripts/loadComponent.js',
			});
			window.close();
		})
	});
}

function loadComponentOnEnter(event) {
	if(event.keyCode == 13) {
        loadComponent();
    }
}

function init() {
	document.getElementById('load_button').addEventListener('click', loadComponent);
	document.body.addEventListener('keyup', loadComponentOnEnter);
}

document.addEventListener('DOMContentLoaded', init);<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

'strict mode'

const assert = require('assert')
const request = require('../js/lib/request').request
const electron = require('electron')
const autoUpdater = electron.autoUpdater
const app = electron.app
const appConfig = require('../js/constants/appConfig')
const messages = require('../js/constants/messages')
const UpdateStatus = require('../js/constants/updateStatus')
const querystring = require('querystring')
const AppStore = require('../js/stores/appStore')
const appActions = require('../js/actions/appActions')
const Immutable = require('immutable')
const dates = require('./dates')
const Channel = require('./channel')

const fs = require('fs')
const path = require('path')
const os = require('os')
const updateLogPath = path.join(app.getPath('userData'), 'updateLog.log')

// in built mode console.log output is not emitted to the terminal
// in prod mode we pipe to a file
var debug = function (contents) {
  fs.appendFile(updateLogPath, new Date().toISOString() + ' - ' + contents + os.EOL)
}

// this maps the result of a call to process.platform to an update API identifier
var platforms = {
  'darwin': 'osx',
  'win32x64': 'winx64',
  'win32ia32': 'winia32'
}

// We are storing this as a package variable because a number of functions need access
// It is set in the init function
var platformBaseUrl = null
var version = null

// build the complete update url from the base, platform and version
exports.updateUrl = function (updates, platform, arch) {
  // For windows we need to separate x64 and ia32 for update purposes
  if (platform === 'win32') {
    platform = platform + arch
  }
  platformBaseUrl = `${updates.baseUrl}/${Channel.channel()}/${version}/${platforms[platform]}`
  debug(`platformBaseUrl = ${platformBaseUrl}`)
  if (platform === 'darwin') {
    return platformBaseUrl
  } else {
    if (platform.match(/^win32/)) {
      var windowsUpdateUrlWithArch = updates.winBaseUrl.replace('CHANNEL', Channel.channel()) + platforms[platform]
      return windowsUpdateUrlWithArch
    } else {
      // Unsupport platform for automatic updates
      return null
    }
  }
}

// Setup schedule for periodic and startup update checks
var scheduleUpdates = () => {
  // Periodic check
  if (appConfig.updates.appUpdateCheckFrequency) {
    setInterval(() => {
      exports.checkForUpdate()
    }, appConfig.updates.appUpdateCheckFrequency)
  }

  // Startup check
  if (appConfig.updates.runtimeUpdateCheckDelay) {
    setTimeout(() => {
      exports.checkForUpdate()
    }, appConfig.updates.runtimeUpdateCheckDelay)
  }
}

// set the feed url for the auto-update system
exports.init = (platform, arch, ver) => {
  // When starting up we should not expect an update to be available
  appActions.setUpdateStatus(UpdateStatus.UPDATE_NONE)

  // Browser version X.X.X
  version = ver

  var baseUrl = exports.updateUrl(appConfig.updates, platform, arch)
  debug(`updateUrl = ${baseUrl}`)

  scheduleUpdates()

  // This will fail if we are in dev
  try {
    autoUpdater.setFeedURL(baseUrl)
  } catch (err) {
    console.log(err)
  }
}

// Build a set of three params providing flags determining when the last update occurred
// This is a privacy preserving policy. Instead of passing personally identifying
// information, the browser will pass thefour boolean values indicating when the last
// update check occurred.
var paramsFromLastCheckDelta = (lastCheckYMD, lastCheckWOY, lastCheckMonth, firstCheckMade) => {
  return {
    daily: !lastCheckYMD || (dates.todayYMD() > lastCheckYMD),
    weekly: !lastCheckWOY || (dates.todayWOY() !== lastCheckWOY),
    monthly: !lastCheckMonth || (dates.todayMonth() !== lastCheckMonth),
    first: !firstCheckMade
  }
}

// Make a request to the update server to retrieve meta data
var requestVersionInfo = (done, pingOnly) => {
  if (!platformBaseUrl) throw new Error('platformBaseUrl not set')

  // Get the daily, week of year and month update checks
  var lastCheckYMD = AppStore.getState().toJS().updates['lastCheckYMD'] || null
  debug(`lastCheckYMD = ${lastCheckYMD}`)

  var lastCheckWOY = AppStore.getState().toJS().updates['lastCheckWOY'] || null
  debug(`lastCheckWOY = ${lastCheckWOY}`)

  var lastCheckMonth = AppStore.getState().toJS().updates['lastCheckMonth'] || null
  debug(`lastCheckMonth = ${lastCheckMonth}`)

  // Has the browser ever asked for an update
  var firstCheckMade = AppStore.getState().toJS().updates['firstCheckMade'] || false
  debug(`firstCheckMade = ${firstCheckMade}`)

  // Build query string based on the last date an update request was made
  var query = paramsFromLastCheckDelta(
    lastCheckYMD,
    lastCheckWOY,
    lastCheckMonth,
    firstCheckMade
  )
  var queryString = `${platformBaseUrl}?${querystring.stringify(query)}`
  debug(queryString)

  request(queryString, (err, statusCode, body) => {
    appActions.setUpdateLastCheck()
    if (pingOnly) {
      return
    }
    if (!err && statusCode === 204) {
      autoUpdater.emit(messages.UPDATE_NOT_AVAILABLE)
    } else if (!err && (statusCode === 200)) {
      if (body) {
        try {
          body = JSON.parse(body)
        } catch (error) {
          autoUpdater.emit('error', error)
        }
      }
      // This should be handled by a UI component for the update toolbar
      process.emit(messages.UPDATE_META_DATA_RETRIEVED, body)
      done(null, body)
    } else {
      // Network error or mis-configuration
      autoUpdater.emit('error', err)
    }
  })
}

var downloadHandler = (err, metadata) => {
  assert.equal(err, null)
  debug(`Metadata: ${JSON.stringify(metadata)}`)
  appActions.setUpdateStatus(undefined, undefined, Immutable.fromJS(metadata))
  if (process.platform === 'win32') {
    // check versions to see if an update is required
    if (metadata) {
      autoUpdater.checkForUpdates()
    } else {
      autoUpdater.emit(messages.UPDATE_NOT_AVAILABLE)
    }
  } else {
    autoUpdater.checkForUpdates()
  }
}

// Make network request to check for an available update
exports.checkForUpdate = (verbose) => {
  const updateStatus = AppStore.getState().getIn(['updates', 'status'])
  if (updateStatus !== UpdateStatus.UPDATE_ERROR &&
      updateStatus !== UpdateStatus.UPDATE_NOT_AVAILABLE &&
      updateStatus !== UpdateStatus.UPDATE_NONE) {
    debug('Already checking for updates...')
    requestVersionInfo(undefined, true)
    appActions.setUpdateStatus(undefined, verbose)
    return
  }
  // Force falsy or truthy here so session store will write out a value
  // and it won't auto make updater UI appear periodically.
  appActions.setUpdateStatus(UpdateStatus.UPDATE_CHECKING, !!verbose)
  debug('checkForUpdates')
  try {
    requestVersionInfo(downloadHandler, false)
  } catch (err) {
    debug(err)
  }
}

exports.quitAndInstall = () => {
  autoUpdater.quitAndInstall()
}

// The download is complete, we send a signal and await UI
autoUpdater.on('update-downloaded', (evt, releaseNotes, releaseDate, updateURL) => {
  debug('update downloaded')
  if (releaseNotes) {
    debug(`Release notes : ${releaseNotes}`)
  }
  if (releaseDate) {
    debug(`Release date: ${releaseDate}`)
  }
  if (updateURL) {
    debug(`Update URL: ${updateURL}`)
  }
  appActions.setUpdateStatus(UpdateStatus.UPDATE_AVAILABLE)
})

// Download has started
autoUpdater.on(messages.UPDATE_AVAILABLE, (evt) => {
  debug('update downloading')
  appActions.setUpdateStatus(UpdateStatus.UPDATE_DOWNLOADING)
})

// The current version of the software is up to date
autoUpdater.on(messages.UPDATE_NOT_AVAILABLE, (evt) => {
  debug('update not available')
  appActions.setUpdateStatus(UpdateStatus.UPDATE_NOT_AVAILABLE)
})

// Handle autoUpdater errors (Network, permissions etc...)
autoUpdater.on('error', (err) => {
  appActions.setUpdateStatus(UpdateStatus.UPDATE_ERROR)
  debug(err)
})
<commit_msg>Retrieve status code from response object in metadata request<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

'strict mode'

const assert = require('assert')
const request = require('../js/lib/request').request
const electron = require('electron')
const autoUpdater = electron.autoUpdater
const app = electron.app
const appConfig = require('../js/constants/appConfig')
const messages = require('../js/constants/messages')
const UpdateStatus = require('../js/constants/updateStatus')
const querystring = require('querystring')
const AppStore = require('../js/stores/appStore')
const appActions = require('../js/actions/appActions')
const Immutable = require('immutable')
const dates = require('./dates')
const Channel = require('./channel')

const fs = require('fs')
const path = require('path')
const os = require('os')
const updateLogPath = path.join(app.getPath('userData'), 'updateLog.log')

// in built mode console.log output is not emitted to the terminal
// in prod mode we pipe to a file
var debug = function (contents) {
  fs.appendFile(updateLogPath, new Date().toISOString() + ' - ' + contents + os.EOL)
}

// this maps the result of a call to process.platform to an update API identifier
var platforms = {
  'darwin': 'osx',
  'win32x64': 'winx64',
  'win32ia32': 'winia32'
}

// We are storing this as a package variable because a number of functions need access
// It is set in the init function
var platformBaseUrl = null
var version = null

// build the complete update url from the base, platform and version
exports.updateUrl = function (updates, platform, arch) {
  // For windows we need to separate x64 and ia32 for update purposes
  if (platform === 'win32') {
    platform = platform + arch
  }
  platformBaseUrl = `${updates.baseUrl}/${Channel.channel()}/${version}/${platforms[platform]}`
  debug(`platformBaseUrl = ${platformBaseUrl}`)
  if (platform === 'darwin') {
    return platformBaseUrl
  } else {
    if (platform.match(/^win32/)) {
      var windowsUpdateUrlWithArch = updates.winBaseUrl.replace('CHANNEL', Channel.channel()) + platforms[platform]
      return windowsUpdateUrlWithArch
    } else {
      // Unsupport platform for automatic updates
      return null
    }
  }
}

// Setup schedule for periodic and startup update checks
var scheduleUpdates = () => {
  // Periodic check
  if (appConfig.updates.appUpdateCheckFrequency) {
    setInterval(() => {
      exports.checkForUpdate()
    }, appConfig.updates.appUpdateCheckFrequency)
  }

  // Startup check
  if (appConfig.updates.runtimeUpdateCheckDelay) {
    setTimeout(() => {
      exports.checkForUpdate()
    }, appConfig.updates.runtimeUpdateCheckDelay)
  }
}

// set the feed url for the auto-update system
exports.init = (platform, arch, ver) => {
  // When starting up we should not expect an update to be available
  appActions.setUpdateStatus(UpdateStatus.UPDATE_NONE)

  // Browser version X.X.X
  version = ver

  var baseUrl = exports.updateUrl(appConfig.updates, platform, arch)
  debug(`updateUrl = ${baseUrl}`)

  scheduleUpdates()

  // This will fail if we are in dev
  try {
    autoUpdater.setFeedURL(baseUrl)
  } catch (err) {
    console.log(err)
  }
}

// Build a set of three params providing flags determining when the last update occurred
// This is a privacy preserving policy. Instead of passing personally identifying
// information, the browser will pass thefour boolean values indicating when the last
// update check occurred.
var paramsFromLastCheckDelta = (lastCheckYMD, lastCheckWOY, lastCheckMonth, firstCheckMade) => {
  return {
    daily: !lastCheckYMD || (dates.todayYMD() > lastCheckYMD),
    weekly: !lastCheckWOY || (dates.todayWOY() !== lastCheckWOY),
    monthly: !lastCheckMonth || (dates.todayMonth() !== lastCheckMonth),
    first: !firstCheckMade
  }
}

// Make a request to the update server to retrieve meta data
var requestVersionInfo = (done, pingOnly) => {
  if (!platformBaseUrl) throw new Error('platformBaseUrl not set')

  // Get the daily, week of year and month update checks
  var lastCheckYMD = AppStore.getState().toJS().updates['lastCheckYMD'] || null
  debug(`lastCheckYMD = ${lastCheckYMD}`)

  var lastCheckWOY = AppStore.getState().toJS().updates['lastCheckWOY'] || null
  debug(`lastCheckWOY = ${lastCheckWOY}`)

  var lastCheckMonth = AppStore.getState().toJS().updates['lastCheckMonth'] || null
  debug(`lastCheckMonth = ${lastCheckMonth}`)

  // Has the browser ever asked for an update
  var firstCheckMade = AppStore.getState().toJS().updates['firstCheckMade'] || false
  debug(`firstCheckMade = ${firstCheckMade}`)

  // Build query string based on the last date an update request was made
  var query = paramsFromLastCheckDelta(
    lastCheckYMD,
    lastCheckWOY,
    lastCheckMonth,
    firstCheckMade
  )
  var queryString = `${platformBaseUrl}?${querystring.stringify(query)}`
  debug(queryString)

  request(queryString, (err, response, body) => {
    var statusCode = response.statusCode
    appActions.setUpdateLastCheck()
    if (pingOnly) {
      return
    }
    if (!err && statusCode === 204) {
      autoUpdater.emit(messages.UPDATE_NOT_AVAILABLE)
    } else if (!err && (statusCode === 200)) {
      if (body) {
        try {
          body = JSON.parse(body)
        } catch (error) {
          autoUpdater.emit('error', error)
        }
      }
      // This should be handled by a UI component for the update toolbar
      process.emit(messages.UPDATE_META_DATA_RETRIEVED, body)
      done(null, body)
    } else {
      // Network error or mis-configuration
      autoUpdater.emit('error', err)
    }
  })
}

var downloadHandler = (err, metadata) => {
  assert.equal(err, null)
  debug(`Metadata: ${JSON.stringify(metadata)}`)
  appActions.setUpdateStatus(undefined, undefined, Immutable.fromJS(metadata))
  if (process.platform === 'win32') {
    // check versions to see if an update is required
    if (metadata) {
      autoUpdater.checkForUpdates()
    } else {
      autoUpdater.emit(messages.UPDATE_NOT_AVAILABLE)
    }
  } else {
    autoUpdater.checkForUpdates()
  }
}

// Make network request to check for an available update
exports.checkForUpdate = (verbose) => {
  const updateStatus = AppStore.getState().getIn(['updates', 'status'])
  if (updateStatus !== UpdateStatus.UPDATE_ERROR &&
      updateStatus !== UpdateStatus.UPDATE_NOT_AVAILABLE &&
      updateStatus !== UpdateStatus.UPDATE_NONE) {
    debug('Already checking for updates...')
    requestVersionInfo(undefined, true)
    appActions.setUpdateStatus(undefined, verbose)
    return
  }
  // Force falsy or truthy here so session store will write out a value
  // and it won't auto make updater UI appear periodically.
  appActions.setUpdateStatus(UpdateStatus.UPDATE_CHECKING, !!verbose)
  debug('checkForUpdates')
  try {
    requestVersionInfo(downloadHandler, false)
  } catch (err) {
    debug(err)
  }
}

exports.quitAndInstall = () => {
  autoUpdater.quitAndInstall()
}

// The download is complete, we send a signal and await UI
autoUpdater.on('update-downloaded', (evt, releaseNotes, releaseDate, updateURL) => {
  debug('update downloaded')
  if (releaseNotes) {
    debug(`Release notes : ${releaseNotes}`)
  }
  if (releaseDate) {
    debug(`Release date: ${releaseDate}`)
  }
  if (updateURL) {
    debug(`Update URL: ${updateURL}`)
  }
  appActions.setUpdateStatus(UpdateStatus.UPDATE_AVAILABLE)
})

// Download has started
autoUpdater.on(messages.UPDATE_AVAILABLE, (evt) => {
  debug('update downloading')
  appActions.setUpdateStatus(UpdateStatus.UPDATE_DOWNLOADING)
})

// The current version of the software is up to date
autoUpdater.on(messages.UPDATE_NOT_AVAILABLE, (evt) => {
  debug('update not available')
  appActions.setUpdateStatus(UpdateStatus.UPDATE_NOT_AVAILABLE)
})

// Handle autoUpdater errors (Network, permissions etc...)
autoUpdater.on('error', (err) => {
  appActions.setUpdateStatus(UpdateStatus.UPDATE_ERROR)
  debug(err)
})
<|endoftext|>


<commit_before>function loadWithPho() {
$( ".buttons" ).remove();
$( ".player" ).empty();
var script = document.createElement('script');
script.src = 'https://phosphorus.github.io/embed.js?id=' + Scratch.INIT_DATA.PROJECT.model.id + '&auto-start=true&light-content=false';
var first = document.getElementsByClassName('player')[0];
first.parentNode.insertBefore(script, first);
}
<commit_msg>Delete PhosphorusLoaderSource.js<commit_after><|endoftext|>


<commit_before>/* @flow */
/* eslint-disable react-native/no-unused-styles */
import React, { PureComponent } from 'react';
import { StyleSheet, View } from 'react-native';

import type { Style, Presence } from '../types';
import { statusFromPresence } from '../utils/presence';

const styles = StyleSheet.create({
  common: {
    width: 12,
    height: 12,
    borderRadius: 6,
    borderColor: 'white',
    borderWidth: 2,
  },
  active: {
    backgroundColor: '#44c21d',
  },
  idle: {
    backgroundColor: 'rgba(255, 165, 0, 1)',
  },
  offline: {
    backgroundColor: 'lightgray',
  },
});

type Props = {
  style?: Style,
  presence?: Presence,
  hideIfOffline: boolean,
};

export default class UserStatusIndicator extends PureComponent<Props> {
  props: Props;

  render() {
    const { presence, style, hideIfOffline } = this.props;

    if (!presence || !presence.aggregated) {
      return null;
    }

    const status = statusFromPresence(presence);

    if (hideIfOffline && status === 'offline') {
      return null;
    }

    return <View style={[styles.common, styles[status], style]} />;
  }
}
<commit_msg>jsdoc: Document UserStatusIndicator component.<commit_after>/* @flow */
/* eslint-disable react-native/no-unused-styles */
import React, { PureComponent } from 'react';
import { StyleSheet, View } from 'react-native';

import type { Style, Presence } from '../types';
import { statusFromPresence } from '../utils/presence';

const styles = StyleSheet.create({
  common: {
    width: 12,
    height: 12,
    borderRadius: 6,
    borderColor: 'white',
    borderWidth: 2,
  },
  active: {
    backgroundColor: '#44c21d',
  },
  idle: {
    backgroundColor: 'rgba(255, 165, 0, 1)',
  },
  offline: {
    backgroundColor: 'lightgray',
  },
});

type Props = {
  style?: Style,
  presence?: Presence,
  hideIfOffline: boolean,
};

/**
 * A colored dot indicating user online status.
 * * green if 'online'
 * * orange if 'idle'
 * * gray if 'offline'
 *
 * @prop [style] - Style object for additional customization.
 * @prop [presence] - Presence object used to determine the status from.
 * @prop hideIfOffline - Do not render for 'offline' state.
 */
export default class UserStatusIndicator extends PureComponent<Props> {
  props: Props;

  render() {
    const { presence, style, hideIfOffline } = this.props;

    if (!presence || !presence.aggregated) {
      return null;
    }

    const status = statusFromPresence(presence);

    if (hideIfOffline && status === 'offline') {
      return null;
    }

    return <View style={[styles.common, styles[status], style]} />;
  }
}
<|endoftext|>


<commit_before>/**
 * @file bbn-context component
 *
 * @description bbn-context is a menu that can be activated with a right click.
 * The source of the menu can have a tree structure.
 *
 * @copyright BBN Solutions
 *
 * @created 15/02/2017.
 */

(bbn => {
  "use strict";

  /**
   * Classic input with normalized appearance.
   */
  Vue.component('bbn-context', {
    /**
     * @mixin bbn.vue.basicComponent
     * @mixin bbn.vue.listComponent
     * @mixin bbn.vue.dimensionsComponent
     * @mixin bbn.vue.eventsComponent
     */
    mixins:
    [
      bbn.vue.basicComponent,
      bbn.vue.listComponent,
      bbn.vue.dimensionsComponent,
      bbn.vue.eventsComponent
    ],
    props: {
      /**
       * @prop {Boolean} [false] autobind
       */
      autobind: {
        type: Boolean,
        default: false
      },
      /**
       * @prop {Boolean} [false] disabled
       */
      disabled: {
        type: Boolean,
        default: false
      },
      /**
       * Will force the position.
       * @prop {String} [''] position
       */
      position: {
        type: String,
        default: ''
      },
      /**
       * The html tag used to render the property content.
       * @prop {String} ['span'] tag
       */
       tag: {
        type: String,
        default: 'span'
      },
      /**
       * If defined it will be show at the top of the list.
       * @prop {String} [false] floaterTitle
       */
       floaterTitle: {
        type: [Boolean, String],
        default: false
      },
      /**
       * Set to true to show the floating element containing the menu.
       * @prop {Boolean} [false] context
       * ì
       */
      context: {
        type: Boolean,
        default: false
      },
      /**
       * The content of the context menu.
       * @prop {String} content
       */
      content: {
        type: String
      },
      /**
       * Selection mode.
       * @prop {String} ['free'] mode
       */
      mode: {
        type: String,
        default: 'free'
      },
      /**
       *
       * @prop {String} ['items'] children
       */
      children: {
        type: String,
        default: 'items'
      },
      /**
       * The component used by list's items.
       * @prop {Object|String} itemComponent
       */
      itemComponent: {
        type: [Object, String]
      },
      /**
       * The HTMLElement to bind to.
       * @props {HTMLElement} attach
       */
      attach: {
        type: HTMLElement
      },
      /**
       * The name of the property to be used as action to execute when selected.
       * @prop {String} sourceAction
       * @memberof listComponent
       */
      sourceAction: {
        type: [String, Function],
        default: 'action'
      },
      /**
       * The name of the property to be used as URL to go to when selected.
       * @prop {String} sourceUrl
       * @memberof listComponent
       */
      sourceUrl: {
        type: [String, Function],
        default: 'url'
      },
    },
    data(){
      return {
        /**
         * True if the floating element of the menu is opened.
         * @data {Boolean} [false] showFloater
         */
        showFloater: false,
        /**
         * @data {Boolean} [false] docEvent
         */
        docEvent: false,
        currentLeft: null,
        currentTop: null,
        currentRight: null,
        currentBottom: null
      };
    },
    methods: {
      /**
       * Based on the type of event and on the property context, shows or hides the floating element of the menu.
       * @method clickItem
       * @param {Event} e ì
       * @fires updateData
       */
      clickItem(e){
        if (
          !this.disabled
          && (
            (e.type === 'keydown') ||
            ((e.type === 'contextmenu') && this.context) ||
            ((e.type === 'click') && !this.context)
          )
        ){
          bbn.fn.log('aaaa', e.target)
          if (e.preventDefault) {
            e.preventDefault();
            e.stopPropagation();
          }
          // Don't execute if in the floater
          if (!e.target.closest('.bbn-floater-context-' + this.bbnUid)) {
            if (!this.showFloater && !this.attach) {
              if (e.pageX > bbn.env.width / 2) {
                this.currentLeft = null;
                this.currentRight = bbn.env.width - e.pageX + 5;
              }
              else {
                this.currentLeft = e.pageX - 5;
                this.currentRight = null;
              }

              if (e.pageY > bbn.env.height / 2) {
                this.currentTop = null;
                this.currentBottom = bbn.env.height - e.pageY + 5;
              }
              else {
                this.currentTop = e.pageY - 5;
                this.currentBottom = null;
              }
            }

            this.toggle();
          }
        }
      },
      /**
       * @method clickOut
       * @param e
       */
      clickOut(e){
        if (!e.target.closest('.bbn-floater-context-' + this.bbnUid)) {
          bbn.fn.log('bbbb', e)
          this.showFloater = false;
        }
      },
      /**
       * @method toggle
       */
      toggle(){
        if (!this.showFloater) {
          this.updateData().then(() => {
            this.showFloater = !this.showFloater;
          });
        }
        else {
          this.showFloater = !this.showFloater;
        }
      },
      onMouseDown(e){
        let event = new CustomEvent('mousedown', {
          cancelable: true,
          detail: e
        });
        this.$emit('mousedown', event);
        if (!event.defaultPrevented) {
          e.preventDefault();
          e.stopPropagation();
          return false;
        }
      }
    },
    /**
     * @method beforeDestroy
     */
    beforeDestroy() {
      if (this.docEvent) {
        document.removeEventListener('click', this.clickout)
      }
    },
    watch: {
      showFloater(v){
        if (v) {
          document.addEventListener('click', this.clickOut, true)
          this.docEvent = true;
        }
        else {
          document.removeEventListener('click', this.clickout)
          this.docEvent = false;
        }
      }
    }
  });

})(bbn);
<commit_msg>Removed logs<commit_after>/**
 * @file bbn-context component
 *
 * @description bbn-context is a menu that can be activated with a right click.
 * The source of the menu can have a tree structure.
 *
 * @copyright BBN Solutions
 *
 * @created 15/02/2017.
 */

(bbn => {
  "use strict";

  /**
   * Classic input with normalized appearance.
   */
  Vue.component('bbn-context', {
    /**
     * @mixin bbn.vue.basicComponent
     * @mixin bbn.vue.listComponent
     * @mixin bbn.vue.dimensionsComponent
     * @mixin bbn.vue.eventsComponent
     */
    mixins:
    [
      bbn.vue.basicComponent,
      bbn.vue.listComponent,
      bbn.vue.dimensionsComponent,
      bbn.vue.eventsComponent
    ],
    props: {
      /**
       * @prop {Boolean} [false] autobind
       */
      autobind: {
        type: Boolean,
        default: false
      },
      /**
       * @prop {Boolean} [false] disabled
       */
      disabled: {
        type: Boolean,
        default: false
      },
      /**
       * Will force the position.
       * @prop {String} [''] position
       */
      position: {
        type: String,
        default: ''
      },
      /**
       * The html tag used to render the property content.
       * @prop {String} ['span'] tag
       */
       tag: {
        type: String,
        default: 'span'
      },
      /**
       * If defined it will be show at the top of the list.
       * @prop {String} [false] floaterTitle
       */
       floaterTitle: {
        type: [Boolean, String],
        default: false
      },
      /**
       * Set to true to show the floating element containing the menu.
       * @prop {Boolean} [false] context
       * ì
       */
      context: {
        type: Boolean,
        default: false
      },
      /**
       * The content of the context menu.
       * @prop {String} content
       */
      content: {
        type: String
      },
      /**
       * Selection mode.
       * @prop {String} ['free'] mode
       */
      mode: {
        type: String,
        default: 'free'
      },
      /**
       *
       * @prop {String} ['items'] children
       */
      children: {
        type: String,
        default: 'items'
      },
      /**
       * The component used by list's items.
       * @prop {Object|String} itemComponent
       */
      itemComponent: {
        type: [Object, String]
      },
      /**
       * The HTMLElement to bind to.
       * @props {HTMLElement} attach
       */
      attach: {
        type: HTMLElement
      },
      /**
       * The name of the property to be used as action to execute when selected.
       * @prop {String} sourceAction
       * @memberof listComponent
       */
      sourceAction: {
        type: [String, Function],
        default: 'action'
      },
      /**
       * The name of the property to be used as URL to go to when selected.
       * @prop {String} sourceUrl
       * @memberof listComponent
       */
      sourceUrl: {
        type: [String, Function],
        default: 'url'
      },
    },
    data(){
      return {
        /**
         * True if the floating element of the menu is opened.
         * @data {Boolean} [false] showFloater
         */
        showFloater: false,
        /**
         * @data {Boolean} [false] docEvent
         */
        docEvent: false,
        currentLeft: null,
        currentTop: null,
        currentRight: null,
        currentBottom: null
      };
    },
    methods: {
      /**
       * Based on the type of event and on the property context, shows or hides the floating element of the menu.
       * @method clickItem
       * @param {Event} e ì
       * @fires updateData
       */
      clickItem(e){
        if (
          !this.disabled
          && (
            (e.type === 'keydown') ||
            ((e.type === 'contextmenu') && this.context) ||
            ((e.type === 'click') && !this.context)
          )
        ){
          if (e.preventDefault) {
            e.preventDefault();
            e.stopPropagation();
          }
          // Don't execute if in the floater
          if (!e.target.closest('.bbn-floater-context-' + this.bbnUid)) {
            if (!this.showFloater && !this.attach) {
              if (e.pageX > bbn.env.width / 2) {
                this.currentLeft = null;
                this.currentRight = bbn.env.width - e.pageX + 5;
              }
              else {
                this.currentLeft = e.pageX - 5;
                this.currentRight = null;
              }

              if (e.pageY > bbn.env.height / 2) {
                this.currentTop = null;
                this.currentBottom = bbn.env.height - e.pageY + 5;
              }
              else {
                this.currentTop = e.pageY - 5;
                this.currentBottom = null;
              }
            }

            this.toggle();
          }
        }
      },
      /**
       * @method clickOut
       * @param e
       */
      clickOut(e){
        if (!e.target.closest('.bbn-floater-context-' + this.bbnUid)) {
          this.showFloater = false;
        }
      },
      /**
       * @method toggle
       */
      toggle(){
        if (!this.showFloater) {
          this.updateData().then(() => {
            this.showFloater = !this.showFloater;
          });
        }
        else {
          this.showFloater = !this.showFloater;
        }
      },
      onMouseDown(e){
        let event = new CustomEvent('mousedown', {
          cancelable: true,
          detail: e
        });
        this.$emit('mousedown', event);
        if (!event.defaultPrevented) {
          e.preventDefault();
          e.stopPropagation();
          return false;
        }
      }
    },
    /**
     * @method beforeDestroy
     */
    beforeDestroy() {
      if (this.docEvent) {
        document.removeEventListener('click', this.clickout)
      }
    },
    watch: {
      showFloater(v){
        if (v) {
          document.addEventListener('click', this.clickOut, true)
          this.docEvent = true;
        }
        else {
          document.removeEventListener('click', this.clickout)
          this.docEvent = false;
        }
      }
    }
  });

})(bbn);
<|endoftext|>


<commit_before>function attach_multiselect_detection_events(optionElems,selectElems,callback){
	window.formSelects = {};

	var opts = optionElems || document.getElementsByTagName('option');
	var selects = selectElems || document.getElementsByTagName('select');

	var give_focus = function(){ this.focus(); };

	var handle_ctrl_keypress = function(event){
		var ctrlKeyCode = 17;
		if( event.keyCode === ctrlKeyCode){
			if( event.type === 'keydown'){
				formSelects.ctrlKey = true;
			}else if( event.type === 'keyup'){
				formSelects.ctrlKey = false;
			}
		}
	};

	var exists = function(item,dataset){
		return ( dataset[item] ? true : false );
	};

	var add_remove_selected = function(){
		var child = this;
		var parentID = this.parentNode.id;
		var val = child.value;

		var select = document.getElementById(parentID);
		var optIndex = select.selectedIndex;

		if( !formSelects[parentID] ){
			formSelects[parentID] = { selected : {} };
			formSelects[parentID].selected[val] = 1;
		} else {
			if( formSelects.ctrlKey === true ){
				if( exists(val,formSelects[parentID].selected) ){
					delete formSelects[parentID].selected[val];
				}else{
					formSelects[parentID].selected[val] = 1;
				}
			} else if( !formSelects.ctrlKey || formSelects.ctrlKey === false ){
				delete formSelects[parentID];
				formSelects[parentID] = { selected : {} };
				formSelects[parentID].selected[val] = 1;
			}
		}
		callback();
	};

	var discover_adjacent_selected = function(){
		var	adjacentSelected = [];
		var i = startIndex,
			j = startIndex;

		var child = this;
		var parentID = this.parentNode.id;
		var val = child.value;

		var select = document.getElementById(parentID);
		var optIndex = select.selectedIndex;

		// FIXME: save and return indices of selected elements in addition to values
		while( selectElem.options[i].selected){
			adjacentSelected.push(selectElem.options[i].value);
			++i;
		}

		while(selectElem.options[j].selected){
			adjacentSelected.push(selectElem.options[i].value);
			--j;
		}
		return adjacentSelected;
	};

	for(var i = 0, numOpts = opts.length; i < numOpts; ++i){
		opts[i].onclick = add_remove_selected;
		opts[i].onmouseup = discover_adjacent_selected;
	}

	for(var j = 0, numSelects = selects.length; j < numSelects; ++j){
		selects[j].onmouseover = give_focus;
		selects[j].onkeydown = handle_ctrl_keypress;
		selects[j].onkeyup = handle_ctrl_keypress;
	}
}

function test_events(){
	var parents = Object.keys(formSelects);
	for(var i = 0, numParents = parents.length; i < numParents; ++i){
		if(parents[i] !== 'ctrlKey'){
			console.log( parents[i] + " " + JSON.stringify( formSelects[parents[i]].selected,null,'\t' ) );
		}
	}
}

var allOpts =  document.getElementsByTagName('option');
var allSelects = document.getElementsByTagName('select');

attach_multiselect_detection_events(allOpts,allSelects,test_events);<commit_msg>prototype reorganization<commit_after>function attach_multiselect_detection_events(optionElems,selectElems,callback){
	window.formSelects = {};

	var opts = optionElems || document.getElementsByTagName('option');
	var selects = selectElems || document.getElementsByTagName('select');

	var give_focus = function(){ this.focus(); };

	var handle_ctrl_keypress = function(event){
		var ctrlKeyCode = 17;
		if( event.keyCode === ctrlKeyCode){
			if( event.type === 'keydown'){
				formSelects.ctrlKey = true;
			}else if( event.type === 'keyup'){
				formSelects.ctrlKey = false;
			}
		}
	};

	var exists = function(item,dataset){
		return ( dataset[item] ? true : false );
	};

	var add_remove_selected = function(event){
		var	adjacentSelected = [],
			i = startIndex,
			j = startIndex;

		var child = this,
			parentID = this.parentNode.id,
			val = child.value;

		var select = document.getElementById(parentID);
		var optIndex = select.selectedIndex;

		if(event.type === 'click'){
			handle_click();
		}else{
			var adjacent_selected = discover_adjacent_selected();
		}
		callback();

		var handle_click = function(){
			if( !formSelects[parentID] ){
				formSelects[parentID] = { selected : {} };
				formSelects[parentID].selected[val] = 1;
			} else {
				if( formSelects.ctrlKey === true ){
					if( exists(val,formSelects[parentID].selected) ){
						delete formSelects[parentID].selected[val];
					}else{
						formSelects[parentID].selected[val] = 1;
					}
				} else if( !formSelects.ctrlKey || formSelects.ctrlKey === false ){
					delete formSelects[parentID];
					formSelects[parentID] = { selected : {} };
					formSelects[parentID].selected[val] = 1;
				}
			}
		};

		var discover_adjacent_selected = function(){
			// FIXME: save and return indices of selected elements in addition to values
			while( selectElem.options[i].selected){
				adjacentSelected.push(selectElem.options[i].value);
				++i;
			}

			while(selectElem.options[j].selected){
				adjacentSelected.push(selectElem.options[i].value);
				--j;
			}
			return adjacentSelected;
		};
	};

	for(var i = 0, numOpts = opts.length; i < numOpts; ++i){
		opts[i].onclick = add_remove_selected;
		opts[i].onmouseup = add_remove_selected;
	}

	for(var j = 0, numSelects = selects.length; j < numSelects; ++j){
		selects[j].onmouseover = give_focus;
		selects[j].onkeydown = handle_ctrl_keypress;
		selects[j].onkeyup = handle_ctrl_keypress;
	}
}

function test_events(){
	var parents = Object.keys(formSelects);
	for(var i = 0, numParents = parents.length; i < numParents; ++i){
		if(parents[i] !== 'ctrlKey'){
			console.log( parents[i] + " " + JSON.stringify( formSelects[parents[i]].selected,null,'\t' ) );
		}
	}
}

var allOpts =  document.getElementsByTagName('option');
var allSelects = document.getElementsByTagName('select');

attach_multiselect_detection_events(allOpts,allSelects,test_events);<|endoftext|>