<commit_before>var ExecutionResult = require('./executionResult');
var ServiceException = require('./serviceException');
var RulesValidator = require('./rulesValidator');

var Command = (function() {

  "use strict";

  var Command = function(callbacks) {
    callbacks = callbacks || {};
    if (this instanceof Command) {

      if (!this._onInitialization) { // allow for inheritance (ES6)
        this._onInitialization = callbacks._onInitialization || function(context, done) {
          if (done) return done();
          return Promise.resolve();
        };
      }

      if (!this._getRules) { // allow for inheritance (ES6)
        this._getRules = callbacks._getRules || function(context, done) {
          if (done) return done(null, []);
          return Promise.resolve([]);
        };
      }

      if (!this._onValidationSuccess) { // allow for inheritance (ES6)
        this._onValidationSuccess = callbacks._onValidationSuccess || function(context, done) {
          if (done) return done();
          return Promise.resolve();
        };
      }

    } else {
      return new Command(
        callbacks.onInitialization,
        callbacks.getRules,
        callbacks.onValidationSuccess
      );
    }
  };

  Command.prototype = {

    constructor: Command,

    execute: function(done) {
      var self = this;
      var context = {};

      if (!done) {
        return performInitialization()
          .then(getRules)
          .then(validateRules)
          .then(parseErrorsFromRules)
          .then(createExecutionResult);
      }

      function performInitialization() {
        return self._onInitialization(context)
      }

      function createExecutionResult(errors) {
        if (errors.length > 0)
          return Promise.resolve(new ExecutionResult(false, null, errors));

        try {
          return self._onValidationSuccess(context)
            .then((result) => {
              return Promise.resolve(new ExecutionResult(true, result, null));
            })
            .catch(handleError);
        } catch(err) {
          return handleError(err);
        }
      }

      function getRules() {
        return self._getRules(context)
          .then(rules => {
            if (!Array.isArray(rules)) {
              rules = [rules];
            }
            return rules;
          });
      }

      function validateRules(rules) {
        return new RulesValidator(rules).validate();
      }

      function parseErrorsFromRules(rules) {
        var errors = rules.filter(function(rule) { return !rule.valid; })
                          .map(function(rule) { return rule.errors; });

        return [].concat.apply([], errors); // flatten array
      }

      function handleError(err) {
        if (err instanceof ServiceException) {
          return Promise.resolve(new ExecutionResult(false, null, err.errors));
        }
        return Promise.reject(err);
      }

      self._onInitialization(context, function(err) {

        if(err) return done(err);

        self._getRules(context, function(err, rules) {

          if(err) return done(err);

          if (!Array.isArray(rules)) {
            rules = [rules];
          }

          new RulesValidator(rules).validate(function(err) {

            if (err) return done(err);

            var errors = parseErrorsFromRules(rules);

            if (errors.length > 0)
              return done(null, new ExecutionResult(false, null, errors));

            try {
              self._onValidationSuccess(context, function(err, result) {
                if(err) {
                  if (err instanceof ServiceException) {
                    return done(null, new ExecutionResult(false, null, err.errors));
                  }
                  return done(err);
                };
                done(null, new ExecutionResult(true, result, null));
              });
            }
            catch(ex) {
              done(ex);
            }
          });
        });
      });
    }
  };

  Command.extend = function(options) {
    options = options || {};
    var params = options.params || [];
    var functions = options.functions || {};

    var Extended = function() {
      var self = this;
      self.arguments = arguments;
      params.forEach(function(param, index) {
        self[param] = self.arguments[index];
      });
    };

    Extended.prototype = new Command();

    Extended.prototype._onInitialization = functions._onInitialization || function(context, done) {
      if (done) return done();
      return Promise.resolve();
    };

    Extended.prototype._getRules = functions._getRules || function(context, done) {
      if (done) return done(null, []);
      return Promise.resolve([]);
    };

    Extended.prototype._onValidationSuccess = functions._onValidationSuccess || function(context, done) {
      if (done) return done();
      return Promise.resolve();
    };

    return Extended;
  };

  Command.executeAll = function(commands, done) {

    if (!Array.isArray(commands)) {
      commands = [commands];
    }

    var count = commands.length;

    if (count < 1) {
      if (done) return done();
      return Promise.resolve();
    }

    if (!done) {
      return Promise.all(commands.map(c => c.execute()));
    }

    var current = 0;
    var results = [];

    commands.forEach(function(command) {
      command.execute(onComplete);
    });

    function onComplete(err, result) {
      if (err) { return done(err, results); }
      current++;
      results.push(result);
      if (current === count) {
        done(null, results);
      }
    }
  };

  return Command;

})();

module.exports = Command;
<commit_msg>first pass at refactoring command after promisification<commit_after>var ExecutionResult = require('./executionResult');
var ServiceException = require('./serviceException');
var RulesValidator = require('./rulesValidator');

var Command = (function() {

  "use strict";

  var Command = function(callbacks) {
    callbacks = callbacks || {};
    if (this instanceof Command) {

      if (!this._onInitialization) { // allow for inheritance (ES6)
        this._onInitialization = callbacks._onInitialization || function(context, done) {
          if (done) return done();
          return Promise.resolve();
        };
      }

      if (!this._getRules) { // allow for inheritance (ES6)
        this._getRules = callbacks._getRules || function(context, done) {
          if (done) return done(null, []);
          return Promise.resolve([]);
        };
      }

      if (!this._onValidationSuccess) { // allow for inheritance (ES6)
        this._onValidationSuccess = callbacks._onValidationSuccess || function(context, done) {
          if (done) return done();
          return Promise.resolve();
        };
      }

    } else {
      return new Command(
        callbacks.onInitialization,
        callbacks.getRules,
        callbacks.onValidationSuccess
      );
    }
  };

  Command.prototype = {

    constructor: Command,

    execute: function(done) {
      var self = this;
      var context = {};

      if (!done) {
        return performInitialization(done)
          .then(getRules)
          .then(validateRules)
          .then(parseErrorsFromRules)
          .then(createExecutionResult);
      }

      function performInitialization(done) {
        return self._onInitialization(context)
      }

      function createExecutionResult(errors) {
        if (errors.length > 0)
          return Promise.resolve(new ExecutionResult(false, null, errors));

        try {
          return self._onValidationSuccess(context)
            .then((result) => {
              return Promise.resolve(new ExecutionResult(true, result, null));
            })
            .catch(handleError);
        } catch(err) {
          return handleError(err);
        }
      }

      function getRules() {
        return self._getRules(context)
          .then(rules => {
            if (!Array.isArray(rules)) {
              rules = [rules];
            }
            return rules;
          });
      }

      function validateRules(rules) {
        return new RulesValidator(rules).validate();
      }

      function parseErrorsFromRules(rules) {
        var errors = rules.filter(function(rule) { return !rule.valid; })
                          .map(function(rule) { return rule.errors; });

        return [].concat.apply([], errors); // flatten array
      }

      function handleError(err) {
        if (err instanceof ServiceException) {
          return Promise.resolve(new ExecutionResult(false, null, err.errors));
        }
        return Promise.reject(err);
      }

      self._onInitialization(context, function(err) {

        if(err) return done(err);

        self._getRules(context, function(err, rules) {

          if(err) return done(err);

          if (!Array.isArray(rules)) {
            rules = [rules];
          }

          new RulesValidator(rules).validate(function(err) {

            if (err) return done(err);

            var errors = parseErrorsFromRules(rules);

            if (errors.length > 0)
              return done(null, new ExecutionResult(false, null, errors));

            try {
              self._onValidationSuccess(context, function(err, result) {
                if(err) {
                  if (err instanceof ServiceException) {
                    return done(null, new ExecutionResult(false, null, err.errors));
                  }
                  return done(err);
                };
                done(null, new ExecutionResult(true, result, null));
              });
            }
            catch(ex) {
              done(ex);
            }
          });
        });
      });
    }
  };

  Command.extend = function(options) {
    options = options || {};
    var params = options.params || [];
    var functions = options.functions || {};

    var Extended = function() {
      var self = this;
      self.arguments = arguments;
      params.forEach(function(param, index) {
        self[param] = self.arguments[index];
      });
    };

    Extended.prototype = new Command();

    Extended.prototype._onInitialization = functions._onInitialization || function(context, done) {
      if (done) return done();
      return Promise.resolve();
    };

    Extended.prototype._getRules = functions._getRules || function(context, done) {
      if (done) return done(null, []);
      return Promise.resolve([]);
    };

    Extended.prototype._onValidationSuccess = functions._onValidationSuccess || function(context, done) {
      if (done) return done();
      return Promise.resolve();
    };

    return Extended;
  };

  Command.executeAll = function(commands, done) {

    if (!Array.isArray(commands)) {
      commands = [commands];
    }

    var count = commands.length;

    if (count < 1) {
      if (done) return done();
      return Promise.resolve();
    }

    if (!done) {
      return Promise.all(commands.map(c => c.execute()));
    }

    var current = 0;
    var results = [];

    commands.forEach(function(command) {
      command.execute(onComplete);
    });

    function onComplete(err, result) {
      if (err) { return done(err, results); }
      current++;
      results.push(result);
      if (current === count) {
        done(null, results);
      }
    }
  };

  return Command;

})();

module.exports = Command;
<|endoftext|>


<commit_before>/* globals $ */
var popoverLocalInit = function() {
  var options = {
    html: true,
    placement: function(context, source) {
      var position = $(source).offset();
      $(context).addClass($(source).attr('data-popover-class'));
      if ($(source).hasClass('a-js-popoverBig')) {
        return 'bottom';
      }
      if (position.left < 125) {
        return 'right';
      }
      if (position.left > ($(document).width() - $(source).width() - 125)) {
        return 'left';
      }
      return 'bottom';
    },
    content: function() {
      if ($(this).attr('data-popover-content')) {
        return $('#' + $(this).data('popover-content')).html();
      }
      return false;
    },
    template: '

'
  };

  $('[data-toggle="popover"]').popover(options);

  $('.a-js-togglePopoverIcons').each(function() {
    // $(this).find('i').eq(1).hide();
    $(this).find('.a-js-popoverIconExpanded').hide();
  });

  $('.a-js-popoverIconExpanded').on('click', function() {
    $('.a-js-popoverIconExpanded').hide();
    $('.a-js-popoverIconInitial').show();
    // $(this).hide();
    // $('.a-js-popoverIconInitial').show();
  });
  $('.a-js-popoverIconInitial').on('click', function() {
    $(this).hide();
    $(this).parent().find('.a-js-popoverIconExpanded').show();
  });
};

