<commit_before>'use strict';
(function(module) {
  try {
    module = angular.module('tink.popover');
  } catch (e) {
    module = angular.module('tink.popover', []);
  }
  module.directive( 'tinkPopover', ['$q','$templateCache','$http','$compile','$timeout','$window','$rootScope',function ($q,$templateCache,$http,$compile,$timeout,$window,$rootScope) {
  return {
    restrict:'EA',
    scope: true,
    compile: function compile( tElement, attrs ) {
      var fetchPromises = {};
      //to retrieve a template;
      function getTemplate(template) {
        // --- if the template already is in our app cache return it. //
        if (fetchPromises[template]){
          return fetchPromises[template];
        }
        // --- If not get the template from templatecache or http. //
        return (fetchPromises[template] = $q.when($templateCache.get(template) || $http.get(template))
          .then(function (res) {
            // --- When the template is retrieved return it. //
            if (angular.isObject(res)) {
              $templateCache.put(template, res.data);
              return res.data;
            }
            return res;
          }));
      }
      var theTemplate = null;
      if(attrs.tinkPopoverTemplate){
        theTemplate = getTemplate(attrs.tinkPopoverTemplate);
      }

      return {
          post: function postLink(scope, element, attributes) {

              var timeoutResize = null;
              var onresizefunc = function () {
                  if (isOpen !== null) {
                      $timeout.cancel(timeoutResize);
                      timeoutResize = $timeout(function () {
                          // setPos(isOpen,placement,align,spacing);
                          calcPos(element, isOpen, placement, align, spacing);
                      }, 250);
                  }
              };

              var onscrollfunc = function () {
                  if (isOpen !== null) {
                      $timeout.cancel(timeoutResize);
                      timeoutResize = $timeout(function () {
                          // setPos(isOpen,placement,align,spacing);
                          calcPos(element, isOpen, placement, align, spacing);
                      }, 450);
                  }
              };

              scope.$on('$destroy', function() {
                  element.off('click');
                  element.off('mouseenter');
                  element.off('mouseleave');
                  $(document).off('click');
                  $window.removeEventListener('resize', onresizefunc);
                  $window.removeEventListener('scroll', onscrollfunc);

              });

          var placement = attributes.tinkPopoverPlace;
          var align = attributes.tinkPopoverAlign;
          var arrow = attributes.tinkArrow;
          var trigger = 'click';
          var spacing = 2;

          var isOpen = null;
          if(trigger === 'click'){
            element.bind('click',function(){
              scope.$apply(function(){
                if(isOpen === null){
                  show();
                }else{
                  hide();
                }

              });
            });
          }else if(trigger === 'hover'){
            element.bind('mouseenter',function(){
              show();
            });
            element.bind('mouseleave',function(){
              hide();
            });
          }

          function popoverHtml(){
            var html = '
'+
                       ''+
                       '
';
            return html;
          }

          function childOf(c,p){ //returns boolean
            while((c=c.parentNode)&&c!==p){
            }
            return !!c;
          }

          $(document).bind('click',function(e){
            var clicked = $(e.target).parents('.popover').last();
            var group = $(e.target).attr('tink-popover-group');
            if(isOpen && !childOf($(e.target).get(0),element.get(0)) && ($(e.target).get(0) !== element.get(0) || clicked.length > 0)){
              if(isOpen.get(0) !== clicked.get(0) &&  $(e.target).get(0) !== isOpen.get(0) && attributes.tinkPopoverGroup !== group){
                hide();
              }
            }
          });

          if(attributes.tinkPopoverGroup){
            scope.$on('popover-open', function(event, args) {

              var group = args.group;
              if(group !== attributes.tinkPopoverGroup && isOpen && $(args.el).get(0) !== isOpen.get(0)){
                hide();
              }
            });
          }

          function show (){
            if(theTemplate !== null){
              theTemplate.then(function(data){
                if(isOpen === null){
                  var elContent =$($compile('
'+data+'
')(scope));
                  var el =$($compile(popoverHtml())(scope));
                  el.css('position','absolute');
                  el.css('visibility','hidden');
                  elContent.insertAfter(el.find('span'));

                  if(placement === 'top'){
                    element.before(el);
                  }else{
                    element.after(el);
                  }

                  el.css('top',-100);
                  el.css('left',-10);

                  calcPos(element,el,placement,align,spacing);

                  if(attributes.tinkPopoverGroup){
                    $rootScope.$broadcast('popover-open', { group: attributes.tinkPopoverGroup,el:el });
                  }

                  isOpen = el;
                }
              });
            }
          }

          $window.addEventListener('resize', onresizefunc, true);

          $window.addEventListener('scroll', onscrollfunc, true);

          function hide(){
            if(isOpen !== null){
              isOpen.remove();
              isOpen = null;
            }
          }

          //The function that will be called to position the tooltip;
          function getPos(el,placement,align,spacing){

            var porcent = {right:0.85,left:0.15,top:0.15,bottom:0.85};

            // Default offset of the popover
            var arrowHeight = 0;
            var arrowWidth = 0;

            // If the popover has an arrow, change the default offset
            if (typeof arrow === 'undefined' || arrow === 'true') {
              arrowHeight = 10;
              arrowWidth = 10;
            }

            var alignLeft = 0;
            var alignTop = 0;
            if(align === 'center'){
              alignLeft = (el.outerWidth(true) / 2)-(element.outerWidth(true)/2);
              alignTop = 0;
            }else if(align === 'left' || align === 'right'){
              alignLeft = (el.outerWidth(true)*porcent[align]) -(element.outerWidth(true)/2);
            }else if(align === 'top' || align === 'bottom'){
              alignTop = 0;
            }

            var left = element.position().left - alignLeft;
            var top = null;
              if(placement === 'top'){
                top = element.position().top - (el.outerHeight() + arrowHeight +spacing);
              }else if(placement === 'bottom'){
                top = element.position().top + element.outerHeight() + arrowHeight +spacing;
              }else if(placement === 'right'){
                left = element.position().left + element.outerWidth(true) + arrowWidth + spacing;
              }else if(placement === 'left'){
                left = element.position().left - el.outerWidth(true)- arrowWidth - spacing;
              }

              if(align === 'right'){
                left = element.position().left + (element.outerWidth(true) - el.outerWidth(true));
              }else if(align === 'left'){
                left = element.position().left;
              }else if(align === 'top'){
                top = element.position().top;
              }else if(align === 'bottom'){
                top = element.position().top - el.outerHeight(true) + element.outerHeight(true);
              }else if(align === 'center'){
                if(placement === 'top' || placement === 'bottom'){
                  left = element.position().left - ((el.outerWidth(true) / 2)-(element.outerWidth(true)/2));
                }else if(placement === 'left' || placement === 'right'){
                  top = element.position().top - ((el.outerHeight(true) / 2)-(element.outerHeight(true)/2));
                }
              }

              return {top:top,left:left,place:placement,align:align};
            }

            function arrowCal(placement,align){
              // show or don't show arrow
              if (typeof arrow === 'undefined' || arrow === 'true') {
                var arrowCss = 'arrow-';
                switch(placement){
                  case 'left':
                    arrowCss = arrowCss + 'right';
                    break;
                  case 'right':
                    arrowCss = arrowCss + 'left';
                    break;
                  case 'top':
                    arrowCss = arrowCss + 'bottom';
                    break;
                  case 'bottom':
                    arrowCss = arrowCss + 'top';
                    break;
                }

                switch(align){
                  case 'center':
                    break;
                  case 'top':
                  case 'bottom':
                    if(placement === 'right' || placement === 'left'){
                      arrowCss = arrowCss + '-' + align;
                    }
                    break;
                  case 'left':
                  case 'right':
                    if(placement === 'top' || placement === 'bottom'){
                      arrowCss = arrowCss + '-' + align;
                    }
                }
                scope.arrowPlacement = arrowCss;
              }
            }
            arrowCal(placement,align);

            //calculate the position
            function calcPos(element,el,place,align,spacing){
              var pageScrollY = ($window.scrollY || $window.pageYOffset);
              var pageScrollX = ($window.scrollX || $window.pageXOffset);

              var w1 = element.offset().left - pageScrollX;
              var w2 = $window.innerWidth - (w1+element.outerWidth(true));
              var h1 = element.offset().top - Math.ceil(parseFloat($('body').css('padding-top'))) - pageScrollY;
              var h2 = $window.innerHeight - (h1+element.outerHeight(true));

              if(place){
                if(place==='top'){
                  if(el.outerHeight(true) + spacing + 10 > h1){
                    place = undefined;
                    align = undefined;
                  }
                }else if (place === 'bottom'){
                  if(el.outerHeight(true) + spacing + 10 > h2){
                    place = undefined;
                    align = undefined;
                  }
                }else if(place === 'left'){
                  if((el.outerWidth(true) - element.outerWidth(true)) > w1){
                    place = undefined;
                    align = undefined;
                  }
                }else if(place === 'right'){
                  if((el.outerWidth(true) - element.outerWidth(true)) > w2){
                    place = undefined;
                    align = undefined;
                  }
                }else{
                  place = undefined;
                  align = undefined;
                }
              }

              if(!place){
                if(h1 > element.outerHeight() || h2 > element.outerHeight()){
                  if(h1 > h2){
                    place = 'top';
                  }else{
                    place = 'bottom';
                  }
                }else if(w1 > element.outerWidth() || w2 > element.outerWidth()){
                  if(w1 > w2){
                    place = 'left';
                  }else {
                    place = ' right';
                  }
                }else{
                  place = 'bottom';
                }
              }
              var val;
              if(align){
                if(place === 'left' || place === 'right'){
                  if(align === 'top'){
                    if((el.outerHeight(true) - element.outerHeight(true))> h2){
                      align = undefined;
                    }
                  }else if(align === 'bottom'){
                    if((el.outerHeight(true) - element.outerHeight(true))> h1){
                      align = undefined;
                    }
                  }else if(align === 'center'){
                    val = (el.outerHeight(true) - element.outerHeight(true)) / 2;
                    if(val > h1 || val > h2){
                      align = undefined;
                    }
                  }

                }else if(place === 'top' || place === 'bottom'){
                  if(align === 'left'){
                    if((el.outerWidth(true) - element.outerWidth(true))> w2){
                      align = undefined;
                    }
                  }else if(align === 'right'){
                    if((el.outerWidth(true) - element.outerWidth(true))> w1){
                      align = undefined;
                    }
                  }else if(align === 'center'){
                    val = (el.outerWidth(true) - element.outerWidth(true))/2;
                    if(val > w1 || val > w2){
                      align = undefined;
                    }
                  }

                }
              }

              if(!align){
                if(place === 'left' || place === 'right'){
                  if(h1 > h2){
                    align = 'bottom';
                  }else {
                    align = 'top';
                  }
                }else if(place === 'top' || place === 'bottom'){
                  if(w1 > w2){
                    align  = 'right';
                  }else{
                    align = 'left';
                  }
                }
              }

              function calcPostInside(){
                var data = getPos(el,place,align,spacing);
                el.css('top',data.top);
                el.css('left',data.left);
                arrowCal(data.place,data.align);
              }

              // calcPostInside();

              $timeout(function(){
                calcPostInside();
                el.css('visibility','visible');
              },20);

              // Fix an early transition
              $timeout(function(){
                el.addClass('popover-transition');
              },250);
            }

          }
        };
      }
    };

  }]);
})();
;<commit_msg>Fix pull request comment.<commit_after>'use strict';
(function(module) {
  try {
    module = angular.module('tink.popover');
  } catch (e) {
    module = angular.module('tink.popover', []);
  }
  module.directive( 'tinkPopover', ['$q','$templateCache','$http','$compile','$timeout','$window','$rootScope',function ($q,$templateCache,$http,$compile,$timeout,$window,$rootScope) {
  return {
    restrict:'EA',
    scope: true,
    compile: function compile( tElement, attrs ) {
      var fetchPromises = {};
      //to retrieve a template;
      function getTemplate(template) {
        // --- if the template already is in our app cache return it. //
        if (fetchPromises[template]){
          return fetchPromises[template];
        }
        // --- If not get the template from templatecache or http. //
        return (fetchPromises[template] = $q.when($templateCache.get(template) || $http.get(template))
          .then(function (res) {
            // --- When the template is retrieved return it. //
            if (angular.isObject(res)) {
              $templateCache.put(template, res.data);
              return res.data;
            }
            return res;
          }));
      }
      var theTemplate = null;
      if(attrs.tinkPopoverTemplate){
        theTemplate = getTemplate(attrs.tinkPopoverTemplate);
      }

      return {
          post: function postLink(scope, element, attributes) {

              var timeoutResize = null;
              var onresizefunc = function () {
                  if (isOpen !== null) {
                      $timeout.cancel(timeoutResize);
                      timeoutResize = $timeout(function () {
                          // setPos(isOpen,placement,align,spacing);
                          calcPos(element, isOpen, placement, align, spacing);
                      }, 250);
                  }
              };

              var onscrollfunc = function () {
                  if (isOpen !== null) {
                      $timeout.cancel(timeoutResize);
                      timeoutResize = $timeout(function () {
                          // setPos(isOpen,placement,align,spacing);
                          calcPos(element, isOpen, placement, align, spacing);
                      }, 450);
                  }
              };

              scope.$on('$destroy', function() {
                  element.off('click');
                  element.off('mouseenter');
                  element.off('mouseleave');
                  $window.removeEventListener('resize', onresizefunc);
                  $window.removeEventListener('scroll', onscrollfunc);

              });

          var placement = attributes.tinkPopoverPlace;
          var align = attributes.tinkPopoverAlign;
          var arrow = attributes.tinkArrow;
          var trigger = 'click';
          var spacing = 2;

          var isOpen = null;
          if(trigger === 'click'){
            element.bind('click',function(){
              scope.$apply(function(){
                if(isOpen === null){
                  show();
                }else{
                  hide();
                }

              });
            });
          }else if(trigger === 'hover'){
            element.bind('mouseenter',function(){
              show();
            });
            element.bind('mouseleave',function(){
              hide();
            });
          }

          function popoverHtml(){
            var html = '
'+
                       ''+
                       '
';
            return html;
          }

          function childOf(c,p){ //returns boolean
            while((c=c.parentNode)&&c!==p){
            }
            return !!c;
          }

          $(document).bind('click',function(e){
            var clicked = $(e.target).parents('.popover').last();
            var group = $(e.target).attr('tink-popover-group');
            if(isOpen && !childOf($(e.target).get(0),element.get(0)) && ($(e.target).get(0) !== element.get(0) || clicked.length > 0)){
              if(isOpen.get(0) !== clicked.get(0) &&  $(e.target).get(0) !== isOpen.get(0) && attributes.tinkPopoverGroup !== group){
                hide();
              }
            }
          });

          if(attributes.tinkPopoverGroup){
            scope.$on('popover-open', function(event, args) {

              var group = args.group;
              if(group !== attributes.tinkPopoverGroup && isOpen && $(args.el).get(0) !== isOpen.get(0)){
                hide();
              }
            });
          }

          function show (){
            if(theTemplate !== null){
              theTemplate.then(function(data){
                if(isOpen === null){
                  var elContent =$($compile('
'+data+'
')(scope));
                  var el =$($compile(popoverHtml())(scope));
                  el.css('position','absolute');
                  el.css('visibility','hidden');
                  elContent.insertAfter(el.find('span'));

                  if(placement === 'top'){
                    element.before(el);
                  }else{
                    element.after(el);
                  }

                  el.css('top',-100);
                  el.css('left',-10);

                  calcPos(element,el,placement,align,spacing);

                  if(attributes.tinkPopoverGroup){
                    $rootScope.$broadcast('popover-open', { group: attributes.tinkPopoverGroup,el:el });
                  }

                  isOpen = el;
                }
              });
            }
          }

          $window.addEventListener('resize', onresizefunc, true);

          $window.addEventListener('scroll', onscrollfunc, true);

          function hide(){
            if(isOpen !== null){
              isOpen.remove();
              isOpen = null;
            }
          }

          //The function that will be called to position the tooltip;
          function getPos(el,placement,align,spacing){

            var porcent = {right:0.85,left:0.15,top:0.15,bottom:0.85};

            // Default offset of the popover
            var arrowHeight = 0;
            var arrowWidth = 0;

            // If the popover has an arrow, change the default offset
            if (typeof arrow === 'undefined' || arrow === 'true') {
              arrowHeight = 10;
              arrowWidth = 10;
            }

            var alignLeft = 0;
            var alignTop = 0;
            if(align === 'center'){
              alignLeft = (el.outerWidth(true) / 2)-(element.outerWidth(true)/2);
              alignTop = 0;
            }else if(align === 'left' || align === 'right'){
              alignLeft = (el.outerWidth(true)*porcent[align]) -(element.outerWidth(true)/2);
            }else if(align === 'top' || align === 'bottom'){
              alignTop = 0;
            }

            var left = element.position().left - alignLeft;
            var top = null;
              if(placement === 'top'){
                top = element.position().top - (el.outerHeight() + arrowHeight +spacing);
              }else if(placement === 'bottom'){
                top = element.position().top + element.outerHeight() + arrowHeight +spacing;
              }else if(placement === 'right'){
                left = element.position().left + element.outerWidth(true) + arrowWidth + spacing;
              }else if(placement === 'left'){
                left = element.position().left - el.outerWidth(true)- arrowWidth - spacing;
              }

              if(align === 'right'){
                left = element.position().left + (element.outerWidth(true) - el.outerWidth(true));
              }else if(align === 'left'){
                left = element.position().left;
              }else if(align === 'top'){
                top = element.position().top;
              }else if(align === 'bottom'){
                top = element.position().top - el.outerHeight(true) + element.outerHeight(true);
              }else if(align === 'center'){
                if(placement === 'top' || placement === 'bottom'){
                  left = element.position().left - ((el.outerWidth(true) / 2)-(element.outerWidth(true)/2));
                }else if(placement === 'left' || placement === 'right'){
                  top = element.position().top - ((el.outerHeight(true) / 2)-(element.outerHeight(true)/2));
                }
              }

              return {top:top,left:left,place:placement,align:align};
            }

            function arrowCal(placement,align){
              // show or don't show arrow
              if (typeof arrow === 'undefined' || arrow === 'true') {
                var arrowCss = 'arrow-';
                switch(placement){
                  case 'left':
                    arrowCss = arrowCss + 'right';
                    break;
                  case 'right':
                    arrowCss = arrowCss + 'left';
                    break;
                  case 'top':
                    arrowCss = arrowCss + 'bottom';
                    break;
                  case 'bottom':
                    arrowCss = arrowCss + 'top';
                    break;
                }

                switch(align){
                  case 'center':
                    break;
                  case 'top':
                  case 'bottom':
                    if(placement === 'right' || placement === 'left'){
                      arrowCss = arrowCss + '-' + align;
                    }
                    break;
                  case 'left':
                  case 'right':
                    if(placement === 'top' || placement === 'bottom'){
                      arrowCss = arrowCss + '-' + align;
                    }
                }
                scope.arrowPlacement = arrowCss;
              }
            }
            arrowCal(placement,align);

            //calculate the position
            function calcPos(element,el,place,align,spacing){
              var pageScrollY = ($window.scrollY || $window.pageYOffset);
              var pageScrollX = ($window.scrollX || $window.pageXOffset);

              var w1 = element.offset().left - pageScrollX;
              var w2 = $window.innerWidth - (w1+element.outerWidth(true));
              var h1 = element.offset().top - Math.ceil(parseFloat($('body').css('padding-top'))) - pageScrollY;
              var h2 = $window.innerHeight - (h1+element.outerHeight(true));

              if(place){
                if(place==='top'){
                  if(el.outerHeight(true) + spacing + 10 > h1){
                    place = undefined;
                    align = undefined;
                  }
                }else if (place === 'bottom'){
                  if(el.outerHeight(true) + spacing + 10 > h2){
                    place = undefined;
                    align = undefined;
                  }
                }else if(place === 'left'){
                  if((el.outerWidth(true) - element.outerWidth(true)) > w1){
                    place = undefined;
                    align = undefined;
                  }
                }else if(place === 'right'){
                  if((el.outerWidth(true) - element.outerWidth(true)) > w2){
                    place = undefined;
                    align = undefined;
                  }
                }else{
                  place = undefined;
                  align = undefined;
                }
              }

              if(!place){
                if(h1 > element.outerHeight() || h2 > element.outerHeight()){
                  if(h1 > h2){
                    place = 'top';
                  }else{
                    place = 'bottom';
                  }
                }else if(w1 > element.outerWidth() || w2 > element.outerWidth()){
                  if(w1 > w2){
                    place = 'left';
                  }else {
                    place = ' right';
                  }
                }else{
                  place = 'bottom';
                }
              }
              var val;
              if(align){
                if(place === 'left' || place === 'right'){
                  if(align === 'top'){
                    if((el.outerHeight(true) - element.outerHeight(true))> h2){
                      align = undefined;
                    }
                  }else if(align === 'bottom'){
                    if((el.outerHeight(true) - element.outerHeight(true))> h1){
                      align = undefined;
                    }
                  }else if(align === 'center'){
                    val = (el.outerHeight(true) - element.outerHeight(true)) / 2;
                    if(val > h1 || val > h2){
                      align = undefined;
                    }
                  }

                }else if(place === 'top' || place === 'bottom'){
                  if(align === 'left'){
                    if((el.outerWidth(true) - element.outerWidth(true))> w2){
                      align = undefined;
                    }
                  }else if(align === 'right'){
                    if((el.outerWidth(true) - element.outerWidth(true))> w1){
                      align = undefined;
                    }
                  }else if(align === 'center'){
                    val = (el.outerWidth(true) - element.outerWidth(true))/2;
                    if(val > w1 || val > w2){
                      align = undefined;
                    }
                  }

                }
              }

              if(!align){
                if(place === 'left' || place === 'right'){
                  if(h1 > h2){
                    align = 'bottom';
                  }else {
                    align = 'top';
                  }
                }else if(place === 'top' || place === 'bottom'){
                  if(w1 > w2){
                    align  = 'right';
                  }else{
                    align = 'left';
                  }
                }
              }

              function calcPostInside(){
                var data = getPos(el,place,align,spacing);
                el.css('top',data.top);
                el.css('left',data.left);
                arrowCal(data.place,data.align);
              }

              // calcPostInside();

              $timeout(function(){
                calcPostInside();
                el.css('visibility','visible');
              },20);

              // Fix an early transition
              $timeout(function(){
                el.addClass('popover-transition');
              },250);
            }

          }
        };
      }
    };

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


<commit_before>const path = require('path');
const webpackMerge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const { DefinePlugin, LoaderOptionsPlugin, NoEmitOnErrorsPlugin } = require('webpack');
const { UglifyJsPlugin } = require('webpack').optimize;
const commonConfig = require('./webpack.common.js');

const ENV = process.env.NODE_ENV = process.env.ENV = 'production';

module.exports = webpackMerge(commonConfig, {
  devtool: 'inline-source-map',

  output: {
    path: path.resolve(__dirname, '../dist'),
    filename: '[name].[hash].js',
    chunkFilename: '[id].[hash].chunk.js'
  },

  plugins: [
    new NoEmitOnErrorsPlugin(),
    new ExtractTextPlugin('[name].[hash].css'),
    new DefinePlugin({
      'process.env': {
        'ENV': JSON.stringify(ENV),
        'NODE_ENV': JSON.stringify(ENV)
      }
    }),
    new UglifyJsPlugin({
      sourceMap: false,
      mangle: {
        keep_fnames: true
      },
      compress: {
        warnings: false
      },
      output: {
        comments: false
      },
    }),
    new LoaderOptionsPlugin({
      htmlLoader: {
        minimize: false
      }
    })
  ],
  devServer: {
    historyApiFallback: true
  }
});
<commit_msg>update prod<commit_after>const path = require('path');
const webpackMerge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const { DefinePlugin, LoaderOptionsPlugin, NoEmitOnErrorsPlugin } = require('webpack');
const { UglifyJsPlugin } = require('webpack').optimize;
const commonConfig = require('./webpack.common.js');

const ENV = process.env.NODE_ENV = process.env.ENV = 'production';

module.exports = webpackMerge(commonConfig, {
  devtool: '',

  output: {
    path: path.resolve(__dirname, '../dist'),
    filename: '[name].[hash].js',
    chunkFilename: '[id].[hash].chunk.js'
  },

  plugins: [
    new NoEmitOnErrorsPlugin(),
    new ExtractTextPlugin('[name].[hash].css'),
    new DefinePlugin({
      'process.env': {
        'ENV': JSON.stringify(ENV),
        'NODE_ENV': JSON.stringify(ENV)
      }
    }),
    new UglifyJsPlugin({
      sourceMap: false,
      mangle: {
        keep_fnames: true
      },
      compress: {
        warnings: false
      },
      output: {
        comments: false
      },
    }),
    new LoaderOptionsPlugin({
      htmlLoader: {
        minimize: false
      }
    })
  ],
  devServer: {
    historyApiFallback: true
  }
});
<|endoftext|>


<commit_before>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2017 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Methods for dragging a block visually.
 * @author fenichel@google.com (Rachel Fenichel)
 */
'use strict';

goog.provide('Blockly.BlockDragger');

goog.require('Blockly.InsertionMarkerManager');

goog.require('goog.math.Coordinate');
goog.require('goog.asserts');

/**
 * Class for a block dragger.  It moves blocks around the workspace when they
 * are being dragged by a mouse or touch.
 * @param {!Blockly.Block} block The block to drag.
 * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on.
 * @constructor
 */
Blockly.BlockDragger = function(block, workspace) {
  /**
   * The top block in the stack that is being dragged.
   * @type {!Blockly.BlockSvg}
   * @private
   */
  this.draggingBlock_ = block;

  /**
   * The workspace on which the block is being dragged.
   * @type {!Blockly.WorkspaceSvg}
   * @private
   */
  this.workspace_ = workspace;

  /**
   * Object that keeps track of connections on dragged blocks.
   * @type {!Blockly.InsertionMarkerManager}
   * @private
   */
  this.draggedConnectionManager_ = new Blockly.InsertionMarkerManager(
      this.draggingBlock_);

  /**
   * Which delete area the mouse pointer is over, if any.
   * One of {@link Blockly.DELETE_AREA_TRASH},
   * {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}.
   * @type {?number}
   * @private
   */
  this.deleteArea_ = null;

  /**
   * Whether the block would be deleted if dropped immediately.
   * @type {boolean}
   * @private
   */
  this.wouldDeleteBlock_ = false;

  /**
   * The location of the top left corner of the dragging block at the beginning
   * of the drag in workspace coordinates.
   * @type {!goog.math.Coordinate}
   * @private
   */
  this.startXY_ = this.draggingBlock_.getRelativeToSurfaceXY();

  /**
   * A list of all of the icons (comment, warning, and mutator) that are
   * on this block and its descendants.  Moving an icon moves the bubble that
   * extends from it if that bubble is open.
   * @type {Array.<!Object>}
   * @private
   */
  this.dragIconData_ = Blockly.BlockDragger.initIconData_(block);
};

/**
 * Sever all links from this object.
 * @package
 */
Blockly.BlockDragger.prototype.dispose = function() {
  this.draggingBlock_ = null;
  this.workspace_ = null;
  this.startWorkspace_ = null;
  this.dragIconData_.length = 0;

  if (this.draggedConnectionManager_) {
    this.draggedConnectionManager_.dispose();
    this.draggedConnectionManager_ = null;
  }
};

/**
 * Make a list of all of the icons (comment, warning, and mutator) that are
 * on this block and its descendants.  Moving an icon moves the bubble that
 * extends from it if that bubble is open.
 * @param {!Blockly.BlockSvg} block The root block that is being dragged.
 * @return {!Array.<!Object>} The list of all icons and their locations.
 * @private
 */
Blockly.BlockDragger.initIconData_ = function(block) {
  // Build a list of icons that need to be moved and where they started.
  var dragIconData = [];
  var descendants = block.getDescendants();
  for (var i = 0, descendant; descendant = descendants[i]; i++) {
    var icons = descendant.getIcons();
    for (var j = 0; j < icons.length; j++) {
      var data = {
        // goog.math.Coordinate with x and y properties (workspace coordinates).
        location: icons[j].getIconLocation(),
        // Blockly.Icon
        icon: icons[j]
      };
      dragIconData.push(data);
    }
  }
  return dragIconData;
};

/**
 * Start dragging a block.  This includes moving it to the drag surface.
 * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
 *     moved from the position at mouse down, in pixel units.
 * @package
 */
Blockly.BlockDragger.prototype.startBlockDrag = function(currentDragDeltaXY) {
  if (!Blockly.Events.getGroup()) {
    Blockly.Events.setGroup(true);
  }

  this.workspace_.setResizesEnabled(false);
  Blockly.BlockSvg.disconnectUiStop_();

  if (this.draggingBlock_.getParent()) {
    this.draggingBlock_.unplug();
    var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
    var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);

    this.draggingBlock_.translate(newLoc.x, newLoc.y);
    this.draggingBlock_.disconnectUiEffect();
  }
  this.draggingBlock_.setDragging(true);
  // For future consideration: we may be able to put moveToDragSurface inside
  // the block dragger, which would also let the block not track the block drag
  // surface.
  this.draggingBlock_.moveToDragSurface_();

  if (this.workspace_.toolbox_) {
    this.workspace_.toolbox_.addDeleteStyle();
  }
};

/**
 * Execute a step of block dragging, based on the given event.  Update the
 * display accordingly.
 * @param {!Event} e The most recent move event.
 * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
 *     moved from the position at the start of the drag, in pixel units.
 * @package
 */
Blockly.BlockDragger.prototype.dragBlock = function(e, currentDragDeltaXY) {
  var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
  var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);

  this.draggingBlock_.moveDuringDrag(newLoc);
  this.dragIcons_(delta);

  this.deleteArea_ = this.workspace_.isDeleteArea(e);
  this.draggedConnectionManager_.update(delta, this.deleteArea_);

  this.updateCursorDuringBlockDrag_();
};

/**
 * Finish a block drag and put the block back on the workspace.
 * @param {!Event} e The mouseup/touchend event.
 * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
 *     moved from the position at the start of the drag, in pixel units.
 * @package
 */
Blockly.BlockDragger.prototype.endBlockDrag = function(e, currentDragDeltaXY) {
  // Make sure internal state is fresh.
  this.dragBlock(e, currentDragDeltaXY);
  this.dragIconData_ = [];

  Blockly.BlockSvg.disconnectUiStop_();

  var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
  var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
  this.draggingBlock_.moveOffDragSurface_(newLoc);

  var deleted = this.maybeDeleteBlock_();
  if (!deleted) {
    // These are expensive and don't need to be done if we're deleting.
    this.draggingBlock_.moveConnections_(delta.x, delta.y);
    this.draggingBlock_.setDragging(false);
    this.draggedConnectionManager_.applyConnections();
    this.draggingBlock_.render();
    this.fireMoveEvent_();
    this.draggingBlock_.scheduleSnapAndBump();
  }
  this.workspace_.setResizesEnabled(true);

  if (this.workspace_.toolbox_) {
    this.workspace_.toolbox_.removeDeleteStyle();
  }
  Blockly.Events.setGroup(false);
};

/**
 * Fire a move event at the end of a block drag.
 * @private
 */
Blockly.BlockDragger.prototype.fireMoveEvent_ = function() {
  var event = new Blockly.Events.BlockMove(this.draggingBlock_);
  event.oldCoordinate = this.startXY_;
  event.recordNew();
  Blockly.Events.fire(event);
};

/**
 * Shut the trash can and, if necessary, delete the dragging block.
 * Should be called at the end of a block drag.
 * @return {boolean} whether the block was deleted.
 * @private
 */
Blockly.BlockDragger.prototype.maybeDeleteBlock_ = function() {
  var trashcan = this.workspace_.trashcan;

  if (this.wouldDeleteBlock_) {
    if (trashcan) {
      goog.Timer.callOnce(trashcan.close, 100, trashcan);
    }
    // Fire a move event, so we know where to go back to for an undo.
    this.fireMoveEvent_();
    this.draggingBlock_.dispose(false, true);
  } else if (trashcan) {
    // Make sure the trash can is closed.
    trashcan.close();
  }
  return this.wouldDeleteBlock_;
};

/**
 * Update the cursor (and possibly the trash can lid) to reflect whether the
 * dragging block would be deleted if released immediately.
 * @private
 */
Blockly.BlockDragger.prototype.updateCursorDuringBlockDrag_ = function() {
  this.wouldDeleteBlock_ = this.draggedConnectionManager_.wouldDeleteBlock();
  var trashcan = this.workspace_.trashcan;
  if (this.wouldDeleteBlock_) {
    this.draggingBlock_.setDeleteStyle(true);
    if (this.deleteArea_ == Blockly.DELETE_AREA_TRASH && trashcan) {
      trashcan.setOpen_(true);
    }
  } else {
    this.draggingBlock_.setDeleteStyle(false);
    if (trashcan) {
      trashcan.setOpen_(false);
    }
  }
};

/**
 * Convert a coordinate object from pixels to workspace units, including a
 * correction for mutator workspaces.
 * This function does not consider differing origins.  It simply scales the
 * input's x and y values.
 * @param {!goog.math.Coordinate} pixelCoord A coordinate with x and y values
 *     in css pixel units.
 * @return {!goog.math.Coordinate} The input coordinate divided by the workspace
 *     scale.
 * @private
 */
Blockly.BlockDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) {
  var result = new goog.math.Coordinate(pixelCoord.x / this.workspace_.scale,
      pixelCoord.y / this.workspace_.scale);
  if (this.workspace_.isMutator) {
    // If we're in a mutator, its scale is always 1, purely because of some
    // oddities in our rendering optimizations.  The actual scale is the same as
    // the scale on the parent workspace.
    // Fix that for dragging.
    var mainScale = this.workspace_.options.parentWorkspace.scale;
    result = result.scale(1 / mainScale);
  }
  return result;
};

/**
 * Move all of the icons connected to this drag.
 * @param {!goog.math.Coordinate} dxy How far to move the icons from their
 *     original positions, in workspace units.
 * @private
 */
Blockly.BlockDragger.prototype.dragIcons_ = function(dxy) {
  // Moving icons moves their associated bubbles.
  for (var i = 0; i < this.dragIconData_.length; i++) {
    var data = this.dragIconData_[i];
    data.icon.setIconLocation(goog.math.Coordinate.sum(data.location, dxy));
  }
};
<commit_msg>Roll back drag definition deletion if it orphans call blocks.<commit_after>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2017 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Methods for dragging a block visually.
 * @author fenichel@google.com (Rachel Fenichel)
 */
'use strict';

goog.provide('Blockly.BlockDragger');

goog.require('Blockly.InsertionMarkerManager');

goog.require('goog.math.Coordinate');
goog.require('goog.asserts');

/**
 * Class for a block dragger.  It moves blocks around the workspace when they
 * are being dragged by a mouse or touch.
 * @param {!Blockly.Block} block The block to drag.
 * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on.
 * @constructor
 */
Blockly.BlockDragger = function(block, workspace) {
  /**
   * The top block in the stack that is being dragged.
   * @type {!Blockly.BlockSvg}
   * @private
   */
  this.draggingBlock_ = block;

  /**
   * The workspace on which the block is being dragged.
   * @type {!Blockly.WorkspaceSvg}
   * @private
   */
  this.workspace_ = workspace;

  /**
   * Object that keeps track of connections on dragged blocks.
   * @type {!Blockly.InsertionMarkerManager}
   * @private
   */
  this.draggedConnectionManager_ = new Blockly.InsertionMarkerManager(
      this.draggingBlock_);

  /**
   * Which delete area the mouse pointer is over, if any.
   * One of {@link Blockly.DELETE_AREA_TRASH},
   * {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}.
   * @type {?number}
   * @private
   */
  this.deleteArea_ = null;

  /**
   * Whether the block would be deleted if dropped immediately.
   * @type {boolean}
   * @private
   */
  this.wouldDeleteBlock_ = false;

  /**
   * The location of the top left corner of the dragging block at the beginning
   * of the drag in workspace coordinates.
   * @type {!goog.math.Coordinate}
   * @private
   */
  this.startXY_ = this.draggingBlock_.getRelativeToSurfaceXY();

  /**
   * A list of all of the icons (comment, warning, and mutator) that are
   * on this block and its descendants.  Moving an icon moves the bubble that
   * extends from it if that bubble is open.
   * @type {Array.<!Object>}
   * @private
   */
  this.dragIconData_ = Blockly.BlockDragger.initIconData_(block);
};

/**
 * Sever all links from this object.
 * @package
 */
Blockly.BlockDragger.prototype.dispose = function() {
  this.draggingBlock_ = null;
  this.workspace_ = null;
  this.startWorkspace_ = null;
  this.dragIconData_.length = 0;

  if (this.draggedConnectionManager_) {
    this.draggedConnectionManager_.dispose();
    this.draggedConnectionManager_ = null;
  }
};

/**
 * Make a list of all of the icons (comment, warning, and mutator) that are
 * on this block and its descendants.  Moving an icon moves the bubble that
 * extends from it if that bubble is open.
 * @param {!Blockly.BlockSvg} block The root block that is being dragged.
 * @return {!Array.<!Object>} The list of all icons and their locations.
 * @private
 */
Blockly.BlockDragger.initIconData_ = function(block) {
  // Build a list of icons that need to be moved and where they started.
  var dragIconData = [];
  var descendants = block.getDescendants();
  for (var i = 0, descendant; descendant = descendants[i]; i++) {
    var icons = descendant.getIcons();
    for (var j = 0; j < icons.length; j++) {
      var data = {
        // goog.math.Coordinate with x and y properties (workspace coordinates).
        location: icons[j].getIconLocation(),
        // Blockly.Icon
        icon: icons[j]
      };
      dragIconData.push(data);
    }
  }
  return dragIconData;
};

/**
 * Start dragging a block.  This includes moving it to the drag surface.
 * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
 *     moved from the position at mouse down, in pixel units.
 * @package
 */
Blockly.BlockDragger.prototype.startBlockDrag = function(currentDragDeltaXY) {
  if (!Blockly.Events.getGroup()) {
    Blockly.Events.setGroup(true);
  }

  this.workspace_.setResizesEnabled(false);
  Blockly.BlockSvg.disconnectUiStop_();

  if (this.draggingBlock_.getParent()) {
    this.draggingBlock_.unplug();
    var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
    var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);

    this.draggingBlock_.translate(newLoc.x, newLoc.y);
    this.draggingBlock_.disconnectUiEffect();
  }
  this.draggingBlock_.setDragging(true);
  // For future consideration: we may be able to put moveToDragSurface inside
  // the block dragger, which would also let the block not track the block drag
  // surface.
  this.draggingBlock_.moveToDragSurface_();

  if (this.workspace_.toolbox_) {
    this.workspace_.toolbox_.addDeleteStyle();
  }
};

/**
 * Execute a step of block dragging, based on the given event.  Update the
 * display accordingly.
 * @param {!Event} e The most recent move event.
 * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
 *     moved from the position at the start of the drag, in pixel units.
 * @package
 */
Blockly.BlockDragger.prototype.dragBlock = function(e, currentDragDeltaXY) {
  var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
  var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);

  this.draggingBlock_.moveDuringDrag(newLoc);
  this.dragIcons_(delta);

  this.deleteArea_ = this.workspace_.isDeleteArea(e);
  this.draggedConnectionManager_.update(delta, this.deleteArea_);

  this.updateCursorDuringBlockDrag_();
};

/**
 * Finish a block drag and put the block back on the workspace.
 * @param {!Event} e The mouseup/touchend event.
 * @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
 *     moved from the position at the start of the drag, in pixel units.
 * @package
 */
Blockly.BlockDragger.prototype.endBlockDrag = function(e, currentDragDeltaXY) {
  // Make sure internal state is fresh.
  this.dragBlock(e, currentDragDeltaXY);
  this.dragIconData_ = [];

  Blockly.BlockSvg.disconnectUiStop_();

  var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
  var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
  this.draggingBlock_.moveOffDragSurface_(newLoc);

  // Scratch-specific: note possible illegal definition deletion for rollback below.
  var isDeletingProcDef = this.wouldDeleteBlock_ &&
      (this.draggingBlock_.type == Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE);

  var deleted = this.maybeDeleteBlock_();
  if (!deleted) {
    // These are expensive and don't need to be done if we're deleting.
    this.draggingBlock_.moveConnections_(delta.x, delta.y);
    this.draggingBlock_.setDragging(false);
    this.draggedConnectionManager_.applyConnections();
    this.draggingBlock_.render();
    this.fireMoveEvent_();
    this.draggingBlock_.scheduleSnapAndBump();
  }
  this.workspace_.setResizesEnabled(true);

  if (this.workspace_.toolbox_) {
    this.workspace_.toolbox_.removeDeleteStyle();
  }
  Blockly.Events.setGroup(false);

  // Scratch-specific: roll back deletes that create call blocks with defines.
  // Have to wait for connections to be re-established, so put in setTimeout.
  // Only do this if we deleted a proc def.
  if (isDeletingProcDef) {
    var ws = this.workspace_;
    setTimeout(function() {
      var allBlocks = ws.getAllBlocks();
      for (var i = 0; i < allBlocks.length; i++) {
        var block = allBlocks[i];
        if (block.type == Blockly.PROCEDURES_CALL_BLOCK_TYPE) {
          var procCode = block.getProcCode();
          // Check for call blocks with no associated define block.
          if (!Blockly.Procedures.getDefineBlock(procCode, ws)) {
            // TODO:(#1151)
            alert('To delete a block definition, first remove all uses of the block');
            ws.undo();
            return; // There can only be one define deletion at a time.
          }
        }
      }
      // The proc deletion was valid, update the toolbox.
      ws.refreshToolboxSelection_();
    });
  }
};

/**
 * Fire a move event at the end of a block drag.
 * @private
 */
Blockly.BlockDragger.prototype.fireMoveEvent_ = function() {
  var event = new Blockly.Events.BlockMove(this.draggingBlock_);
  event.oldCoordinate = this.startXY_;
  event.recordNew();
  Blockly.Events.fire(event);
};

/**
 * Shut the trash can and, if necessary, delete the dragging block.
 * Should be called at the end of a block drag.
 * @return {boolean} whether the block was deleted.
 * @private
 */
Blockly.BlockDragger.prototype.maybeDeleteBlock_ = function() {
  var trashcan = this.workspace_.trashcan;

  if (this.wouldDeleteBlock_) {
    if (trashcan) {
      goog.Timer.callOnce(trashcan.close, 100, trashcan);
    }
    // Fire a move event, so we know where to go back to for an undo.
    this.fireMoveEvent_();
    this.draggingBlock_.dispose(false, true);
  } else if (trashcan) {
    // Make sure the trash can is closed.
    trashcan.close();
  }
  return this.wouldDeleteBlock_;
};

/**
 * Update the cursor (and possibly the trash can lid) to reflect whether the
 * dragging block would be deleted if released immediately.
 * @private
 */
Blockly.BlockDragger.prototype.updateCursorDuringBlockDrag_ = function() {
  this.wouldDeleteBlock_ = this.draggedConnectionManager_.wouldDeleteBlock();
  var trashcan = this.workspace_.trashcan;
  if (this.wouldDeleteBlock_) {
    this.draggingBlock_.setDeleteStyle(true);
    if (this.deleteArea_ == Blockly.DELETE_AREA_TRASH && trashcan) {
      trashcan.setOpen_(true);
    }
  } else {
    this.draggingBlock_.setDeleteStyle(false);
    if (trashcan) {
      trashcan.setOpen_(false);
    }
  }
};

/**
 * Convert a coordinate object from pixels to workspace units, including a
 * correction for mutator workspaces.
 * This function does not consider differing origins.  It simply scales the
 * input's x and y values.
 * @param {!goog.math.Coordinate} pixelCoord A coordinate with x and y values
 *     in css pixel units.
 * @return {!goog.math.Coordinate} The input coordinate divided by the workspace
 *     scale.
 * @private
 */
Blockly.BlockDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) {
  var result = new goog.math.Coordinate(pixelCoord.x / this.workspace_.scale,
      pixelCoord.y / this.workspace_.scale);
  if (this.workspace_.isMutator) {
    // If we're in a mutator, its scale is always 1, purely because of some
    // oddities in our rendering optimizations.  The actual scale is the same as
    // the scale on the parent workspace.
    // Fix that for dragging.
    var mainScale = this.workspace_.options.parentWorkspace.scale;
    result = result.scale(1 / mainScale);
  }
  return result;
};

/**
 * Move all of the icons connected to this drag.
 * @param {!goog.math.Coordinate} dxy How far to move the icons from their
 *     original positions, in workspace units.
 * @private
 */
Blockly.BlockDragger.prototype.dragIcons_ = function(dxy) {
  // Moving icons moves their associated bubbles.
  for (var i = 0; i < this.dragIconData_.length; i++) {
    var data = this.dragIconData_[i];
    data.icon.setIconLocation(goog.math.Coordinate.sum(data.location, dxy));
  }
};
<|endoftext|>


<commit_before>'use strict';

var initObjectIdGenerator = require('./');
var assert = require('assert');

describe('objectid-stub', function() {
  var objectIdStub;

    describe('without options', function() {

      beforeEach(function() {
        objectIdStub = initObjectIdGenerator();
      });

      it('should work as expected', function() {
        assert.equal(objectIdStub(), 'abbacaca6a6affffffffffff');

        assert.equal(objectIdStub.next(), objectIdStub());

        assert.equal(objectIdStub(), 'abbacaca6a6afffffffffffd');

        objectIdStub.reset();

        assert.equal(objectIdStub(), 'abbacaca6a6affffffffffff');
      });

    });

    describe('with prefix option', function() {

      beforeEach(function() {
        objectIdStub = initObjectIdGenerator({
          prefix: '570b570b570b',
        });
      });

      it('should work as expected', function() {
        assert.equal(objectIdStub(), '570b570b570bffffffffffff');

        assert.equal(objectIdStub.next(), objectIdStub());

        assert.equal(objectIdStub(), '570b570b570bfffffffffffd');

        objectIdStub.reset('570b570b570b');

        assert.equal(objectIdStub(), '570b570b570bffffffffffff');
      });

    });

  describe('with ctor option', function() {

    beforeEach(function() {
      objectIdStub = initObjectIdGenerator({ ctor: String });
    });

    it('should work as expected', function() {
      assert.equal(objectIdStub().toString(), 'abbacaca6a6affffffffffff');

      assert.equal(objectIdStub.next().toString(), objectIdStub().toString());

      assert.equal(objectIdStub().toString(), 'abbacaca6a6afffffffffffd');

      objectIdStub.reset();

      assert.equal(objectIdStub().toString(), 'abbacaca6a6affffffffffff');
    });

  });

});
<commit_msg>Suppress eslint warnings<commit_after>'use strict';

var initObjectIdGenerator = require('./');
var assert = require('assert');

describe('objectid-stub', function() {
  var objectIdStub;

  describe('without options', function() {

    beforeEach(function() {
      objectIdStub = initObjectIdGenerator();
    });

    it('should work as expected', function() {
      assert.equal(objectIdStub(), 'abbacaca6a6affffffffffff');

      assert.equal(objectIdStub.next(), objectIdStub());

      assert.equal(objectIdStub(), 'abbacaca6a6afffffffffffd');

      objectIdStub.reset();

      assert.equal(objectIdStub(), 'abbacaca6a6affffffffffff');
    });

  });

  describe('with prefix option', function() {

    beforeEach(function() {
      objectIdStub = initObjectIdGenerator({
        prefix: '570b570b570b',
      });
    });

    it('should work as expected', function() {
      assert.equal(objectIdStub(), '570b570b570bffffffffffff');

      assert.equal(objectIdStub.next(), objectIdStub());

      assert.equal(objectIdStub(), '570b570b570bfffffffffffd');

      objectIdStub.reset('570b570b570b');

      assert.equal(objectIdStub(), '570b570b570bffffffffffff');
    });

  });

  describe('with ctor option', function() {

    beforeEach(function() {
      objectIdStub = initObjectIdGenerator({ ctor: String });
    });

    it('should work as expected', function() {
      assert.equal(objectIdStub().toString(), 'abbacaca6a6affffffffffff');

      assert.equal(objectIdStub.next().toString(), objectIdStub().toString());

      assert.equal(objectIdStub().toString(), 'abbacaca6a6afffffffffffd');

      objectIdStub.reset();

      assert.equal(objectIdStub().toString(), 'abbacaca6a6affffffffffff');
    });

  });

});
<|endoftext|>


<commit_before>var
	fs = require('fs'),
	url = require('url'),
	path = require('path'),
	exec = require('child_process').exec,
	jsdom = require('jsdom'),
	dom = require('./dom'),
	jady = require('./jady');

var
	opts = require('../options'),
	publicPath = opts.common.pathToSpecs;

module.exports = function reply(req, res, next) {
	var
		parsedUrl = url.parse(req.url, true),
		urlPath = parsedUrl.pathname,
		urlHost = req.headers.host,
		urlAdress = (parsedUrl.protocol || "") + urlHost + urlPath,
		tpl = parsedUrl.query.get,
		id = parsedUrl.query.id,
		wrap = parsedUrl.query.wrap || true,
        phantom = parsedUrl.query.ph || false;
//debugger;

//// if we have query on index.html
	if (path.basename(parsedUrl.path).indexOf('index.html') != -1 && parsedUrl.query.get) {
// reading file..
		fs.readFile(publicPath + '/' + urlPath, function (err, data) {
            var responseData = data || '';

            if (err) res.end('Huston, we have 404.\n'+ err);

            if (responseData !== '') {

                // make data for template
                function reqHandler(res, html) {
                    if (html.source) {
                        //// переменные для Jade
                        var locals = {
                            head: {
                                title: html.title,
                                mAuthor: html.meta.author,
                                mKeywords: html.meta.keywords,
                                mDescription: html.meta.description,
                                scripts: html.scripts,
                                stylesheets: html.styles
                            },
                            body: {
                                spec: html.source.content,
                                specLength: html.source.length,
                                specId: html.source.id,
                                specIdSum: html.source.idSum,
                                homeLink: 'http://'+ urlAdress
                            },
                            pretty: true
                        };

                        res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
                        res.end(jady(locals, tpl));

                    } else res.end('STDOUT: can\'t recieve content.');
                }

        // if using PhantomJs
                if (phantom) {

                    var params = "core/clarify/phantomjs "+
                        "core/clarify/phantom/ph.js "+
                        "http://"+ urlAdress +" "+ id +" "+ wrap;

                    // executes ph.js via phantomjs like separate child process
                    exec(params, function (err, stdout, stderr) {
                        if (err) console.log('Exec report error: ' + err);
                        else {
                            try {
                                var html = JSON.parse(stdout);
                            } catch(e) {
                                html = 'Parsing error: ' + e;
                            }
        // PhantomJS output
        console.log(html);
        // got to show some view
                            reqHandler(res, html);
                        }
                    });

                }
        // jsdom starts
                else {
                    jsdom.env(responseData.toString(), function (err, win) {
        // 	     		jsdom.env(publicPath + '/' + urlPath, function (err, win) { // url mode
                        if (err) console.log('JSdom report error: ' + err);
                        else {
                            console.log('JSDOM', wrap);
                            var
                                doc = win.document,
                                html = {};

                            try {
                                html.title = doc.title;
                                html.meta = dom.getMeta(doc);
                                html.styles = dom.getHeadData(doc)[0];
                                html.scripts = dom.getHeadData(doc)[1];
                                html.source = dom.getSource(doc, id, wrap);
                            } catch (e) {
                                html.err = {
                                    text: e,
                                    type: e.name
                                };
                            }
        console.log(html);

        // got to show some view
                            reqHandler(res, html);
                        }
                    });
                }

            }
		});
	} else next();
};

// TODO: check list below
// [done] beatify HTML output
// [done] create JSON with data from <HEAD>
// [done] parse several blocks in same page with one request
// [done] switchers to another specs from cleared one;
// [done] clear template - @param {GET} clr
// [done] phantomjs -> jsdom
// [..partial] client-side UI controls to clarify specs
// [...] support for other template engines
// * [] Add check for OS, if not Mac, then link to other phantomjs binary, that need to be git ignored and custom description about the lack of it with installation instructions must be provided
// * [] connect custom templates and scripts
// * [] avoid hardcoded paths
// * [] use css/js optionally by GET params
// * [] save user session settings
// * [] try POST instead GET
// * [] Ajax
// * [] link from already clarified code to original spec page
// * [] phantomjs error with try to get unavaliable script
// * [] screenshots by phatnomjs
// * [] phantomjs: not to close session (improve perfomance?);
// * [] buttons  to add custom libraries to clarified page (jQuery, require);
// * [] another context templates [mob, clr, ...]
<commit_msg>Fixing merge bug<commit_after>var
	fs = require('fs'),
	url = require('url'),
	path = require('path'),
	exec = require('child_process').exec,
	jsdom = require('jsdom'),
	dom = require('./dom'),
	jady = require('./jady');

var
	opts = require('../options'),
	publicPath = opts.common.pathToSpecs;

module.exports = function reply(req, res, next) {
	var
		parsedUrl = url.parse(req.url, true),
		urlPath = parsedUrl.pathname,
		urlHost = req.headers.host,
		urlAdress = (parsedUrl.protocol || "") + urlHost + urlPath,
		tpl = parsedUrl.query.get,
		id = parsedUrl.query.id,
		wrap = parsedUrl.query.wrap || true,
        phantom = parsedUrl.query.ph || false;

//// check if we have queried on file nor in navigation
	if (path.basename(parsedUrl.path).match(/.+\..+/i) && parsedUrl.query.get) {

// reading file
		fs.readFile(publicPath + '/' + urlPath, function (err, data) {
            if (err) {
                res.end('No such file.\n'+ err);
                return;
            }

                // make data for template
                function reqHandler(res, html) {
                    if (html.source) {
                        //// переменные для Jade
                        var locals = {
                            head: {
                                title: html.title,
                                mAuthor: html.meta.author,
                                mKeywords: html.meta.keywords,
                                mDescription: html.meta.description,
                                scripts: html.scripts,
                                stylesheets: html.styles
                            },
                            body: {
                                spec: html.source.content,
                                specLength: html.source.length,
                                specId: html.source.id,
                                specIdSum: html.source.idSum,
                                homeLink: 'http://'+ urlAdress
                            },
                            pretty: true
                        };

                        res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
                        res.end(jady(locals, tpl));

                    } else res.end('STDOUT: can\'t recieve content.');
                }

        // if using PhantomJs
                if (phantom) {

                var params = "core/clarify/phantomjs "+
                        "core/clarify/phantom/ph.js "+
                        "http://"+ urlAdress +" "+ id +" "+ wrap;

// executes ph.js by phantomjs in new process
                    exec(params, function (err, stdout, stderr) {
                    if (err) res.end('Exec report error:\n ' + err);
                        else {
                            try {
                                var html = JSON.parse(stdout);
                            } catch(e) {
                                html = 'Parsing error: ' + e;
                            }
        // PhantomJS output
        console.log(html);
        // got to show some view
                            reqHandler(res, html);
                        }
                    });

        // jsdom starts
            } else {
                jsdom.env(data.toString(), function (err, win) {
        // 	     		jsdom.env(publicPath + '/' + urlPath, function (err, win) { // url mode
                    if (err) res.end('JSdom report error:\n ' + err);
                        else {
                            console.log('JSDOM', wrap);
                            var
                                doc = win.document,
                                html = {};

                            try {
                                html.title = doc.title;
                                html.meta = dom.getMeta(doc);
                                html.styles = dom.getHeadData(doc)[0];
                                html.scripts = dom.getHeadData(doc)[1];
                                html.source = dom.getSource(doc, id, wrap);
                            } catch (e) {
                                html.err = {
                                    text: e,
                                    type: e.name
                                };
                            }
        console.log(html);

    // show template
                            reqHandler(res, html);
                        }
                    });
                }

		});
	} else next();
};

// TODO: check list below
// [done] beatify HTML output
// [done] create JSON with data from <HEAD>
// [done] parse several blocks in same page with one request
// [done] switchers to another specs from cleared one;
// [done] clear template - @param {GET} clr
// [done] phantomjs -> jsdom
// [..partial] client-side UI controls to clarify specs
// [...] support for other template engines
// * [] diffrernt links to phantomjs relative to OS
// * [] connect custom templates and scripts
// * [] avoid hardcoded paths
// * [] use css/js optionally by GET params
// * [] save user session settings
// * [] try POST instead GET
// * [] Ajax
// * [] link from already clarified code to original spec page
// * [] phantomjs error with try to get unavaliable script
// * [] screenshots by phatnomjs
// * [] phantomjs: not to close session (improve perfomance?);
// * [] buttons  to add custom libraries to clarified page (jQuery, require);
// * [in progress..] another context templates [mob, clr, ...]
<|endoftext|>


<commit_before>/*global Resumable, FLOW, $, Ember */

FLOW.uuid = function (file) {
  return Math.uuidFast();
};

FLOW.uploader = Ember.Object.create({
  r: new Resumable({
    target: FLOW.Env.flowServices + '/upload',
    uploadDomain: FLOW.Env.surveyuploadurl.split('/')[2],
    simultaneousUploads: 1,
    testChunks: false,
    throttleProgressCallbacks: 1, // 1s
    chunkRetryInterval: 1000, // 1s
    chunkSize: 512 * 1024, // 512KB,
    generateUniqueIdentifier: FLOW.uuid
  }),

  assignDrop: function (el) {
    return this.get('r').assignDrop(el);
  },

  assignBrowse: function (el) {
    return this.get('r').assignBrowse(el);
  },

  support: function () {
    return this.get('r').support;
  }.property(),

  upload: function () {
    return this.get('r').upload();
  },

  pause: function () {
    return this.get('r').pause();
  },

  isUploading: function () {
    return this.get('r').isUploading();
  },

  cancel: function () {
    return this.get('r').cancel();
  },

  addFile: function (file) {
    return this.get('r').addFile(file);
  },

  registerEvents: function () {
    var r = this.get('r');

    // Handle file add event
    r.on('fileAdded', function (file) {
      var li;

      FLOW.uploader.set('cancelled', false);

      // Show progress pabr
      $('.resumable-list').show();

      // Add the file to the list
      li = $('.resumable-file-' + file.uniqueIdentifier);
      if (file.file.type != "application/zip" && file.file.type !="application/x-zip-compressed") {
        $('.resumable-progress').hide();
        $('.resumable-list').append('
'+''+file.fileName+'' + ''
          + Ember.String.loc('_unsupported_file_type')) + '
' ;
        $('.resumable-list').css({
            color: '#FF0000'
        })
      } else {
        $('.resumable-progress').show();
        if (li.length === 0) {
          $('.resumable-list').append('
Uploading...  ');
        }

        $('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-name').html(file.fileName);

        $('.progress-bar').css({
          width: '0%'
        });
        // Actually start the upload
        r.upload();
      }
    });

    r.on('pause', function () {
      // Show resume, hide pause
      $('.resumable-progress .progress-resume-link').show();
      $('.resumable-progress .progress-pause-link').hide();
    });

    r.on('complete', function () {
      // Hide pause/resume when the upload has completed
      $('.resumable-progress .progress-resume-link, .resumable-progress .progress-pause-link').hide();
    });

    r.on('fileSuccess', function (file, message) {
      var target = this.opts.target,
      data = {
        uniqueIdentifier: file.uniqueIdentifier,
        filename: file.fileName,
        baseURL: location.protocol + '//' + location.host,
        appId: FLOW.Env.appId,
        uploadDomain: this.opts.uploadDomain,
        complete: true
      },
      fname = file.fileName,
      excel = /\.xlsx$/gi,
      csv = /\.csv$/gi,
      sc;

      if (excel.test(fname)) {
        data.surveyId = FLOW.selectedControl.selectedSurvey.get('id');
      }

      if (csv.test(fname)) {
        sc = FLOW.selectedControl.selectedCascadeResource;
        data.cascadeResourceId = sc.get('keyId');
        data.numLevels = FLOW.selectedControl.get('cascadeImportNumLevels');
        data.includeCodes = !!FLOW.selectedControl.get('cascadeImportIncludeCodes');
      }

      // Reflect that the file upload has completed
      $('.resumable-list').append('
' +''+file.fileName+''
                       + '' + ' '
                       + Ember.String.loc('_upload_complete')
                       + '
'
                     );

      setTimeout(function() {
        $.ajax({
          url : target,
          cache : false,
          type : 'POST',
          data : data
        });
      }, 500);

    });

    r.on('fileError', function (file, message) {
      // Reflect that the file upload has resulted in error
      $('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html('(file could not be uploaded: ' + message + ')');
    });

    r.on('fileProgress', function (file) {
      // Handle progress for both the file and the overall upload
      $('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html(Math.floor(file.progress() * 100) + '%');
      $('.progress-bar').css({
        width: Math.floor(r.progress() * 100) + '%'
      });
    });

  },
  showCancelledMessage: function () {
    FLOW.dialogControl.set('activeAction', 'ignore');
    FLOW.dialogControl.set('header', Ember.String.loc('_upload_cancelled'));
    FLOW.dialogControl.set('message', Ember.String.loc('_upload_cancelled_due_to_navigation'));
    FLOW.dialogControl.set('showCANCEL', false);
    FLOW.dialogControl.set('showDialog', true);
  }
});

FLOW.BulkUploadAppletView = FLOW.View.extend({
  didInsertElement: function () {
    FLOW.uploader.assignDrop($('.resumable-drop')[0]);
    FLOW.uploader.assignBrowse($('.resumable-browse')[0]);
    FLOW.uploader.registerEvents();
  },
  willDestroyElement: function () {
    FLOW.uploader.set('cancelled', FLOW.uploader.isUploading());
    FLOW.uploader.cancel();
    this._super();
  }
});

/* Show warning when trying to close the tab/window with an upload process in progress */
window.onbeforeunload = function (e) {
  var confirmationMessage = Ember.String.loc('_upload_in_progress');

  if (FLOW.uploader.isUploading()) {
    (e || window.event).returnValue = confirmationMessage;
    return confirmationMessage;
  }
};
<commit_msg>[#2471]-Rectifying the code quality  after PR failed codacy test<commit_after>/*global Resumable, FLOW, $, Ember */

FLOW.uuid = function (file) {
  return Math.uuidFast();
};

FLOW.uploader = Ember.Object.create({
  r: new Resumable({
    target: FLOW.Env.flowServices + '/upload',
    uploadDomain: FLOW.Env.surveyuploadurl.split('/')[2],
    simultaneousUploads: 1,
    testChunks: false,
    throttleProgressCallbacks: 1, // 1s
    chunkRetryInterval: 1000, // 1s
    chunkSize: 512 * 1024, // 512KB,
    generateUniqueIdentifier: FLOW.uuid
  }),

  assignDrop: function (el) {
    return this.get('r').assignDrop(el);
  },

  assignBrowse: function (el) {
    return this.get('r').assignBrowse(el);
  },

  support: function () {
    return this.get('r').support;
  }.property(),

  upload: function () {
    return this.get('r').upload();
  },

  pause: function () {
    return this.get('r').pause();
  },

  isUploading: function () {
    return this.get('r').isUploading();
  },

  cancel: function () {
    return this.get('r').cancel();
  },

  addFile: function (file) {
    return this.get('r').addFile(file);
  },

  registerEvents: function () {
    var r = this.get('r');

    // Handle file add event
    r.on('fileAdded', function (file) {
      var li;

      FLOW.uploader.set('cancelled', false);

      // Show progress pabr
      $('.resumable-list').show();

      // Add the file to the list
      li = $('.resumable-file-' + file.uniqueIdentifier);
      if (file.file.type !== "application/zip" && file.file.type !== "application/x-zip-compressed") {
        $('.resumable-progress').hide();
        $('.resumable-list').append('
'+''+file.fileName+'' + ''
          + Ember.String.loc('_unsupported_file_type')) + '
' ;
        $('.resumable-list').css({
            color: '#FF0000'
        })
      } else {
        $('.resumable-progress').show();
        if (li.length === 0) {
          $('.resumable-list').append('
Uploading...  ');
        }

        $('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-name').html(file.fileName);

        $('.progress-bar').css({
          width: '0%'
        });
        // Actually start the upload
        r.upload();
      }
    });

    r.on('pause', function () {
      // Show resume, hide pause
      $('.resumable-progress .progress-resume-link').show();
      $('.resumable-progress .progress-pause-link').hide();
    });

    r.on('complete', function () {
      // Hide pause/resume when the upload has completed
      $('.resumable-progress .progress-resume-link, .resumable-progress .progress-pause-link').hide();
    });

    r.on('fileSuccess', function (file, message) {
      var target = this.opts.target,
      data = {
        uniqueIdentifier: file.uniqueIdentifier,
        filename: file.fileName,
        baseURL: location.protocol + '//' + location.host,
        appId: FLOW.Env.appId,
        uploadDomain: this.opts.uploadDomain,
        complete: true
      },
      fname = file.fileName,
      excel = /\.xlsx$/gi,
      csv = /\.csv$/gi,
      sc;

      if (excel.test(fname)) {
        data.surveyId = FLOW.selectedControl.selectedSurvey.get('id');
      }

      if (csv.test(fname)) {
        sc = FLOW.selectedControl.selectedCascadeResource;
        data.cascadeResourceId = sc.get('keyId');
        data.numLevels = FLOW.selectedControl.get('cascadeImportNumLevels');
        data.includeCodes = !!FLOW.selectedControl.get('cascadeImportIncludeCodes');
      }

      // Reflect that the file upload has completed
      $('.resumable-list').append('
' + ''+file.fileName+''
                       + '' + ' '
                       + Ember.String.loc('_upload_complete')
                       + '
'
                     );
      setTimeout(function() {
        $.ajax({
          url : target,
          cache : false,
          type : 'POST',
          data : data
        });
      }, 500);

    });

    r.on('fileError', function (file, message) {
      // Reflect that the file upload has resulted in error
      $('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html('(file could not be uploaded: ' + message + ')');
    });

    r.on('fileProgress', function (file) {
      // Handle progress for both the file and the overall upload
      $('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html(Math.floor(file.progress() * 100) + '%');
      $('.progress-bar').css({
        width: Math.floor(r.progress() * 100) + '%'
      });
    });

  },
  showCancelledMessage: function () {
    FLOW.dialogControl.set('activeAction', 'ignore');
    FLOW.dialogControl.set('header', Ember.String.loc('_upload_cancelled'));
    FLOW.dialogControl.set('message', Ember.String.loc('_upload_cancelled_due_to_navigation'));
    FLOW.dialogControl.set('showCANCEL', false);
    FLOW.dialogControl.set('showDialog', true);
  }
});

FLOW.BulkUploadAppletView = FLOW.View.extend({
  didInsertElement: function () {
    FLOW.uploader.assignDrop($('.resumable-drop')[0]);
    FLOW.uploader.assignBrowse($('.resumable-browse')[0]);
    FLOW.uploader.registerEvents();
  },
  willDestroyElement: function () {
    FLOW.uploader.set('cancelled', FLOW.uploader.isUploading());
    FLOW.uploader.cancel();
    this._super();
  }
});

/* Show warning when trying to close the tab/window with an upload process in progress */
window.onbeforeunload = function (e) {
  var confirmationMessage = Ember.String.loc('_upload_in_progress');

  if (FLOW.uploader.isUploading()) {
    (e || window.event).returnValue = confirmationMessage;
    return confirmationMessage;
  }
};
<|endoftext|>


<commit_before>const VERSION = '0.1';

self.addEventListener('install', function(event) {
    console.log(`Service Worker installed`);
    return self.skipWaiting();
});

self.addEventListener('activate', function(event) {
    console.log(`Service Worker activated`);
    return self.clients.claim();
});

self.addEventListener('fetch', function(event) {
    console.log(`fetch for request ${event.request.url}`);
    // check if the request is an image
    if (/\.jpg$|.png$|.webp$/.test(event.request.url)) {
        const navigatorConnectionSupported = 'connection' in navigator;

        // check if navigator.connection is supported
        if (navigatorConnectionSupported) {
            const connectionEffectiveType = navigator.connection.effectiveType;

            // check if effectiveType is supported
            if (connectionEffectiveType) {
                const req = event.request.clone();
                let imageResolution = '';

                switch (connectionEffectiveType) {
                    case "slow-2g":
                    case "2g":
                        imageResolution = '_low';
                        break;
                    case "4g":
                        imageResolution = '_high';
                        break;
                    default:
                        imageResolution = '';
                }

                // Build the image we want to return based on connection
                const returnUrl = req.url.substr(0, req.url.lastIndexOf(".")) + imageResolution + "." + req.url.split('.').pop();

                event.respondWith(
                    fetch(returnUrl, {
                        mode: 'no-cors'
                    })
                );

            }

        }
    }
});<commit_msg>network based image loading - define future test outside fetch handler<commit_after>const VERSION = '0.1';

self.addEventListener('install', function(event) {
    console.log(`Service Worker installed`);
    return self.skipWaiting();
});

self.addEventListener('activate', function(event) {
    console.log(`Service Worker activated`);
    return self.clients.claim();
});

const navigatorConnectionSupported = 'connection' in navigator && navigator.connection.effectiveType;

self.addEventListener('fetch', function(event) {
    console.log(`fetch for request ${event.request.url}`);
    // check if the request is an image
    if (/\.jpg$|.png$|.webp$/.test(event.request.url)) {

        // check if navigator.connection is supported
        if (navigatorConnectionSupported) {
            const connectionEffectiveType = navigator.connection.effectiveType;

            // check if effectiveType is supported
            if (connectionEffectiveType) {
                const req = event.request.clone();
                let imageResolution = '';

                switch (connectionEffectiveType) {
                    case "slow-2g":
                    case "2g":
                        imageResolution = '_low';
                        break;
                    case "4g":
                        imageResolution = '_high';
                        break;
                    default:
                        imageResolution = '';
                }

                // Build the image we want to return based on connection
                const returnUrl = req.url.substr(0, req.url.lastIndexOf(".")) + imageResolution + "." + req.url.split('.').pop();

                event.respondWith(
                    fetch(returnUrl, {
                        mode: 'no-cors'
                    })
                );

            }

        }
    }
});<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
*/
foam.CLASS({
  package: 'foam.nanos.u2.navigation',
  name: 'UserInfoNavigationView',
  extends: 'foam.u2.View',

  documentation: 'Displays user and agent label if present. Clicking view opens settings submenu.',

  requires: [
    'foam.nanos.menu.Menu',
    'foam.nanos.menu.SubMenuView'
  ],

  imports: [
    'agent',
    'user'
  ],

  css: `
    ^ {
      cursor: pointer;
      display: flex;
      align-items: center;
    }
    ^carrot {
      margin-left: 15px;
      border-left: 5px solid transparent;
      border-right: 5px solid transparent;
      border-top: 5px solid white;
    }
    ^userName {
      color: /*%GREY4%*/;
      font-weight: 600;
      font-size: 12px;
    }
    ^agentName{
      color: /*%GREY3%*/;
      font-weight: 400;
      font-size: 11px;
    }
    ^ .name-container {
      max-width: 75px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    ^container {
      cursor: pointer;
      display: flex;
      align-items: center;
      width: 100%;
      height: 100%;
    }
  `,

  methods: [
    function initE() {
      this
        .addClass(this.myClass())
        .start().addClass(this.myClass('container'))
          .on('click', () => {
            this.tag(this.SubMenuView.create({
              menu: this.Menu.create({ id: 'settings' })
            }));
          })
          .start()
            .add(this.slot((agent, user) => {
              return this.E().addClass('name-container')
                  .start('span').addClass(this.myClass('userName'))
                    .add( agent.firstName ? user.businessName : user.label())
                  .end();
            }))
            .add(this.slot((agent) => {
              if ( ! agent ) return;
              return this.E().addClass('name-container')
                  .start('span').addClass(this.myClass('agentName'))
                    .add( agent ? agent.label() : '')
                  .end();
            }))
          .end()
          .start()
            .addClass(this.myClass('carrot'))
          .end()
        .end();
    }
  ]
});
<commit_msg>Update src/foam/nanos/u2/navigation/UserInfoNavigationView.js<commit_after>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
*/
foam.CLASS({
  package: 'foam.nanos.u2.navigation',
  name: 'UserInfoNavigationView',
  extends: 'foam.u2.View',

  documentation: 'Displays user and agent label if present. Clicking view opens settings submenu.',

  requires: [
    'foam.nanos.menu.Menu',
    'foam.nanos.menu.SubMenuView'
  ],

  imports: [
    'agent',
    'user'
  ],

  css: `
    ^ {
      cursor: pointer;
      display: flex;
      align-items: center;
    }
    ^carrot {
      margin-left: 15px;
      border-left: 5px solid transparent;
      border-right: 5px solid transparent;
      border-top: 5px solid white;
    }
    ^userName {
      color: /*%GREY4%*/;
      font-weight: 600;
      font-size: 12px;
    }
    ^agentName{
      color: /*%GREY3%*/;
      font-weight: 400;
      font-size: 11px;
    }
    ^ .name-container {
      max-width: 75px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    ^container {
      cursor: pointer;
      display: flex;
      align-items: center;
      width: 100%;
      height: 100%;
    }
  `,

  methods: [
    function initE() {
      this
        .addClass(this.myClass())
        .start().addClass(this.myClass('container'))
          .on('click', () => {
            this.tag(this.SubMenuView.create({
              menu: this.Menu.create({ id: 'settings' })
            }));
          })
          .start()
            .add(this.slot((agent, user) => {
              return this.E().addClass('name-container')
                  .start('span').addClass(this.myClass('userName'))
                    .add(user.label())
                  .end();
            }))
            .add(this.slot((agent) => {
              if ( ! agent ) return;
              return this.E().addClass('name-container')
                  .start('span').addClass(this.myClass('agentName'))
                    .add( agent ? agent.label() : '')
                  .end();
            }))
          .end()
          .start()
            .addClass(this.myClass('carrot'))
          .end()
        .end();
    }
  ]
});
<|endoftext|>


<commit_before>var React = require('react');
var ReactPropTypes = React.PropTypes;

var DimensionType = React.createClass({

  // This React class only works if a list of 'dimensions' is passed through its properties.
  propTypes: {
    doSelectDimension: ReactPropTypes.object.isRequired,
    doBuildDimension: ReactPropTypes.object.isRequired,
    doBuildIdentifier: ReactPropTypes.object.isRequired,
    doBuildMeasurement: ReactPropTypes.object.isRequired,
    type: ReactPropTypes.string.isRequired
  },

  getInitialState: function() {
    return {
      'visible': true
    };
  },

  /**
   * @return {object}
   */
  render: function() {

    var caret;
    if (this.state.visible){
      caret = ;
    } else {
      caret = ;
    }

    var options;
    if (this.state.visible) {
      console.log(this.props.type);
      var community_active = (this.props.type == 'community') ? 'active': '';
      var community =

                        Community

;

      var coded_active = (this.props.type == 'coded') ? 'active': '';
      console.log(coded_active);
      var coded =

                    Coded

;

      var identifier_active = (this.props.type == 'identifier') ? 'active': '';
      var identifier =

                          Identifier

;

      var other_active = (this.props.type == 'other') ? 'active': '';
      var other =

                    Other

;

      options =

                  {community}
                  {coded}
                  {identifier}
                  {other}

;
    }

    return (

Variable Type {caret}

        {options}

    );
  },

  /**
   * Event handler for 'change' events coming from the MessageStore
   */
  _onToggle: function() {
    var new_state = this.state;
    new_state.visible = !this.state.visible;
    this.setState(new_state);
  },

});

module.exports = DimensionType;
<commit_msg>Better alignment with rest of form<commit_after>var React = require('react');
var ReactPropTypes = React.PropTypes;

var DimensionType = React.createClass({

  // This React class only works if a list of 'dimensions' is passed through its properties.
  propTypes: {
    doSelectDimension: ReactPropTypes.object.isRequired,
    doBuildDimension: ReactPropTypes.object.isRequired,
    doBuildIdentifier: ReactPropTypes.object.isRequired,
    doBuildMeasurement: ReactPropTypes.object.isRequired,
    type: ReactPropTypes.string.isRequired
  },

  getInitialState: function() {
    return {
      'visible': true
    };
  },

  /**
   * @return {object}
   */
  render: function() {

    var caret;
    if (this.state.visible){
      caret = ;
    } else {
      caret = ;
    }

    var options;
    if (this.state.visible) {
      console.log(this.props.type);
      var community_active = (this.props.type == 'community') ? 'active': '';
      var community =

                        Community

;

      var coded_active = (this.props.type == 'coded') ? 'active': '';
      console.log(coded_active);
      var coded =

                    Coded

;

      var identifier_active = (this.props.type == 'identifier') ? 'active': '';
      var identifier =

                          Identifier

;

      var other_active = (this.props.type == 'other') ? 'active': '';
      var other =

                    Other

;

      options =

                  {community}
                  {coded}
                  {identifier}
                  {other}

;
    }

    return (

Variable Type {caret}

            Select a type

            {options}

    );
  },

  /**
   * Event handler for 'change' events coming from the MessageStore
   */
  _onToggle: function() {
    var new_state = this.state;
    new_state.visible = !this.state.visible;
    this.setState(new_state);
  },

});

module.exports = DimensionType;
<|endoftext|>