var forceFocusTriggerElement;
var popoverGlobalInit = function() {
  $('[data-toggle="dropdown"]').on('click', function(e) {
    if (window.innerWidth < 992) {
      $('.a-dropdown-overflow-menu-right').removeClass('dropdown-menu-right');
    } else {
      $('.a-dropdown-overflow-menu-right').addClass('dropdown-menu-right');
    }
  });

  $('body').on('show.bs.popover', '[data-toggle="popover"].a-js-tabable-popover', function(e) {
    var triggerElement = this;
    $(triggerElement).closest('.a-modal').scrollTop(0);
  });

  $('body').on('shown.bs.popover', '[data-toggle="popover"].a-js-tabable-popover', function(e) {
    var triggerElement = this;
    setTimeout(function() {
      $(triggerElement).after($($(triggerElement).data('bs.popover').tip));
      $(triggerElement).closest('.a-modal').one('scroll', function() {
        $('[data-toggle="popover"]').popover('hide');
      });
    }, 0);
  });

  $('body').on('shown.bs.popover', '[data-toggle="popover"].a-js-popover-forceFocus', function(e) {
    $('body').append($('<button class="sr-only a-js-popoverTrick">ignoreme</button>'));
    forceFocusTriggerElement = this;
    $(forceFocusTriggerElement).one('blur', function() {
      var that = this;
      if (forceFocusTriggerElement) {
        $($(this).data('bs.popover').tip).find('button,input,a,textarea').filter(':visible:first').focus();
      }
    });
  });

  $('body').on('hidden.bs.popover', '[data-toggle="popover"].a-js-popover-forceFocus', function(e) {
    $('body').find('.a-js-popoverTrick').remove();
  });

  // hides popover when the cehckbutton is checked
  $('body').on('focus', '[data-toggle="popover"].sr-only', function(e) {
    if ($(this).is(':checked')) {
      $(this).popover('hide');
    } else {
      $(this).popover('show');
    }
  });

  // show/hide popover on checkbutton change
  $('body').on('change', 'a-switch[data-toggle=popover]', function() {
    if ($(this).is(':checked')) {
      $(this).popover('hide');
    } else {
      $(this).popover('show');
    }
  });

  // Hide all existing popovers when opening a new popover
  $('body').on('click', '[data-toggle="popover"]', function(e) {
    $('[data-toggle="popover"]').not(this).popover('hide');
  });

  // Hide all existing popovers when focusing a new element
  // which is not the open popover or any of its content
  $('body').on('blur', '[data-toggle="popover"], .popover *', function(e) {
    setTimeout(function() {
      var $focused = $(':focus');
      if ((($focused.length !== 0 || forceFocusTriggerElement)
        && !$focused.hasClass('popover')
        && !$focused.parents('.popover').length >= 1) || $focused.hasClass('a-js-popoverTrick')) {
        if (forceFocusTriggerElement) {
          $(forceFocusTriggerElement).focus();
          forceFocusTriggerElement = false;
        }
        // disable blur when in modal to allow use of non-original scrollbar
        if ($('.modal.show').length > 0) {
          $('.popover-big[data-toggle="popover"]').popover('hide');
        }
      }
    }, 0);
  });

  // Hide popovers when clicking on something else than the trigger element
  // and the popover itself
  $('body').on('click', function(e) {
    if ($(e.target).data('toggle') !== 'popover'
      && $(e.target).parents('[data-toggle="popover"]').length === 0
      && $(e.target).parents('.popover.show').length === 0) {
      $('[data-toggle="popover"]').popover('hide');
      forceFocusTriggerElement = false;
      $(this).parent().find('.a-js-popoverIconInitial').show();
      $(this).parent().find('.a-js-popoverIconExpanded').hide();
    }
  });

  function resetTranslate() {
    $('.popover-big').attr('style', $('.popover-big').attr('style').replace(/translateX\(.*?\)/, 'translateX(0px)'));
  }

  function adjustBig() {
    var modalHeight;
    var padding;
    if ($('.popover-big').length > 0) {
      if ($('.modal.show').length > 0) {
        // Add padding to make sure modal is big enough to contain popover
        modalHeight = $('.modal-dialog').height() + $('.modalPage').height();
        padding = ($('.popover').offset().top + $('.modal').scrollTop() + $('.popover').height() + 5) - modalHeight;
        $('.modalPage').css('padding-bottom', padding + 'px');
        // tranlate is somehow added by Bootstrap later when in modal??
        setTimeout(resetTranslate, 0);
      } else {
        resetTranslate();
      }
    }
  }

  $('body').on('shown.bs.popover', '.a-js-persistPopover', function() {
    $('.arrow').html('');
    $('html, body').animate({
      scrollTop: $('.a-js-persistPopover').offset().top - 50
    }, 250);

    // bind scroll wheel to modal popover
    if ($('.modal.show').length > 0) {
      $('.popover-big').bind('wheel', function(e) {
        var scrollTo;
        if (e.originalEvent.deltaY > 0 || e.originalEvent.deltaY < 0) {
          scrollTo = (e.originalEvent.deltaY) + $('.modal').scrollTop();
          $('.modal').scrollTop(scrollTo);
        }
      });
    }

    adjustBig();
  });

  // clean up modal page fix
  $('body').on('hidden.bs.popover', 'a-js-persistPopover', function(e) {
    $('.modalPage').css('padding-bottom', '0px');
  });

  $(window).scroll(adjustBig);
  $('.modal').scroll(adjustBig);
  $(window).resize(adjustBig);
};
<commit_msg>Disabled modal scrolling when mouse hovers popover. (#230)<commit_after>/* globals $ */
var popoverLocalInit = function() {
  var options = {
    html: true,
    placement: function(context, source) {
      var position = $(source).offset();
      $(context).addClass($(source).attr('data-popover-class'));
      if ($(source).hasClass('a-js-popoverBig')) {
        return 'bottom';
      }
      if (position.left < 125) {
        return 'right';
      }
      if (position.left > ($(document).width() - $(source).width() - 125)) {
        return 'left';
      }
      return 'bottom';
    },
    content: function() {
      if ($(this).attr('data-popover-content')) {
        return $('#' + $(this).data('popover-content')).html();
      }
      return false;
    },
    template: '

'
  };

  $('[data-toggle="popover"]').popover(options);

  $('.a-js-togglePopoverIcons').each(function() {
    // $(this).find('i').eq(1).hide();
    $(this).find('.a-js-popoverIconExpanded').hide();
  });

  $('.a-js-popoverIconExpanded').on('click', function() {
    $('.a-js-popoverIconExpanded').hide();
    $('.a-js-popoverIconInitial').show();
    // $(this).hide();
    // $('.a-js-popoverIconInitial').show();
  });
  $('.a-js-popoverIconInitial').on('click', function() {
    $(this).hide();
    $(this).parent().find('.a-js-popoverIconExpanded').show();
  });
};

var forceFocusTriggerElement;
var popoverGlobalInit = function() {
  $('[data-toggle="dropdown"]').on('click', function(e) {
    if (window.innerWidth < 992) {
      $('.a-dropdown-overflow-menu-right').removeClass('dropdown-menu-right');
    } else {
      $('.a-dropdown-overflow-menu-right').addClass('dropdown-menu-right');
    }
  });

  $('body').on('show.bs.popover', '[data-toggle="popover"].a-js-tabable-popover', function(e) {
    var triggerElement = this;
    $(triggerElement).closest('.a-modal').scrollTop(0);
  });

  $('body').on('shown.bs.popover', '[data-toggle="popover"].a-js-tabable-popover', function(e) {
    var triggerElement = this;
    setTimeout(function() {
      $(triggerElement).after($($(triggerElement).data('bs.popover').tip));
      $(triggerElement).closest('.a-modal').one('scroll', function() {
        $('[data-toggle="popover"]').popover('hide');
      });
    }, 0);
  });

  $('body').on('shown.bs.popover', '[data-toggle="popover"].a-js-popover-forceFocus', function(e) {
    $('body').append($('<button class="sr-only a-js-popoverTrick">ignoreme</button>'));
    forceFocusTriggerElement = this;
    $(forceFocusTriggerElement).one('blur', function() {
      var that = this;
      if (forceFocusTriggerElement) {
        $($(this).data('bs.popover').tip).find('button,input,a,textarea').filter(':visible:first').focus();
      }
    });
  });

  $('body').on('hidden.bs.popover', '[data-toggle="popover"].a-js-popover-forceFocus', function(e) {
    $('body').find('.a-js-popoverTrick').remove();
  });

  // hides popover when the cehckbutton is checked
  $('body').on('focus', '[data-toggle="popover"].sr-only', function(e) {
    if ($(this).is(':checked')) {
      $(this).popover('hide');
    } else {
      $(this).popover('show');
    }
  });

  // show/hide popover on checkbutton change
  $('body').on('change', 'a-switch[data-toggle=popover]', function() {
    if ($(this).is(':checked')) {
      $(this).popover('hide');
    } else {
      $(this).popover('show');
    }
  });

  // Hide all existing popovers when opening a new popover
  $('body').on('click', '[data-toggle="popover"]', function(e) {
    $('[data-toggle="popover"]').not(this).popover('hide');
  });

  // Hide all existing popovers when focusing a new element
  // which is not the open popover or any of its content
  $('body').on('blur', '[data-toggle="popover"], .popover *', function(e) {
    setTimeout(function() {
      var $focused = $(':focus');
      if ((($focused.length !== 0 || forceFocusTriggerElement)
        && !$focused.hasClass('popover')
        && !$focused.parents('.popover').length >= 1) || $focused.hasClass('a-js-popoverTrick')) {
        if (forceFocusTriggerElement) {
          $(forceFocusTriggerElement).focus();
          forceFocusTriggerElement = false;
        }
        // disable blur when in modal to allow use of non-original scrollbar
        if ($('.modal.show').length > 0) {
          $('.popover-big[data-toggle="popover"]').popover('hide');
        }
      }
    }, 0);
  });

  // Hide popovers when clicking on something else than the trigger element
  // and the popover itself
  $('body').on('click', function(e) {
    if ($(e.target).data('toggle') !== 'popover'
      && $(e.target).parents('[data-toggle="popover"]').length === 0
      && $(e.target).parents('.popover.show').length === 0) {
      $('[data-toggle="popover"]').popover('hide');
      forceFocusTriggerElement = false;
      $(this).parent().find('.a-js-popoverIconInitial').show();
      $(this).parent().find('.a-js-popoverIconExpanded').hide();
    }
  });

  function resetTranslate() {
    $('.popover-big').attr('style', $('.popover-big').attr('style').replace(/translateX\(.*?\)/, 'translateX(0px)'));
  }

  function adjustBig() {
    var modalHeight;
    var padding;
    if ($('.popover-big').length > 0) {
      if ($('.modal.show').length > 0) {
        // Add padding to make sure modal is big enough to contain popover
        modalHeight = $('.modal-dialog').height() + $('.modalPage').height();
        padding = ($('.popover').offset().top + $('.modal').scrollTop() + $('.popover').height() + 5) - modalHeight;
        $('.modalPage').css('padding-bottom', padding + 'px');
        // tranlate is somehow added by Bootstrap later when in modal??
        setTimeout(resetTranslate, 0);
      } else {
        resetTranslate();
      }
    }
  }

  $('body').on('shown.bs.popover', '.a-js-persistPopover', function() {
    $('.arrow').html('');
    $('html, body').animate({
      scrollTop: $('.a-js-persistPopover').offset().top - 50
    }, 250);

    adjustBig();
  });

  // clean up modal page fix
  $('body').on('hidden.bs.popover', 'a-js-persistPopover', function(e) {
    $('.modalPage').css('padding-bottom', '0px');
  });

  $(window).scroll(adjustBig);
  $('.modal').scroll(adjustBig);
  $(window).resize(adjustBig);
};
<|endoftext|>


<commit_before>// @flow
export {FilterView} from './filter-view'
export type {FilterType, ListType, ToggleType, PickerType} from './types'
export {applyFiltersToItem} from './apply-filters'
export {stringifyFilters} from './stringify-filters'
export {filterListSpecs, filterPickerSpecs, filterToggleSpecs} from './tools'
<commit_msg>add necessary exports<commit_after>// @flow
export {FilterView} from './filter-view'
export type {FilterType, ListType, ToggleType, PickerType} from './types'
export {applyFiltersToItem} from './apply-filters'
export {stringifyFilters} from './stringify-filters'
export {filterListSpecs, filterPickerSpecs, filterToggleSpecs} from './tools'
export {FilterToolbar} from './filter-toolbar'
export {FilterPopover} from './filter-popover'
<|endoftext|>


<commit_before>import { Class, isEqual } from '../../core/Core.js';
import { appendChildren, create as el } from '../../dom/Element.js';
import { AbstractInputView } from './AbstractInputView.js';

// ---

const HANDLED_KEYS = new Set([
    'ArrowDown',
    'ArrowLeft',
    'ArrowRight',
    'ArrowUp',
]);

/**
    Class: O.RadioGroupView

    Extends: O.AbstractInputView

    A view representing an HTML `<select>` menu. The `value` property is two-way
    bindable, representing the selected option.
*/
const RadioGroupView = Class({
    Name: 'RadioGroupView',

    Extends: AbstractInputView,

    init: function (/* ...mixins */) {
        RadioGroupView.parent.constructor.apply(this, arguments);
        this._domControls = [];
        const options = this.get('options');
        const value = this.get('value');
        this.selectedIndex = options.findIndex((option) => {
            return isEqual(value, option.value);
        });
    },

    selectedIndex: null,

    value: null,

    /**
        Property: O.RadioGroupView#options
        Type: Array

        The array of options to present in the select menu. Each item in the
        array should be an object, with the following properties:

        label       - {String} The text to display for the item
        description - {String} The subtext to display for the item
        value       - {*} The value for the <O.RadioGroupView#value> property to take
                      when this item is selected.
        isDisabled  - {Boolean} (optional) If true, the option will be disabled
                      (unselectable). Defaults to false if not present.
    */
    options: [],

    // --- Render ---

    layerTag: 'fieldset',

    baseClassName: 'v-RadioGroup',

    type: '',

    drawControl(option, index) {
        const id = this.get('id');
        const control = el('input', {
            type: 'radio',
            id: id + '-option-' + index,
            className: this.get('baseClassName') + '-input',
            checked: index === this.get('selectedIndex'),
            disabled: this.get('isDisabled') || option.isDisabled,
            name: this.get('name') || id + '-value',
            tabIndex: '-1',
            onchange: (event) => {
                if (event.target.checked) {
                    this._settingFromInput = true;
                    this.set('selectedIndex', index);
                    this._settingFromInput = false;
                }
            },
        });
        this._domControls.push(control);
        if (control.checked) {
            this._domControl = control;
        }
        return control;
    },

    drawLabel(label) {
        return el('p', [label]);
    },

    /**
        Method: O.ToggleView#draw

        Overridden to draw toggle in layer. See <O.View#draw>.
    */
    drawOption(option, index) {
        const baseClassName = this.get('baseClassName');

        const control = this.drawControl(option, index);

        const label = this.drawLabel(option.label, option);

        let description = option.description;
        if (description) {
            description = this.drawDescription(description, option);
        }

        return el(
            `label.${baseClassName}-option`,
            [control, el(`div.${baseClassName}-text`, [label, description])],
        );
    },

    /**
        Method: O.RadioGroupView#draw

        Overridden to draw select menu in layer. See <O.View#draw>.
    */
    draw(/*layer*/) {
        let label = this.get('label');
        if (label) {
            label = this.drawLabel(label);
        }

        let description = this.get('description');
        if (description) {
            description = this.drawDescription(description);
        }

        const options = this.get('options').map(this.drawOption, this);

        this.redrawTabIndex();

        return [label, description, options];
    },

    // --- Keep render in sync with state ---

    /**
        Method: O.RadioGroupView#optionsNeedsRedraw

        Calls <O.View#propertyNeedsRedraw> for extra properties requiring
        redraw.
    */
    optionsNeedsRedraw: function (self, property, oldValue) {
        return this.propertyNeedsRedraw(self, property, oldValue);
    }.observes('options'),

    /**
        Method: O.RadioGroupView#redrawOptions

        Updates the DOM representation when the <O.RadioGroupView#options> property
        changes.
    */
    redrawOptions(layer, oldOptions) {
        const options = this.get('options');
        if (!isEqual(options, oldOptions)) {
            const baseElements = this.get('description') ? 2 : 1;
            while (layer.childElementCount > baseElements) {
                layer.removeChild(layer.lastElementChild);
            }

            const value = this.get('value');
            this.selectedIndex = options.findIndex((option) => {
                return isEqual(value, option.value);
            });

            this._domControls = [];
            appendChildren(layer, options.map(this.drawOption, this));

            this.redrawTabIndex();

            if (this.get('isFocused')) {
                this.focus();
            }
        }
    },

    redrawIsDisabled() {
        const isDisabled = this.get('isDisabled');
        const options = this.get('options');
        this._domControls.forEach((control, i) => {
            control.disabled = isDisabled || options[i].isDisabled;
        });
    },

    redrawName() {
        const name = this.get('name');
        this._domControls.forEach((control) => {
            control.name = name;
        });
    },

    redrawValue() {},

    selectedIndexDidChange: function (_, __, oldIndex, index) {
        const control = this._domControls[index];
        if (control) {
            control.checked = true;
            control.tabIndex = this.get('tabIndex');
            if (this.get('isFocused')) {
                control.focus();
            }
            this._domControl = control;
        } else {
            this._domControl = this._domControls[0];
        }

        const oldControl = this._domControls[oldIndex];
        if (oldControl) {
            oldControl.checked = false;
            if (index !== -1) {
                oldControl.tabIndex = '-1';
            }
        }

        const newValue = index > -1 ? this.get('options')[index].value : null;
        if (this._settingFromInput) {
            this.userDidInput(newValue);
        }
    }.observes('selectedIndex'),

    /**
        Method (private): O.AbstractControlView#_updateIsFocused

        Updates the <#isFocused> property.

        Parameters:
            event - {Event} The focus event.
    */
    _updateIsFocused: function (event) {
        if (event.type === 'focusin') {
            this.set('isFocused', true);
        } else if (!this.get('layer').contains(event.relatedTarget)) {
            this.set('isFocused', false);
        }
    }.on('focusin', 'focusout'),

    /**
        Method: O.RadioGroupView#redrawValue

        Checks the corresponding control in the radio group when the
        <O.RadioGroupView#value> property changes.
    */
    valueDidChange: function (_, __, ___, value) {
        if (this._settingFromInput) {
            return;
        }
        const options = this.get('options');
        this.set(
            'selectedIndex',
            options.findIndex((option) => isEqual(value, option.value)),
        );
    }.observes('value'),

    keydown: function (event) {
        const key = event.key;
        if (!HANDLED_KEYS.has(key)) {
            return;
        }
        event.preventDefault();

        let selectedIndex = this.get('selectedIndex');
        if (key === 'ArrowDown' || key === 'ArrowRight') {
            selectedIndex += 1;
        } else {
            selectedIndex -= 1;
        }

        const maxIndex = this.get('options').length - 1;
        if (selectedIndex > maxIndex) {
            selectedIndex = 0;
        } else if (selectedIndex < 0) {
            selectedIndex = maxIndex;
        }
        this._settingFromInput = true;
        this.set('selectedIndex', selectedIndex);
        this._settingFromInput = false;
    }.on('keydown'),
});

export { RadioGroupView };
<commit_msg>RadioGroupView: use <legend> for control label<commit_after>import { Class, isEqual } from '../../core/Core.js';
import { appendChildren, create as el } from '../../dom/Element.js';
import { AbstractInputView } from './AbstractInputView.js';

// ---

const HANDLED_KEYS = new Set([
    'ArrowDown',
    'ArrowLeft',
    'ArrowRight',
    'ArrowUp',
]);

/**
    Class: O.RadioGroupView

    Extends: O.AbstractInputView

    A view representing an HTML `<select>` menu. The `value` property is two-way
    bindable, representing the selected option.
*/
const RadioGroupView = Class({
    Name: 'RadioGroupView',

    Extends: AbstractInputView,

    init: function (/* ...mixins */) {
        RadioGroupView.parent.constructor.apply(this, arguments);
        this._domControls = [];
        const options = this.get('options');
        const value = this.get('value');
        this.selectedIndex = options.findIndex((option) => {
            return isEqual(value, option.value);
        });
    },

    selectedIndex: null,

    value: null,

    /**
        Property: O.RadioGroupView#options
        Type: Array

        The array of options to present in the select menu. Each item in the
        array should be an object, with the following properties:

        label       - {String} The text to display for the item
        description - {String} The subtext to display for the item
        value       - {*} The value for the <O.RadioGroupView#value> property to take
                      when this item is selected.
        isDisabled  - {Boolean} (optional) If true, the option will be disabled
                      (unselectable). Defaults to false if not present.
    */
    options: [],

    // --- Render ---

    layerTag: 'fieldset',

    baseClassName: 'v-RadioGroup',

    type: '',

    drawControl(option, index) {
        const id = this.get('id');
        const control = el('input', {
            type: 'radio',
            id: id + '-option-' + index,
            className: this.get('baseClassName') + '-input',
            checked: index === this.get('selectedIndex'),
            disabled: this.get('isDisabled') || option.isDisabled,
            name: this.get('name') || id + '-value',
            tabIndex: '-1',
            onchange: (event) => {
                if (event.target.checked) {
                    this._settingFromInput = true;
                    this.set('selectedIndex', index);
                    this._settingFromInput = false;
                }
            },
        });
        this._domControls.push(control);
        if (control.checked) {
            this._domControl = control;
        }
        return control;
    },

    drawLabel(label, option) {
        return el(option ? 'p' : 'legend', [label]);
    },

    /**
        Method: O.ToggleView#draw

        Overridden to draw toggle in layer. See <O.View#draw>.
    */
    drawOption(option, index) {
        const baseClassName = this.get('baseClassName');

        const control = this.drawControl(option, index);

        const label = this.drawLabel(option.label, option);

        let description = option.description;
        if (description) {
            description = this.drawDescription(description, option);
        }

        return el(
            `label.${baseClassName}-option`,
            [control, el(`div.${baseClassName}-text`, [label, description])],
        );
    },

    /**
        Method: O.RadioGroupView#draw

        Overridden to draw select menu in layer. See <O.View#draw>.
    */
    draw(/*layer*/) {
        let label = this.get('label');
        if (label) {
            label = this.drawLabel(label);
        }

        let description = this.get('description');
        if (description) {
            description = this.drawDescription(description);
        }

        const options = this.get('options').map(this.drawOption, this);

        this.redrawTabIndex();

        return [label, description, options];
    },

    // --- Keep render in sync with state ---

    /**
        Method: O.RadioGroupView#optionsNeedsRedraw

        Calls <O.View#propertyNeedsRedraw> for extra properties requiring
        redraw.
    */
    optionsNeedsRedraw: function (self, property, oldValue) {
        return this.propertyNeedsRedraw(self, property, oldValue);
    }.observes('options'),

    /**
        Method: O.RadioGroupView#redrawOptions

        Updates the DOM representation when the <O.RadioGroupView#options> property
        changes.
    */
    redrawOptions(layer, oldOptions) {
        const options = this.get('options');
        if (!isEqual(options, oldOptions)) {
            const baseElements = this.get('description') ? 2 : 1;
            while (layer.childElementCount > baseElements) {
                layer.removeChild(layer.lastElementChild);
            }

            const value = this.get('value');
            this.selectedIndex = options.findIndex((option) => {
                return isEqual(value, option.value);
            });

            this._domControls = [];
            appendChildren(layer, options.map(this.drawOption, this));

            this.redrawTabIndex();

            if (this.get('isFocused')) {
                this.focus();
            }
        }
    },

    redrawIsDisabled() {
        const isDisabled = this.get('isDisabled');
        const options = this.get('options');
        this._domControls.forEach((control, i) => {
            control.disabled = isDisabled || options[i].isDisabled;
        });
    },

    redrawName() {
        const name = this.get('name');
        this._domControls.forEach((control) => {
            control.name = name;
        });
    },

    redrawValue() {},

    selectedIndexDidChange: function (_, __, oldIndex, index) {
        const control = this._domControls[index];
        if (control) {
            control.checked = true;
            control.tabIndex = this.get('tabIndex');
            if (this.get('isFocused')) {
                control.focus();
            }
            this._domControl = control;
        } else {
            this._domControl = this._domControls[0];
        }

        const oldControl = this._domControls[oldIndex];
        if (oldControl) {
            oldControl.checked = false;
            if (index !== -1) {
                oldControl.tabIndex = '-1';
            }
        }

        const newValue = index > -1 ? this.get('options')[index].value : null;
        if (this._settingFromInput) {
            this.userDidInput(newValue);
        }
    }.observes('selectedIndex'),

    /**
        Method (private): O.AbstractControlView#_updateIsFocused

        Updates the <#isFocused> property.

        Parameters:
            event - {Event} The focus event.
    */
    _updateIsFocused: function (event) {
        if (event.type === 'focusin') {
            this.set('isFocused', true);
        } else if (!this.get('layer').contains(event.relatedTarget)) {
            this.set('isFocused', false);
        }
    }.on('focusin', 'focusout'),

    /**
        Method: O.RadioGroupView#redrawValue

        Checks the corresponding control in the radio group when the
        <O.RadioGroupView#value> property changes.
    */
    valueDidChange: function (_, __, ___, value) {
        if (this._settingFromInput) {
            return;
        }
        const options = this.get('options');
        this.set(
            'selectedIndex',
            options.findIndex((option) => isEqual(value, option.value)),
        );
    }.observes('value'),

    keydown: function (event) {
        const key = event.key;
        if (!HANDLED_KEYS.has(key)) {
            return;
        }
        event.preventDefault();

        let selectedIndex = this.get('selectedIndex');
        if (key === 'ArrowDown' || key === 'ArrowRight') {
            selectedIndex += 1;
        } else {
            selectedIndex -= 1;
        }

        const maxIndex = this.get('options').length - 1;
        if (selectedIndex > maxIndex) {
            selectedIndex = 0;
        } else if (selectedIndex < 0) {
            selectedIndex = maxIndex;
        }
        this._settingFromInput = true;
        this.set('selectedIndex', selectedIndex);
        this._settingFromInput = false;
    }.on('keydown'),
});

export { RadioGroupView };
<|endoftext|>


<commit_before>//-------------------------------------------------------------------------

var utils = require('../../../libs/utils.js');

//-------------------------------------------------------------------------

function Mover(mapView) {

    console.log("  building mover");

    this.mapView = mapView;

    this.lastMouseX = null;
    this.lastMouseY = null;
    this.autoMoving = false;
    this.mouseData = [];
    this.drawers = [];

    this.defaultMoveDistance = 300;
    this.defaultMoveMillis = 150;

    this.initListeners();
}

//-------------------------------------------------------------------------

Mover.prototype.initListeners = function (event) {

    this.mapView.on("panstart", function (event) {
        this.reset(event);
    }.bind(this));

    this.mapView.on("panmove", function (event) {
        this.panmove(event);
    }.bind(this));

    this.mapView.on("panend", function (event) {
        this.panend(event);
    }.bind(this));

    this.mapView.on("tap", function (event) {

        this.mapView.context.mouseP = utils.getPoint(event);
        this.mapView.context.mouseM = utils.converToMeters(
            this.mapView.canvas,
            this.mapView.context,
            this.mapView.context.mouseP
        );

    }.bind(this));

    //  var mover = this;

    //  this.mapView.mapCanvas.on(MaperialEvents.MOUSE_DOWN, function(){
    //  mover.reset();
    //  });

    //  this.context.mapCanvas.on(MaperialEvents.MOUSE_UP, function(){
    //  mover.receivedMouseUp();
    //  });

    //  $(window).on(MaperialEvents.DRAGGING_MAP, function(event, name){
    //  if(mover.mapView.name == name){
    //  mover.drag();
    //  }
    //  });

    //  this.context.mapCanvas.on(MaperialEvents.CONTROL_UP, function(){
    //  mover.moveUp();
    //  });

    //  this.context.mapCanvas.on(MaperialEvents.CONTROL_DOWN, function(){
    //  mover.moveDown();
    //  });

    //  this.context.mapCanvas.on(MaperialEvents.CONTROL_RIGHT, function(){
    //  mover.moveRight();
    //  });

    //  this.context.mapCanvas.on(MaperialEvents.CONTROL_LEFT, function(){
    //  mover.moveLeft();
    //  });
};

//--------------------------------------------------------------------

Mover.prototype.removeListeners = function () {

};

//-------------------------------------------------------------------------

Mover.prototype.reset = function (event) {
    this.mapView.context.mouseP = utils.getPoint(event);

    this.mouseData = [];
    this.autoMoving = false;

    this.lastMouseX = this.mapView.context.mouseP.x;
    this.lastMouseY = this.mapView.context.mouseP.y;
};

//-------------------------------------------------------------------------

Mover.prototype.panmove = function (event) {

    this.mapView.context.mouseP = utils.getPoint(event);
    this.mapView.context.mouseM = utils.converToMeters(
        this.mapView.canvas,
        this.mapView.context,
        this.mapView.context.mouseP
    );

    var newX = this.mapView.context.mouseP.x,
        newY = this.mapView.context.mouseP.y,
        deltaX = newX - this.lastMouseX,
        deltaY = newY - this.lastMouseY;

    this.lastMouseX = newX;
    this.lastMouseY = newY;

    this.registerMouseData(newX, newY);

    this.moveMap(deltaX, deltaY);
    this.moveDrawers(deltaX, deltaY);

};

//-------------------------------------------------------------------------
//Auto Move workflow

Mover.prototype.panend = function () {
    if (this.requireAutoMove()) {
        this.prepareAutoMove();
    }
};

//-------------------------------------------------------------------------

Mover.prototype.moveMap = function (dx, dy) {
    var r = this.mapView.context.coordS.Resolution(this.mapView.context.zoom);

    this.mapView.context.centerM.x -= dx * r;
    this.mapView.context.centerM.y += dy * r;

    this.mapView.trigger(Maperial.EVENTS.MAP_MOVED);
};

//-------------------------------------------------------------------------

Mover.prototype.requireAutoMove = function () {

    // on arrive dans des cas chelous qui petent tout parfois..
    if (this.mouseData.length < 3)
        return false;

    // recup des derniers moves de la souris
    var endPoint = this.mouseData.pop(),
        now = new Date().getTime();

    // verif si la souris n'a pas été statique à la fin = no automove
    return (now - endPoint.time <= 120);
};

Mover.prototype.prepareAutoMove = function () {

    var startPoint = this.mouseData[0],
        endPoint = this.mouseData.pop(),

        deltaX = endPoint.x - startPoint.x,
        deltaY = endPoint.y - startPoint.y,

        deltaTime = endPoint.time - startPoint.time;

    this.move(deltaX, deltaY, deltaTime);
};

//-------------------------------------------------------------------------

Mover.prototype.move = function (deltaX, deltaY, deltaTime) {

    var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY),

        speed = (distance * 1000 / deltaTime) / Maperial.refreshRate,

        speedX = (speed * deltaX / distance) * Maperial.autoMoveSpeedRate,
        speedY = (speed * deltaY / distance) * Maperial.autoMoveSpeedRate;

    this.autoMoving = true;

    this.moveScene(Maperial.autoMoveMillis, speedX, speedY, 0);
};

//-------------------------------------------------------------------------
//Controls

Mover.prototype.moveUp = function () {
    this.move(0, this.defaultMoveDistance, this.defaultMoveMillis);
};

Mover.prototype.moveDown = function () {
    this.move(0, -this.defaultMoveDistance, this.defaultMoveMillis);
};

Mover.prototype.moveRight = function () {
    this.move(-this.defaultMoveDistance, 0, this.defaultMoveMillis);
};

Mover.prototype.moveLeft = function () {
    this.move(this.defaultMoveDistance, 0, this.defaultMoveMillis);
};

//-------------------------------------------------------------------------

Mover.prototype.moveScene = function (timeRemaining, speedX, speedY, nbAutoMove) {

    if (timeRemaining < 0 || !this.autoMoving)
        return;

    if (isNaN(speedX)) {
        return;
    }

    this.moveMap(speedX, speedY);
    this.moveDrawers(speedX, speedY);

    var rate = 0.99 - nbAutoMove * Maperial.autoMoveDeceleration;

    var mover = this;
    setTimeout(function () {
        mover.moveScene(
            timeRemaining - Maperial.refreshRate,
            speedX * rate,
            speedY * rate,
            nbAutoMove + 1
        );
    }, Maperial.refreshRate);
};

Mover.prototype.registerMouseData = function (x, y) {

    if (this.mouseData.length >= Maperial.autoMoveAnalyseSize)
        this.mouseData.shift();

    var data = new Object();
    data.x = x;
    data.y = y;
    data.time = new Date().getTime();

    this.mouseData.push(data);

};

//-------------------------------------------------------------------------
//Drawers To Move

Mover.prototype.addDrawer = function (drawer) {
    this.drawers.push(drawer);
};

Mover.prototype.removeDrawer = function (drawer) {

    for (var i = 0; i < this.drawers.length; i++) {
        if (this.drawers[i] === drawer) {
            break;
        }
    }

    this.drawers.splice(i, 1);
};

Mover.prototype.resizeDrawers = function () {

    for (var i = 0; i < this.drawers.length; i++) {
        this.drawers[i].resize(this.config.width, this.config.height);
    }

};

Mover.prototype.moveDrawers = function (dx, dy) {
    for (var i = 0; i < this.drawers.length; i++) {
        var drawer = this.drawers[i];

        for (var j = 0; j < drawer.pointsToMove.length; j++) {
            var point = drawer.pointsToMove[j];
            point.x += dx;
            point.y += dy;
        }

        drawer.draw();
    }
};

//----------------------------------------------------------------

module.exports = Mover;
<commit_msg>mover : requestAnimationFrame !!!<commit_after>//-------------------------------------------------------------------------

var utils = require('../../../libs/utils.js');

//-------------------------------------------------------------------------

function Mover(mapView) {

    console.log("  building mover");

    this.mapView = mapView;

    this.lastMouseX = null;
    this.lastMouseY = null;
    this.autoMoving = false;
    this.mouseData = [];
    this.drawers = [];

    this.defaultMoveDistance = 300;
    this.defaultMoveMillis = 150;

    this.initListeners();
}

//-------------------------------------------------------------------------

Mover.prototype.initListeners = function (event) {

    this.mapView.on("panstart", function (event) {
        this.reset(event);
    }.bind(this));

    this.mapView.on("panmove", function (event) {
        this.panmove(event);
    }.bind(this));

    this.mapView.on("panend", function (event) {
        this.panend(event);
    }.bind(this));

    this.mapView.on("tap", function (event) {

        this.mapView.context.mouseP = utils.getPoint(event);
        this.mapView.context.mouseM = utils.converToMeters(
            this.mapView.canvas,
            this.mapView.context,
            this.mapView.context.mouseP
        );

    }.bind(this));

    //  var mover = this;

    //  this.mapView.mapCanvas.on(MaperialEvents.MOUSE_DOWN, function(){
    //  mover.reset();
    //  });

    //  this.context.mapCanvas.on(MaperialEvents.MOUSE_UP, function(){
    //  mover.receivedMouseUp();
    //  });

    //  $(window).on(MaperialEvents.DRAGGING_MAP, function(event, name){
    //  if(mover.mapView.name == name){
    //  mover.drag();
    //  }
    //  });

    //  this.context.mapCanvas.on(MaperialEvents.CONTROL_UP, function(){
    //  mover.moveUp();
    //  });

    //  this.context.mapCanvas.on(MaperialEvents.CONTROL_DOWN, function(){
    //  mover.moveDown();
    //  });

    //  this.context.mapCanvas.on(MaperialEvents.CONTROL_RIGHT, function(){
    //  mover.moveRight();
    //  });

    //  this.context.mapCanvas.on(MaperialEvents.CONTROL_LEFT, function(){
    //  mover.moveLeft();
    //  });
};

//--------------------------------------------------------------------

Mover.prototype.removeListeners = function () {

};

//-------------------------------------------------------------------------

Mover.prototype.reset = function (event) {
    this.mapView.context.mouseP = utils.getPoint(event);

    this.mouseData = [];
    this.autoMoving = false;

    this.lastMouseX = this.mapView.context.mouseP.x;
    this.lastMouseY = this.mapView.context.mouseP.y;
};

//-------------------------------------------------------------------------

Mover.prototype.panmove = function (event) {

    this.mapView.context.mouseP = utils.getPoint(event);
    this.mapView.context.mouseM = utils.converToMeters(
        this.mapView.canvas,
        this.mapView.context,
        this.mapView.context.mouseP
    );

    var newX = this.mapView.context.mouseP.x,
        newY = this.mapView.context.mouseP.y,
        deltaX = newX - this.lastMouseX,
        deltaY = newY - this.lastMouseY;

    this.lastMouseX = newX;
    this.lastMouseY = newY;

    this.registerMouseData(newX, newY);

    this.moveMap(deltaX, deltaY);
    this.moveDrawers(deltaX, deltaY);

};

//-------------------------------------------------------------------------
//Auto Move workflow

Mover.prototype.panend = function () {
    if (this.requireAutoMove()) {
        this.prepareAutoMove();
    }
};

//-------------------------------------------------------------------------

Mover.prototype.moveMap = function (dx, dy) {
    var r = this.mapView.context.coordS.Resolution(this.mapView.context.zoom);

    this.mapView.context.centerM.x -= dx * r;
    this.mapView.context.centerM.y += dy * r;

    this.mapView.trigger(Maperial.EVENTS.MAP_MOVED);
};

//-------------------------------------------------------------------------

Mover.prototype.requireAutoMove = function () {

    // on arrive dans des cas chelous qui petent tout parfois..
    if (this.mouseData.length < 3)
        return false;

    // recup des derniers moves de la souris
    var endPoint = this.mouseData.pop(),
        now = new Date().getTime();

    // verif si la souris n'a pas été statique à la fin = no automove
    return (now - endPoint.time <= 120);
};

Mover.prototype.prepareAutoMove = function () {

    var startPoint = this.mouseData[0],
        endPoint = this.mouseData.pop(),

        deltaX = endPoint.x - startPoint.x,
        deltaY = endPoint.y - startPoint.y,

        deltaTime = endPoint.time - startPoint.time;

    this.move(deltaX, deltaY, deltaTime);
};

//-------------------------------------------------------------------------

Mover.prototype.move = function (deltaX, deltaY, deltaTime) {

    var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY),

        speed = (distance * 1000 / deltaTime) / Maperial.refreshRate,

        speedX = (speed * deltaX / distance) * Maperial.autoMoveSpeedRate,
        speedY = (speed * deltaY / distance) * Maperial.autoMoveSpeedRate;

    this.autoMoving = true;

    this.moveScene(Maperial.autoMoveMillis, speedX, speedY, 0);
};

//-------------------------------------------------------------------------
//Controls

Mover.prototype.moveUp = function () {
    this.move(0, this.defaultMoveDistance, this.defaultMoveMillis);
};

Mover.prototype.moveDown = function () {
    this.move(0, -this.defaultMoveDistance, this.defaultMoveMillis);
};

Mover.prototype.moveRight = function () {
    this.move(-this.defaultMoveDistance, 0, this.defaultMoveMillis);
};

Mover.prototype.moveLeft = function () {
    this.move(this.defaultMoveDistance, 0, this.defaultMoveMillis);
};

//-------------------------------------------------------------------------

Mover.prototype.moveScene = function (timeRemaining, speedX, speedY, nbAutoMove) {

    if (timeRemaining < 0 || !this.autoMoving)
        return;

    if (isNaN(speedX)) {
        return;
    }

    this.moveMap(speedX, speedY);
    this.moveDrawers(speedX, speedY);

    var rate = 0.99 - nbAutoMove * Maperial.autoMoveDeceleration;

    var mover = this;
    requestAnimationFrame(function () {
        mover.moveScene(
            timeRemaining - Maperial.refreshRate,
            speedX * rate,
            speedY * rate,
            nbAutoMove + 1
        );
    });
};

Mover.prototype.registerMouseData = function (x, y) {

    if (this.mouseData.length >= Maperial.autoMoveAnalyseSize)
        this.mouseData.shift();

    var data = new Object();
    data.x = x;
    data.y = y;
    data.time = new Date().getTime();

    this.mouseData.push(data);

};

//-------------------------------------------------------------------------
//Drawers To Move

Mover.prototype.addDrawer = function (drawer) {
    this.drawers.push(drawer);
};

Mover.prototype.removeDrawer = function (drawer) {

    for (var i = 0; i < this.drawers.length; i++) {
        if (this.drawers[i] === drawer) {
            break;
        }
    }

    this.drawers.splice(i, 1);
};

Mover.prototype.resizeDrawers = function () {

    for (var i = 0; i < this.drawers.length; i++) {
        this.drawers[i].resize(this.config.width, this.config.height);
    }

};

Mover.prototype.moveDrawers = function (dx, dy) {
    for (var i = 0; i < this.drawers.length; i++) {
        var drawer = this.drawers[i];

        for (var j = 0; j < drawer.pointsToMove.length; j++) {
            var point = drawer.pointsToMove[j];
            point.x += dx;
            point.y += dy;
        }

        drawer.draw();
    }
};

//----------------------------------------------------------------

module.exports = Mover;
<|endoftext|>


<commit_before>/* Python 'tuple' type */

var tuple = __inherit(object, "tuple");

tuple.prototype.__init__ = function(seq) {

    if (arguments.length > 1) {
        throw py_builtins.TypeError.__call__("tuple() takes at most 1 argument (" + arguments.length + " given)");
    } else if (!defined(seq)) {
        this._items = [];
        this._len = 0;
    } else {
        this._items = copy(iter.__call__(seq));
        this._len = -1;
    }
};

tuple.prototype.__str__ = function () {
    if (this.__len__() == 0) {
        return str.__call__("()");
    } else if (this.__len__() == 1) {
        return str.__call__("(" + str.__call__(this._items[0]) + ",)");
    } else {
        var items = map(function (i) {return str.__call__(i);}, this._items);
        return str.__call__("(" + str.__call__(", ").join(items) + ")");
    }
};

tuple.prototype.__repr__ = tuple.prototype.__str__;

tuple.prototype.__eq__ = function (other) {
    if (other.__class__ == this.__class__) {
        if (len(this) != len(other))
            return false;
        for (var i = 0; i < len(this); i++) {
            // TODO: use __eq__ here as well:
            if (this._items[i] != other._items[i])
                return false;
        }
        return true;
        // This doesn't take into account hash collisions:
        //return hash(this) == hash(other)
    } else
        return false;
};

tuple.prototype.toString = function () {
    return js(this.__str__());
};

tuple.prototype._js_ = function () {
    var items = [];

    iterate(iter.__call__(this), function(item) {
        items.push(js(item));
    });

    return items;
};

tuple.prototype.__hash__ = function () {
    var value = 0x345678;
    var length = this.__len__();

    for (var index in this._items) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ hash(this._items[index]);
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

tuple.prototype.__len__ = function() {
    if (this._len == -1) {
        var count = 0;

        for (var index in this._items) {
            count += 1;
        }

        this._len = count;
        return count;
    } else
        return this._len;
};

tuple.prototype.__iter__ = function() {
    return iter.__call__(this._items);
};

tuple.prototype.__contains__ = function(item) {
    for (var index in this._items) {
        if (py_builtins.eq(item, this._items[index])) {
            return true;
        }
    }

    return false;
};

tuple.prototype.__getitem__ = function(index) {
    var seq;
    if (isinstance.__call__(index, slice)) {
        var s = index;
        var inds = s.indices(len(this));
        var start = inds.__getitem__(0);
        var stop = inds.__getitem__(1);
        var step = inds.__getitem__(2);
        seq = [];
        for (var i = start; i < stop; i += step) {
            seq.push(this.__getitem__(i));
        }
        return this.__class__.__call__(seq);
    } else if ((index >= 0) && (index < len(this)))
        return this._items[index];
    else if ((index < 0) && (index >= -len(this)))
        return this._items[index+len(this)];
    else
        throw py_builtins.IndexError.__call__("list assignment index out of range");
};

tuple.prototype.__setitem__ = function(index, value) {
    throw py_builtins.TypeError.__call__("'tuple' object doesn't support item assignment");
};

tuple.prototype.__delitem__ = function(index) {
    throw py_builtins.TypeError.__call__("'tuple' object doesn't support item deletion");
};

tuple.prototype.count = Function(function(value) {
    var count = 0;

    for (var index in this._items) {
        if (value == this._items[index]) {
            count += 1;
        }
    }

    return count;
});

tuple.prototype.index = Function(function(value, start, end) {
    if (!defined(start)) {
        start = 0;
    }

    for (var i = start; !defined(end) || (start < end); i++) {
        var _value = this._items[i];

        if (!defined(_value)) {
            break;
        }

        if (_value == value) {
            return i;
        }
    }

    throw py_builtins.ValueError.__call__("tuple.index(x): x not in list");
});

<commit_msg> - Removed obsolete tuple.toString()<commit_after>/* Python 'tuple' type */

var tuple = __inherit(object, "tuple");

tuple.prototype.__init__ = function(seq) {

    if (arguments.length > 1) {
        throw py_builtins.TypeError.__call__("tuple() takes at most 1 argument (" + arguments.length + " given)");
    } else if (!defined(seq)) {
        this._items = [];
        this._len = 0;
    } else {
        this._items = copy(iter.__call__(seq));
        this._len = -1;
    }
};

tuple.prototype.__str__ = function () {
    if (this.__len__() == 0) {
        return str.__call__("()");
    } else if (this.__len__() == 1) {
        return str.__call__("(" + str.__call__(this._items[0]) + ",)");
    } else {
        var items = map(function (i) {return str.__call__(i);}, this._items);
        return str.__call__("(" + str.__call__(", ").join(items) + ")");
    }
};

tuple.prototype.__repr__ = tuple.prototype.__str__;

tuple.prototype.__eq__ = function (other) {
    if (other.__class__ == this.__class__) {
        if (len(this) != len(other))
            return false;
        for (var i = 0; i < len(this); i++) {
            // TODO: use __eq__ here as well:
            if (this._items[i] != other._items[i])
                return false;
        }
        return true;
        // This doesn't take into account hash collisions:
        //return hash(this) == hash(other)
    } else
        return false;
};

tuple.prototype._js_ = function () {
    var items = [];

    iterate(iter.__call__(this), function(item) {
        items.push(js(item));
    });

    return items;
};

tuple.prototype.__hash__ = function () {
    var value = 0x345678;
    var length = this.__len__();

    for (var index in this._items) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ hash(this._items[index]);
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

tuple.prototype.__len__ = function() {
    if (this._len == -1) {
        var count = 0;

        for (var index in this._items) {
            count += 1;
        }

        this._len = count;
        return count;
    } else
        return this._len;
};

tuple.prototype.__iter__ = function() {
    return iter.__call__(this._items);
};

tuple.prototype.__contains__ = function(item) {
    for (var index in this._items) {
        if (py_builtins.eq(item, this._items[index])) {
            return true;
        }
    }

    return false;
};

tuple.prototype.__getitem__ = function(index) {
    var seq;
    if (isinstance.__call__(index, slice)) {
        var s = index;
        var inds = s.indices(len(this));
        var start = inds.__getitem__(0);
        var stop = inds.__getitem__(1);
        var step = inds.__getitem__(2);
        seq = [];
        for (var i = start; i < stop; i += step) {
            seq.push(this.__getitem__(i));
        }
        return this.__class__.__call__(seq);
    } else if ((index >= 0) && (index < len(this)))
        return this._items[index];
    else if ((index < 0) && (index >= -len(this)))
        return this._items[index+len(this)];
    else
        throw py_builtins.IndexError.__call__("list assignment index out of range");
};

tuple.prototype.__setitem__ = function(index, value) {
    throw py_builtins.TypeError.__call__("'tuple' object doesn't support item assignment");
};

tuple.prototype.__delitem__ = function(index) {
    throw py_builtins.TypeError.__call__("'tuple' object doesn't support item deletion");
};

tuple.prototype.count = Function(function(value) {
    var count = 0;

    for (var index in this._items) {
        if (value == this._items[index]) {
            count += 1;
        }
    }

    return count;
});

tuple.prototype.index = Function(function(value, start, end) {
    if (!defined(start)) {
        start = 0;
    }

    for (var i = start; !defined(end) || (start < end); i++) {
        var _value = this._items[i];

        if (!defined(_value)) {
            break;
        }

        if (_value == value) {
            return i;
        }
    }

    throw py_builtins.ValueError.__call__("tuple.index(x): x not in list");
});

<|endoftext|>


<commit_before>import utils from 'osg/utils';
import NodeVisitor from 'osg/NodeVisitor';
import Geometry from 'osg/Geometry';
import BufferArray from 'osg/BufferArray';
import DrawArrays from 'osg/DrawArrays';
import primitiveSet from 'osg/primitiveSet';
import StateSet from 'osg/StateSet';
import Uniform from 'osg/Uniform';
import Depth from 'osg/Depth';
import { vec3 } from 'osg/glMatrix';
import ShaderGenerator from 'osgShader/ShaderGenerator';
import Compiler from 'osgShader/Compiler';
import RigGeometry from 'osgAnimation/RigGeometry';
import MorphGeometry from 'osgAnimation/MorphGeometry';
import UpdateMorph from 'osgAnimation/UpdateMorph';

////////////////////////
// COMPILER OFFSET NORMAL
////////////////////////
var CompilerOffsetNormal = function() {
    Compiler.apply(this, arguments);
};

var configNormal = Compiler.cloneStateAttributeConfig(Compiler);
configNormal.textureAttribute = [];

Compiler.setStateAttributeConfig(CompilerOffsetNormal, configNormal);

utils.createPrototypeObject(
    CompilerOffsetNormal,
    utils.objectInherit(Compiler.prototype, {
        getCompilerName: function() {
            return 'CompilerOffsetNormal';
        },
        initTextureAttributes: function() {},
        createFragmentShaderGraph: function() {
            var frag = this.getNode('glFragColor');

            this.getNode('SetAlpha')
                .inputs({
                    color: this.getOrCreateUniform('vec3', 'uColorDebug'),
                    alpha: this.createVariable('float').setValue('1.0')
                })
                .outputs({
                    result: frag
                });

            return [frag];
        },
        getOffsetDirection: function() {
            return this.getOrCreateModelNormal();
        },
        getOrCreateModelVertex: function() {
            var vertexOffset = this.getVariable('vertexOffset');
            if (vertexOffset) return vertexOffset;

            vertexOffset = this.createVariable('vec3', 'vertexOffset');

            var str =
                '%out = %offset == 1.0 ? %vertex + normalize(%direction.xyz) * %scale: %vertex;';
            this.getNode('InlineCode')
                .code(str)
                .inputs({
                    offset: this.getOrCreateAttribute('float', 'Offset'),
                    direction: this.getOffsetDirection(),
                    vertex: Compiler.prototype.getOrCreateModelVertex.call(this),
                    scale: this.getOrCreateUniform('float', 'uScale')
                })
                .outputs({
                    out: vertexOffset
                });

            return vertexOffset;
        },
        getOrCreateViewVertex: function() {
            var out = this._variables.FragEyeVector;
            if (out && !out.isEmpty()) return out;
            out = this._varyings.FragEyeVector || this.createVariable('vec4', 'FragEyeVector');

            this.getNode('MatrixMultPosition')
                .inputs({
                    matrix: this.getOrCreateUniform('mat4', 'uViewMatrix'),
                    vec: this.getOrCreateModelVertex()
                })
                .outputs({
                    vec: out
                });

            return out;
        }
    }),
    'osgUtil',
    'CompilerOffsetNormal'
);

var ShaderGeneratorCompilerOffsetNormal = function() {
    ShaderGenerator.apply(this, arguments);
    this.setShaderCompiler(CompilerOffsetNormal);
};
utils.createPrototypeObject(
    ShaderGeneratorCompilerOffsetNormal,
    utils.objectInherit(ShaderGenerator.prototype, {}),
    'osgUtil',
    'ShaderGeneratorCompilerOffsetNormal'
);

////////////////////////
// COMPILER OFFSET TANGENT
////////////////////////
var CompilerOffsetTangent = function() {
    CompilerOffsetNormal.apply(this, arguments);
};

var configTangent = configNormal;
Compiler.setStateAttributeConfig(CompilerOffsetTangent, configTangent);

utils.createPrototypeObject(
    CompilerOffsetTangent,
    utils.objectInherit(CompilerOffsetNormal.prototype, {
        getCompilerName: function() {
            return 'CompilerOffsetTangent';
        },
        getOffsetDirection: function() {
            return this.getOrCreateModelTangent();
        }
    }),
    'osgUtil',
    'CompilerOffsetTangent'
);

var ShaderGeneratorCompilerOffsetTangent = function() {
    ShaderGenerator.apply(this, arguments);
    this.setShaderCompiler(CompilerOffsetTangent);
};

utils.createPrototypeObject(
    ShaderGeneratorCompilerOffsetTangent,
    utils.objectInherit(ShaderGenerator.prototype, {}),
    'osgUtil',
    'ShaderGeneratorCompilerOffsetTangent'
);

////////////////////////
// DISPLAY NORMAL VISITOR
////////////////////////

var DisplayNormalVisitor = function() {
    NodeVisitor.call(this);

    this._unifScale = Uniform.createFloat(1.0, 'uScale');

    var ns = (this._normalStateSet = new StateSet());
    ns.addUniform(Uniform.createFloat3(vec3.fromValues(1.0, 0.0, 0.0), 'uColorDebug'));
    ns.addUniform(this._unifScale);
    ns.setAttributeAndModes(new Depth(Depth.NEVER));
    ns.setShaderGeneratorName('debugNormal');

    var ts = (this._tangentStateSet = new StateSet());
    ts.addUniform(Uniform.createFloat3(vec3.fromValues(0.0, 1.0, 0.0), 'uColorDebug'));
    ts.addUniform(this._unifScale);
    ts.setAttributeAndModes(new Depth(Depth.NEVER));
    ts.setShaderGeneratorName('debugTangent');
};

DisplayNormalVisitor.CompilerOffsetNormal = CompilerOffsetNormal;
DisplayNormalVisitor.CompilerOffsetTangent = CompilerOffsetTangent;
DisplayNormalVisitor.ShaderGeneratorCompilerOffsetNormal = ShaderGeneratorCompilerOffsetNormal;
DisplayNormalVisitor.ShaderGeneratorCompilerOffsetTangent = ShaderGeneratorCompilerOffsetTangent;

utils.createPrototypeObject(
    DisplayNormalVisitor,
    utils.objectInherit(NodeVisitor.prototype, {
        setScale: function(scale) {
            this._unifScale.setFloat(scale);
        },
        setTangentVisibility: function(bool) {
            this._tangentStateSet.setAttributeAndModes(new Depth(bool ? Depth.LESS : Depth.NEVER));
        },
        setNormalVisibility: function(bool) {
            this._normalStateSet.setAttributeAndModes(new Depth(bool ? Depth.LESS : Depth.NEVER));
        },
        apply: function(node) {
            var list = node.getUpdateCallbackList();
            // dirty the UpdateMorph so that they detect the normal/tangent geometry and update the target/weights correctly
            for (var i = 0, nbCB = list.length; i < nbCB; ++i) {
                if (list[i] instanceof UpdateMorph) {
                    list[i]._isInitialized = false;
                }
            }

            if (node._isVisitedNormalDebug) return;

            node._isVisitedNormalDebug = true;

            if (node instanceof Geometry === false) return this.traverse(node);

            this._createDebugGeom(node, 'Normal', this._normalStateSet);
            this._createDebugGeom(node, 'Tangent', this._tangentStateSet);
        },
        _createDoubleOffsetArray: function(nbVertices) {
            // 0 means original vertex pos
            // 1 means offseted vertex
            var elts = new Float32Array(nbVertices * 2);
            for (var i = 0; i < nbVertices; ++i) {
                elts[i * 2] = 1.0;
            }
            return new BufferArray(BufferArray.ARRAY_BUFFER, elts, 1);
        },
        _createDoubledBufferArray: function(bufferArray) {
            // in case of morphs
            if (bufferArray.getInitialBufferArray)
                bufferArray = bufferArray.getInitialBufferArray();

            var itemSize = bufferArray.getItemSize();
            var elements = bufferArray.getElements();
            var nbElements = elements.length / itemSize;

            var ctor = elements.constructor;
            var elementsDouble = new ctor(elements.length * 2);
            for (var i = 0; i < nbElements; ++i) {
                var iSize = i * itemSize;
                var iSize2 = iSize * 2;

                for (var j = 0; j < itemSize; ++j) {
                    elementsDouble[iSize2 + j] = elementsDouble[iSize2 + j + itemSize] =
                        elements[iSize + j];
                }
            }

            return new BufferArray(BufferArray.ARRAY_BUFFER, elementsDouble, itemSize);
        },
        _addMorphTargets: function(originMorph, morph, vecName) {
            var targets = morph.getMorphTargets();
            morph.setName(originMorph.getName()); // for the UpdateMorph

            var originTargets = originMorph.getMorphTargets();
            for (var i = 0, nbTarget = originTargets.length; i < nbTarget; ++i) {
                var origTarget = originTargets[i];
                var origAttrs = origTarget.getVertexAttributeList();

                var newTarget = new Geometry();
                newTarget.setName(origTarget.getName()); // for the UpdateMorph
                var newAttrs = newTarget.getVertexAttributeList();

                newAttrs.Vertex = this._createDoubledBufferArray(origAttrs.Vertex);
                if (origAttrs[vecName])
                    newAttrs[vecName] = this._createDoubledBufferArray(origAttrs[vecName]);

                targets.push(newTarget);
            }

            morph.mergeChildrenVertexAttributeList();
            return morph;
        },
        _createDebugGeom: function(node, vecName, stateSet) {
            var attrs = node.getAttributes();
            var dispVec = attrs[vecName];
            if (!dispVec) return;

            var vertices = attrs.Vertex;
            if (!vertices) return;

            var originMorph;
            if (node instanceof MorphGeometry) originMorph = node;
            else if (node.getSourceGeometry && node.getSourceGeometry() instanceof MorphGeometry)
                originMorph = node.getSourceGeometry();

            var nbVertices = vertices.getElements().length / vertices.getItemSize();

            // vertex and normals
            var source = originMorph ? new MorphGeometry() : new Geometry();
            source.getAttributes().Vertex = this._createDoubledBufferArray(vertices);
            source.getAttributes().Offset = this._createDoubleOffsetArray(nbVertices);
            source.getAttributes()[vecName] = this._createDoubledBufferArray(dispVec);

            // primitive
            source.getPrimitives().push(new DrawArrays(primitiveSet.LINES, 0, nbVertices * 2));

            if (originMorph) this._addMorphTargets(originMorph, source, vecName);

            var geom;
            if (node instanceof RigGeometry) {
                var rig = new RigGeometry();
                rig.setSourceGeometry(source);

                rig.getVertexAttributeList().Bones = this._createDoubledBufferArray(attrs.Bones);
                rig.getVertexAttributeList().Weights = this._createDoubledBufferArray(
                    attrs.Weights
                );

                // we can simply share the rig-animated stateSet attributes
                // (unlike morph, the stateSet and update animation doesn't operate at per vertex level)
                rig._rigTransformImplementation = node._rigTransformImplementation;
                rig._stateSetAnimation = node._stateSetAnimation;

                rig.mergeChildrenData();
                geom = rig;
            } else {
                geom = source;
            }

            // add geom to the graph
            var parents = node.getParents();
            var nbParents = parents.length;
            geom._isVisitedNormalDebug = true;
            geom._isNormalDebug = true;
            geom.setStateSet(stateSet);
            for (var i = 0; i < nbParents; ++i) parents[i].addChild(geom);

            return geom;
        }
    }),
    'osgUtil',
    'DisplayNormalVisitor'
);

export default DisplayNormalVisitor;
<commit_msg>Fixes normal display with morph geometry<commit_after>import utils from 'osg/utils';
import NodeVisitor from 'osg/NodeVisitor';
import Geometry from 'osg/Geometry';
import BufferArray from 'osg/BufferArray';
import DrawArrays from 'osg/DrawArrays';
import primitiveSet from 'osg/primitiveSet';
import StateSet from 'osg/StateSet';
import Uniform from 'osg/Uniform';
import Depth from 'osg/Depth';
import { vec3 } from 'osg/glMatrix';
import ShaderGenerator from 'osgShader/ShaderGenerator';
import Compiler from 'osgShader/Compiler';
import RigGeometry from 'osgAnimation/RigGeometry';
import MorphGeometry from 'osgAnimation/MorphGeometry';
import UpdateMorph from 'osgAnimation/UpdateMorph';

////////////////////////
// COMPILER OFFSET NORMAL
////////////////////////
var CompilerOffsetNormal = function() {
    Compiler.apply(this, arguments);
};

var configNormal = Compiler.cloneStateAttributeConfig(Compiler);
configNormal.textureAttribute = [];

Compiler.setStateAttributeConfig(CompilerOffsetNormal, configNormal);

utils.createPrototypeObject(
    CompilerOffsetNormal,
    utils.objectInherit(Compiler.prototype, {
        getCompilerName: function() {
            return 'CompilerOffsetNormal';
        },
        initTextureAttributes: function() {},
        createFragmentShaderGraph: function() {
            var frag = this.getNode('glFragColor');

            this.getNode('SetAlpha')
                .inputs({
                    color: this.getOrCreateUniform('vec3', 'uColorDebug'),
                    alpha: this.createVariable('float').setValue('1.0')
                })
                .outputs({
                    result: frag
                });

            return [frag];
        },
        getOffsetDirection: function() {
            return this.getOrCreateModelNormal();
        },
        getOrCreateModelVertex: function() {
            var vertexOffset = this.getVariable('vertexOffset');
            if (vertexOffset) return vertexOffset;

            vertexOffset = this.createVariable('vec3', 'vertexOffset');

            var str =
                '%out = %offset == 1.0 ? %vertex + normalize(%direction.xyz) * %scale: %vertex;';
            this.getNode('InlineCode')
                .code(str)
                .inputs({
                    offset: this.getOrCreateAttribute('float', 'Offset'),
                    direction: this.getOffsetDirection(),
                    vertex: Compiler.prototype.getOrCreateModelVertex.call(this),
                    scale: this.getOrCreateUniform('float', 'uScale')
                })
                .outputs({
                    out: vertexOffset
                });

            return vertexOffset;
        },
        getOrCreateViewVertex: function() {
            var out = this._variables.FragEyeVector;
            if (out && !out.isEmpty()) return out;
            out = this._varyings.FragEyeVector || this.createVariable('vec4', 'FragEyeVector');

            this.getNode('MatrixMultPosition')
                .inputs({
                    matrix: this.getOrCreateUniform('mat4', 'uViewMatrix'),
                    vec: this.getOrCreateModelVertex()
                })
                .outputs({
                    vec: out
                });

            return out;
        }
    }),
    'osgUtil',
    'CompilerOffsetNormal'
);

var ShaderGeneratorCompilerOffsetNormal = function() {
    ShaderGenerator.apply(this, arguments);
    this.setShaderCompiler(CompilerOffsetNormal);
};
utils.createPrototypeObject(
    ShaderGeneratorCompilerOffsetNormal,
    utils.objectInherit(ShaderGenerator.prototype, {}),
    'osgUtil',
    'ShaderGeneratorCompilerOffsetNormal'
);

////////////////////////
// COMPILER OFFSET TANGENT
////////////////////////
var CompilerOffsetTangent = function() {
    CompilerOffsetNormal.apply(this, arguments);
};

var configTangent = configNormal;
Compiler.setStateAttributeConfig(CompilerOffsetTangent, configTangent);

utils.createPrototypeObject(
    CompilerOffsetTangent,
    utils.objectInherit(CompilerOffsetNormal.prototype, {
        getCompilerName: function() {
            return 'CompilerOffsetTangent';
        },
        getOffsetDirection: function() {
            return this.getOrCreateModelTangent();
        }
    }),
    'osgUtil',
    'CompilerOffsetTangent'
);

var ShaderGeneratorCompilerOffsetTangent = function() {
    ShaderGenerator.apply(this, arguments);
    this.setShaderCompiler(CompilerOffsetTangent);
};

utils.createPrototypeObject(
    ShaderGeneratorCompilerOffsetTangent,
    utils.objectInherit(ShaderGenerator.prototype, {}),
    'osgUtil',
    'ShaderGeneratorCompilerOffsetTangent'
);

////////////////////////
// DISPLAY NORMAL VISITOR
////////////////////////

var DisplayNormalVisitor = function() {
    NodeVisitor.call(this);

    this._unifScale = Uniform.createFloat(1.0, 'uScale');

    var ns = (this._normalStateSet = new StateSet());
    ns.addUniform(Uniform.createFloat3(vec3.fromValues(1.0, 0.0, 0.0), 'uColorDebug'));
    ns.addUniform(this._unifScale);
    ns.setAttributeAndModes(new Depth(Depth.NEVER));
    ns.setShaderGeneratorName('debugNormal');

    var ts = (this._tangentStateSet = new StateSet());
    ts.addUniform(Uniform.createFloat3(vec3.fromValues(0.0, 1.0, 0.0), 'uColorDebug'));
    ts.addUniform(this._unifScale);
    ts.setAttributeAndModes(new Depth(Depth.NEVER));
    ts.setShaderGeneratorName('debugTangent');
};

DisplayNormalVisitor.CompilerOffsetNormal = CompilerOffsetNormal;
DisplayNormalVisitor.CompilerOffsetTangent = CompilerOffsetTangent;
DisplayNormalVisitor.ShaderGeneratorCompilerOffsetNormal = ShaderGeneratorCompilerOffsetNormal;
DisplayNormalVisitor.ShaderGeneratorCompilerOffsetTangent = ShaderGeneratorCompilerOffsetTangent;

utils.createPrototypeObject(
    DisplayNormalVisitor,
    utils.objectInherit(NodeVisitor.prototype, {
        setScale: function(scale) {
            this._unifScale.setFloat(scale);
        },
        setTangentVisibility: function(bool) {
            this._tangentStateSet.setAttributeAndModes(new Depth(bool ? Depth.LESS : Depth.NEVER));
        },
        setNormalVisibility: function(bool) {
            this._normalStateSet.setAttributeAndModes(new Depth(bool ? Depth.LESS : Depth.NEVER));
        },
        apply: function(node) {
            if (node._isVisitedNormalDebug) return;
            node._isVisitedNormalDebug = true;

            if (node instanceof Geometry) {
                this._createDebugGeom(node, 'Normal', this._normalStateSet);
                this._createDebugGeom(node, 'Tangent', this._tangentStateSet);
                return;
            }

            this.traverse(node);

            var list = node.getUpdateCallbackList();
            // reference the new morph geometry on the UpdateMorph callbacks
            for (var i = 0, nbCB = list.length; i < nbCB; ++i) {
                if (list[i] instanceof UpdateMorph) {
                    list[i].init(node);
                }
            }
        },
        _createDoubleOffsetArray: function(nbVertices) {
            // 0 means original vertex pos
            // 1 means offseted vertex
            var elts = new Float32Array(nbVertices * 2);
            for (var i = 0; i < nbVertices; ++i) {
                elts[i * 2] = 1.0;
            }
            return new BufferArray(BufferArray.ARRAY_BUFFER, elts, 1);
        },
        _createDoubledBufferArray: function(bufferArray) {
            // in case of morphs
            if (bufferArray.getInitialBufferArray)
                bufferArray = bufferArray.getInitialBufferArray();

            var itemSize = bufferArray.getItemSize();
            var elements = bufferArray.getElements();
            var nbElements = elements.length / itemSize;

            var ctor = elements.constructor;
            var elementsDouble = new ctor(elements.length * 2);
            for (var i = 0; i < nbElements; ++i) {
                var iSize = i * itemSize;
                var iSize2 = iSize * 2;

                for (var j = 0; j < itemSize; ++j) {
                    elementsDouble[iSize2 + j] = elementsDouble[iSize2 + j + itemSize] =
                        elements[iSize + j];
                }
            }

            return new BufferArray(BufferArray.ARRAY_BUFFER, elementsDouble, itemSize);
        },
        _addMorphTargets: function(originMorph, morph, vecName) {
            var targets = morph.getMorphTargets();
            morph.setName(originMorph.getName()); // for the UpdateMorph

            var originTargets = originMorph.getMorphTargets();
            for (var i = 0, nbTarget = originTargets.length; i < nbTarget; ++i) {
                var origTarget = originTargets[i];
                var origAttrs = origTarget.getVertexAttributeList();

                var newTarget = new Geometry();
                newTarget.setName(origTarget.getName()); // for the UpdateMorph
                var newAttrs = newTarget.getVertexAttributeList();

                newAttrs.Vertex = this._createDoubledBufferArray(origAttrs.Vertex);
                if (origAttrs[vecName])
                    newAttrs[vecName] = this._createDoubledBufferArray(origAttrs[vecName]);

                targets.push(newTarget);
            }

            morph.mergeChildrenVertexAttributeList();
            return morph;
        },
        _createDebugGeom: function(node, vecName, stateSet) {
            var attrs = node.getAttributes();
            var dispVec = attrs[vecName];
            if (!dispVec) return;

            var vertices = attrs.Vertex;
            if (!vertices) return;

            var originMorph;
            if (node instanceof MorphGeometry) originMorph = node;
            else if (node.getSourceGeometry && node.getSourceGeometry() instanceof MorphGeometry)
                originMorph = node.getSourceGeometry();

            var nbVertices = vertices.getElements().length / vertices.getItemSize();

            // vertex and normals
            var source = originMorph ? new MorphGeometry() : new Geometry();
            source.getAttributes().Vertex = this._createDoubledBufferArray(vertices);
            source.getAttributes().Offset = this._createDoubleOffsetArray(nbVertices);
            source.getAttributes()[vecName] = this._createDoubledBufferArray(dispVec);

            // primitive
            source.getPrimitives().push(new DrawArrays(primitiveSet.LINES, 0, nbVertices * 2));

            if (originMorph) this._addMorphTargets(originMorph, source, vecName);

            var geom;
            if (node instanceof RigGeometry) {
                var rig = new RigGeometry();
                rig.setSourceGeometry(source);

                rig.getVertexAttributeList().Bones = this._createDoubledBufferArray(attrs.Bones);
                rig.getVertexAttributeList().Weights = this._createDoubledBufferArray(
                    attrs.Weights
                );

                // we can simply share the rig-animated stateSet attributes
                // (unlike morph, the stateSet and update animation doesn't operate at per vertex level)
                rig._rigTransformImplementation = node._rigTransformImplementation;
                rig._stateSetAnimation = node._stateSetAnimation;

                rig.mergeChildrenData();
                geom = rig;
            } else {
                geom = source;
            }

            // add geom to the graph
            var parents = node.getParents();
            var nbParents = parents.length;
            geom._isVisitedNormalDebug = true;
            geom._isNormalDebug = true;
            geom.setStateSet(stateSet);
            for (var i = 0; i < nbParents; ++i) parents[i].addChild(geom);

            return geom;
        }
    }),
    'osgUtil',
    'DisplayNormalVisitor'
);

export default DisplayNormalVisitor;
<|endoftext|>


<commit_before>(function() {
  var editor;

  function useACE(yes) {
    console.log("ACE: %s", yes);
    if (yes) {
      $('#body').hide();
      $('#editor').show();
      $('#editor_toggle_value')[0].checked = true;
      $.cookie('use-ace', true);
    } else {
      $('#body').show();
      $('#editor').hide();
      $('#editor_toggle_value')[0].checked = false;
      $.cookie('use-ace', false);
    }
  }

  function syncBodyToEditor() {
    editor.setValue($('#body').val());

  }

  function syncEditorToBody() {
    $('#body').val(editor.getValue());
  }

  $(document).ready(function() {
    console.log($('#editor_toggle_value'));
    if (ace) {
      $('#editor_toggle').show();
      editor = ace.edit("editor");
      editor.setTheme("ace/theme/monokai");
      editor.getSession().setMode("ace/mode/markdown");
      editor.getSession().on('change', syncEditorToBody);
      $('#body').change(syncBodyToEditor);
      $.cookie.json = true;
      if ($.cookie('use-ace')) {
        useACE(true);
      } else {
        useACE(false);
      }
    }
    syncBodyToEditor();
    $('#editor_toggle_value').change(function() {
      useACE($('#editor_toggle_value')[0].checked);
    });
  });
})();
<commit_msg>Fix up editor.js errors<commit_after>(function() {
  var editor;

  function useACE(yes) {
    console.log("ACE: %s", yes);
    if (yes) {
      $('#body').hide();
      $('#editor').show();
      $('#editor_toggle_value')[0].checked = true;
      $.cookie('use-ace', true);
    } else {
      $('#body').show();
      $('#editor').hide();
      $('#editor_toggle_value')[0].checked = false;
      $.cookie('use-ace', false);
    }
  }

  function syncBodyToEditor() {
    editor.setValue($('#body').val());

  }

  function syncEditorToBody() {
    $('#body').val(editor.getValue());
  }

  $(document).ready(function() {
    if ($('#editor').length > 0) {
      if (ace) {
        $('#editor_toggle').show();
        editor = ace.edit("editor");
        editor.setTheme("ace/theme/monokai");
        editor.getSession().setMode("ace/mode/markdown");
        editor.getSession().on('change', syncEditorToBody);
        $('#body').change(syncBodyToEditor);
        $.cookie.json = true;
        if ($.cookie('use-ace')) {
          useACE(true);
        } else {
          useACE(false);
        }
      }
      syncBodyToEditor();
      $('#editor_toggle_value').change(function() {
        useACE($('#editor_toggle_value')[0].checked);
      });
    }
  });
})();
<|endoftext|>


<commit_before>function Compass(context, x, y, n) {
  this.draw = function (dx, dy, r) {
    var r = (r || 1);
    context.beginPath();
    context.arc(n*(dx + x), n*(dy + y), n*r, 0, 2*Math.PI);
    context.stroke();
  };
}
<commit_msg>colors - fixes #1<commit_after>function Compass(context, x, y, n) {
  this.options = {
    color: 'black',
    fill: 'transparent'
  };

  this.color = function (color) {
    this.options.color = color;
    return this;
  };

  this.fill = function (color) {
    this.options.fill = color;
    return this;
  };

  this.draw = function (dx, dy, r) {
    var r = (r || 1);
    context.strokeStyle = this.options.color;
    context.fillStyle = this.options.fill;
    context.beginPath();
    context.arc(n*(dx + x), n*(dy + y), n*r, 0, 2*Math.PI);
    context.fill();
    context.stroke();
  };
}
<|endoftext|>


<commit_before>"use strict";
// compile.js compiles objects and expressions from source by performing
// all the necessary steps (i.e. scan, parse, check, rename, make).

const immutable = require("../src/immutable2.js");
const List = immutable.List;

const scan = require("./scan.js");
const Scanner = scan.Scanner;

const parse = require("./parse.js");
const parseDecl = parse.parseDecl;
const parseExpr = parse.parseExpr;

const check = require("./check.js");
const checkDecl = check.checkDecl;
const checkExpr = check.checkExpr;

const rename = require("./rename.js");
const renameDecl = rename.renameDecl;
const renameExpr = rename.renameExpr;

const make = require("./make.js");
const makeObject = make.makeObject;
const makeExpr = make.makeExpr;

// Compiles an object from its source lines.
function compileObject(pathname, lines) {
  const name = nameFromPath(pathFromPathname(pathname));
  const objLines = fullLines(lines).filter(function(line) {
    return line.startsWith("$");
  });
  var decls = [];
  for (var i = 0; i < objLines.length; i++) {
    try {
      var decl = parseDecl(new Scanner(objLines[i]));
      checkDecl(decl);
      renameDecl(decl, name);
      decls.push(decl);
    } catch (err) {
      err.pathname = pathname;
      err.line = objLines[i];
      throw err;
    }
  }
  return makeObject(decls);
}

// Compiles an expression from a source string (e.g. '2 + 2').
function compileExpr(pathname, line) {
  const name = nameFromPath(pathFromPathname(pathname));
  var expr = parseExpr(new Scanner(line));
  checkExpr(expr, {});
  renameExpr(expr, name);
  return makeExpr(expr, {});
}

// Returns a new array where the lines that were separated
// by linebreaks are concatenated.
function fullLines(lines) {
  const full = [];
  var prefix = "";
  for (var i = 0; i < lines.length; i++) {
    const line = lines[i];
    if (line.endsWith("\\\n")) {
      prefix += line.slice(0, -2);
    } else {
      full.push(prefix + line);
      prefix = "";
    }
  }
  return full;
}

// Returns the path to a class from its pathname
// e.g. pathFromPathname("~/abc/def/") is List(["abc", "def"]).
function pathFromPathname(pathname) {
  return List(pathname.match(/[a-z][a-z0-9_]*/g));
}

// Returns the name of a class from its path.
// e.g. nameFromPath(List(["abc", "def"])) is "AbcDef"
function nameFromPath(path) {
  return path
    .map(function(s) {
      return s.charAt(0).toUpperCase() + s.slice(1);
    })
    .join("");
}

exports.compileObject = compileObject;
exports.compileExpr = compileExpr;
<commit_msg>forgot a tilde in compile.js<commit_after>"use strict";
// compile.js compiles objects and expressions from source by performing
// all the necessary steps (i.e. scan, parse, check, rename, make).

const immutable = require("../src/immutable2.js");
const List = immutable.List;

const scan = require("./scan.js");
const Scanner = scan.Scanner;

const parse = require("./parse.js");
const parseDecl = parse.parseDecl;
const parseExpr = parse.parseExpr;

const check = require("./check.js");
const checkDecl = check.checkDecl;
const checkExpr = check.checkExpr;

const rename = require("./rename.js");
const renameDecl = rename.renameDecl;
const renameExpr = rename.renameExpr;

const make = require("./make.js");
const makeObject = make.makeObject;
const makeExpr = make.makeExpr;

// Compiles an object from its source lines.
function compileObject(pathname, lines) {
  const name = nameFromPath(pathFromPathname(pathname));
  const objLines = fullLines(lines).filter(function(line) {
    return line.startsWith("$");
  });
  var decls = [];
  for (var i = 0; i < objLines.length; i++) {
    try {
      var decl = parseDecl(new Scanner(objLines[i]));
      checkDecl(decl);
      renameDecl(decl, name);
      decls.push(decl);
    } catch (err) {
      err.pathname = pathname;
      err.line = objLines[i];
      throw err;
    }
  }
  return makeObject(decls);
}

// Compiles an expression from a source string (e.g. '2 + 2').
function compileExpr(pathname, line) {
  const name = nameFromPath(pathFromPathname(pathname));
  var expr = parseExpr(new Scanner(line));
  checkExpr(expr, {});
  renameExpr(expr, name);
  return makeExpr(expr, {});
}

// Returns a new array where the lines that were separated
// by linebreaks are concatenated.
function fullLines(lines) {
  const full = [];
  var prefix = "";
  for (var i = 0; i < lines.length; i++) {
    const line = lines[i];
    if (line.endsWith("\\\n")) {
      prefix += line.slice(0, -2);
    } else {
      full.push(prefix + line);
      prefix = "";
    }
  }
  return full;
}

// Returns the path to a class from its pathname
// e.g. pathFromPathname("/abc/def/") is List(["abc", "def"]).
function pathFromPathname(pathname) {
  return List(pathname.match(/[a-z][a-z0-9_]*/g));
}

// Returns the name of a class from its path.
// e.g. nameFromPath(List(["abc", "def"])) is "AbcDef"
function nameFromPath(path) {
  return path
    .map(function(s) {
      return s.charAt(0).toUpperCase() + s.slice(1);
    })
    .join("");
}

exports.compileObject = compileObject;
exports.compileExpr = compileExpr;
<|endoftext|>