<commit_before>/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SimpleEventPlugin
 */

'use strict';

var EventListener = require('EventListener');
var EventPropagators = require('EventPropagators');
var ReactDOMComponentTree = require('ReactDOMComponentTree');
var SyntheticAnimationEvent = require('SyntheticAnimationEvent');
var SyntheticClipboardEvent = require('SyntheticClipboardEvent');
var SyntheticEvent = require('SyntheticEvent');
var SyntheticFocusEvent = require('SyntheticFocusEvent');
var SyntheticKeyboardEvent = require('SyntheticKeyboardEvent');
var SyntheticMouseEvent = require('SyntheticMouseEvent');
var SyntheticDragEvent = require('SyntheticDragEvent');
var SyntheticTouchEvent = require('SyntheticTouchEvent');
var SyntheticTransitionEvent = require('SyntheticTransitionEvent');
var SyntheticUIEvent = require('SyntheticUIEvent');
var SyntheticWheelEvent = require('SyntheticWheelEvent');

var emptyFunction = require('emptyFunction');
var getEventCharCode = require('getEventCharCode');
var invariant = require('invariant');

var eventTypes = {
  abort: {
    phasedRegistrationNames: {
      bubbled: 'onAbort',
      captured: 'onAbortCapture',
    },
  },
  animationEnd: {
    phasedRegistrationNames: {
      bubbled: 'onAnimationEnd',
      captured: 'onAnimationEndCapture',
    },
  },
  animationIteration: {
    phasedRegistrationNames: {
      bubbled: 'onAnimationIteration',
      captured: 'onAnimationIterationCapture',
    },
  },
  animationStart: {
    phasedRegistrationNames: {
      bubbled: 'onAnimationStart',
      captured: 'onAnimationStartCapture',
    },
  },
  blur: {
    phasedRegistrationNames: {
      bubbled: 'onBlur',
      captured: 'onBlurCapture',
    },
  },
  canPlay: {
    phasedRegistrationNames: {
      bubbled: 'onCanPlay',
      captured: 'onCanPlayCapture',
    },
  },
  canPlayThrough: {
    phasedRegistrationNames: {
      bubbled: 'onCanPlayThrough',
      captured: 'onCanPlayThroughCapture',
    },
  },
  click: {
    phasedRegistrationNames: {
      bubbled: 'onClick',
      captured: 'onClickCapture',
    },
  },
  contextMenu: {
    phasedRegistrationNames: {
      bubbled: 'onContextMenu',
      captured: 'onContextMenuCapture',
    },
  },
  copy: {
    phasedRegistrationNames: {
      bubbled: 'onCopy',
      captured: 'onCopyCapture',
    },
  },
  cut: {
    phasedRegistrationNames: {
      bubbled: 'onCut',
      captured: 'onCutCapture',
    },
  },
  doubleClick: {
    phasedRegistrationNames: {
      bubbled: 'onDoubleClick',
      captured: 'onDoubleClickCapture',
    },
  },
  drag: {
    phasedRegistrationNames: {
      bubbled: 'onDrag',
      captured: 'onDragCapture',
    },
  },
  dragEnd: {
    phasedRegistrationNames: {
      bubbled: 'onDragEnd',
      captured: 'onDragEndCapture',
    },
  },
  dragEnter: {
    phasedRegistrationNames: {
      bubbled: 'onDragEnter',
      captured: 'onDragEnterCapture',
    },
  },
  dragExit: {
    phasedRegistrationNames: {
      bubbled: 'onDragExit',
      captured: 'onDragExitCapture',
    },
  },
  dragLeave: {
    phasedRegistrationNames: {
      bubbled: 'onDragLeave',
      captured: 'onDragLeaveCapture',
    },
  },
  dragOver: {
    phasedRegistrationNames: {
      bubbled: 'onDragOver',
      captured: 'onDragOverCapture',
    },
  },
  dragStart: {
    phasedRegistrationNames: {
      bubbled: 'onDragStart',
      captured: 'onDragStartCapture',
    },
  },
  drop: {
    phasedRegistrationNames: {
      bubbled: 'onDrop',
      captured: 'onDropCapture',
    },
  },
  durationChange: {
    phasedRegistrationNames: {
      bubbled: 'onDurationChange',
      captured: 'onDurationChangeCapture',
    },
  },
  emptied: {
    phasedRegistrationNames: {
      bubbled: 'onEmptied',
      captured: 'onEmptiedCapture',
    },
  },
  encrypted: {
    phasedRegistrationNames: {
      bubbled: 'onEncrypted',
      captured: 'onEncryptedCapture',
    },
  },
  ended: {
    phasedRegistrationNames: {
      bubbled: 'onEnded',
      captured: 'onEndedCapture',
    },
  },
  error: {
    phasedRegistrationNames: {
      bubbled: 'onError',
      captured: 'onErrorCapture',
    },
  },
  focus: {
    phasedRegistrationNames: {
      bubbled: 'onFocus',
      captured: 'onFocusCapture',
    },
  },
  input: {
    phasedRegistrationNames: {
      bubbled: 'onInput',
      captured: 'onInputCapture',
    },
  },
  invalid: {
    phasedRegistrationNames: {
      bubbled: 'onInvalid',
      captured: 'onInvalidCapture',
    },
  },
  keyDown: {
    phasedRegistrationNames: {
      bubbled: 'onKeyDown',
      captured: 'onKeyDownCapture',
    },
  },
  keyPress: {
    phasedRegistrationNames: {
      bubbled: 'onKeyPress',
      captured: 'onKeyPressCapture',
    },
  },
  keyUp: {
    phasedRegistrationNames: {
      bubbled: 'onKeyUp',
      captured: 'onKeyUpCapture',
    },
  },
  load: {
    phasedRegistrationNames: {
      bubbled: 'onLoad',
      captured: 'onLoadCapture',
    },
  },
  loadedData: {
    phasedRegistrationNames: {
      bubbled: 'onLoadedData',
      captured: 'onLoadedDataCapture',
    },
  },
  loadedMetadata: {
    phasedRegistrationNames: {
      bubbled: 'onLoadedMetadata',
      captured: 'onLoadedMetadataCapture',
    },
  },
  loadStart: {
    phasedRegistrationNames: {
      bubbled: 'onLoadStart',
      captured: 'onLoadStartCapture',
    },
  },
  // Note: We do not allow listening to mouseOver events. Instead, use the
  // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`.
  mouseDown: {
    phasedRegistrationNames: {
      bubbled: 'onMouseDown',
      captured: 'onMouseDownCapture',
    },
  },
  mouseMove: {
    phasedRegistrationNames: {
      bubbled: 'onMouseMove',
      captured: 'onMouseMoveCapture',
    },
  },
  mouseOut: {
    phasedRegistrationNames: {
      bubbled: 'onMouseOut',
      captured: 'onMouseOutCapture',
    },
  },
  mouseOver: {
    phasedRegistrationNames: {
      bubbled: 'onMouseOver',
      captured: 'onMouseOverCapture',
    },
  },
  mouseUp: {
    phasedRegistrationNames: {
      bubbled: 'onMouseUp',
      captured: 'onMouseUpCapture',
    },
  },
  paste: {
    phasedRegistrationNames: {
      bubbled: 'onPaste',
      captured: 'onPasteCapture',
    },
  },
  pause: {
    phasedRegistrationNames: {
      bubbled: 'onPause',
      captured: 'onPauseCapture',
    },
  },
  play: {
    phasedRegistrationNames: {
      bubbled: 'onPlay',
      captured: 'onPlayCapture',
    },
  },
  playing: {
    phasedRegistrationNames: {
      bubbled: 'onPlaying',
      captured: 'onPlayingCapture',
    },
  },
  progress: {
    phasedRegistrationNames: {
      bubbled: 'onProgress',
      captured: 'onProgressCapture',
    },
  },
  rateChange: {
    phasedRegistrationNames: {
      bubbled: 'onRateChange',
      captured: 'onRateChangeCapture',
    },
  },
  reset: {
    phasedRegistrationNames: {
      bubbled: 'onReset',
      captured: 'onResetCapture',
    },
  },
  scroll: {
    phasedRegistrationNames: {
      bubbled: 'onScroll',
      captured: 'onScrollCapture',
    },
  },
  seeked: {
    phasedRegistrationNames: {
      bubbled: 'onSeeked',
      captured: 'onSeekedCapture',
    },
  },
  seeking: {
    phasedRegistrationNames: {
      bubbled: 'onSeeking',
      captured: 'onSeekingCapture',
    },
  },
  stalled: {
    phasedRegistrationNames: {
      bubbled: 'onStalled',
      captured: 'onStalledCapture',
    },
  },
  submit: {
    phasedRegistrationNames: {
      bubbled: 'onSubmit',
      captured: 'onSubmitCapture',
    },
  },
  suspend: {
    phasedRegistrationNames: {
      bubbled: 'onSuspend',
      captured: 'onSuspendCapture',
    },
  },
  timeUpdate: {
    phasedRegistrationNames: {
      bubbled: 'onTimeUpdate',
      captured: 'onTimeUpdateCapture',
    },
  },
  touchCancel: {
    phasedRegistrationNames: {
      bubbled: 'onTouchCancel',
      captured: 'onTouchCancelCapture',
    },
  },
  touchEnd: {
    phasedRegistrationNames: {
      bubbled: 'onTouchEnd',
      captured: 'onTouchEndCapture',
    },
  },
  touchMove: {
    phasedRegistrationNames: {
      bubbled: 'onTouchMove',
      captured: 'onTouchMoveCapture',
    },
  },
  touchStart: {
    phasedRegistrationNames: {
      bubbled: 'onTouchStart',
      captured: 'onTouchStartCapture',
    },
  },
  transitionEnd: {
    phasedRegistrationNames: {
      bubbled: 'onTransitionEnd',
      captured: 'onTransitionEndCapture',
    },
  },
  volumeChange: {
    phasedRegistrationNames: {
      bubbled: 'onVolumeChange',
      captured: 'onVolumeChangeCapture',
    },
  },
  waiting: {
    phasedRegistrationNames: {
      bubbled: 'onWaiting',
      captured: 'onWaitingCapture',
    },
  },
  wheel: {
    phasedRegistrationNames: {
      bubbled: 'onWheel',
      captured: 'onWheelCapture',
    },
  },
};

var topLevelEventsToDispatchConfig = {
  topAbort:           eventTypes.abort,
  topAnimationEnd:    eventTypes.animationEnd,
  topAnimationIteration: eventTypes.animationIteration,
  topAnimationStart:  eventTypes.animationStart,
  topBlur:            eventTypes.blur,
  topCanPlay:         eventTypes.canPlay,
  topCanPlayThrough:  eventTypes.canPlayThrough,
  topClick:           eventTypes.click,
  topContextMenu:     eventTypes.contextMenu,
  topCopy:            eventTypes.copy,
  topCut:             eventTypes.cut,
  topDoubleClick:     eventTypes.doubleClick,
  topDrag:            eventTypes.drag,
  topDragEnd:         eventTypes.dragEnd,
  topDragEnter:       eventTypes.dragEnter,
  topDragExit:        eventTypes.dragExit,
  topDragLeave:       eventTypes.dragLeave,
  topDragOver:        eventTypes.dragOver,
  topDragStart:       eventTypes.dragStart,
  topDrop:            eventTypes.drop,
  topDurationChange:  eventTypes.durationChange,
  topEmptied:         eventTypes.emptied,
  topEncrypted:       eventTypes.encrypted,
  topEnded:           eventTypes.ended,
  topError:           eventTypes.error,
  topFocus:           eventTypes.focus,
  topInput:           eventTypes.input,
  topInvalid:         eventTypes.invalid,
  topKeyDown:         eventTypes.keyDown,
  topKeyPress:        eventTypes.keyPress,
  topKeyUp:           eventTypes.keyUp,
  topLoad:            eventTypes.load,
  topLoadedData:      eventTypes.loadedData,
  topLoadedMetadata:  eventTypes.loadedMetadata,
  topLoadStart:       eventTypes.loadStart,
  topMouseDown:       eventTypes.mouseDown,
  topMouseMove:       eventTypes.mouseMove,
  topMouseOut:        eventTypes.mouseOut,
  topMouseOver:       eventTypes.mouseOver,
  topMouseUp:         eventTypes.mouseUp,
  topPaste:           eventTypes.paste,
  topPause:           eventTypes.pause,
  topPlay:            eventTypes.play,
  topPlaying:         eventTypes.playing,
  topProgress:        eventTypes.progress,
  topRateChange:      eventTypes.rateChange,
  topReset:           eventTypes.reset,
  topScroll:          eventTypes.scroll,
  topSeeked:          eventTypes.seeked,
  topSeeking:         eventTypes.seeking,
  topStalled:         eventTypes.stalled,
  topSubmit:          eventTypes.submit,
  topSuspend:         eventTypes.suspend,
  topTimeUpdate:      eventTypes.timeUpdate,
  topTouchCancel:     eventTypes.touchCancel,
  topTouchEnd:        eventTypes.touchEnd,
  topTouchMove:       eventTypes.touchMove,
  topTouchStart:      eventTypes.touchStart,
  topTransitionEnd:   eventTypes.transitionEnd,
  topVolumeChange:    eventTypes.volumeChange,
  topWaiting:         eventTypes.waiting,
  topWheel:           eventTypes.wheel,
};

for (var type in topLevelEventsToDispatchConfig) {
  topLevelEventsToDispatchConfig[type].dependencies = [type];
}

var onClickListeners = {};

function getDictionaryKey(inst) {
  // Prevents V8 performance issue:
  // https://github.com/facebook/react/pull/7232
  return '.' + inst._rootNodeID;
}

var SimpleEventPlugin = {

  eventTypes: eventTypes,

  extractEvents: function(
    topLevelType,
    targetInst,
    nativeEvent,
    nativeEventTarget
  ) {
    var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
    if (!dispatchConfig) {
      return null;
    }
    var EventConstructor;
    switch (topLevelType) {
      case 'topAbort':
      case 'topCanPlay':
      case 'topCanPlayThrough':
      case 'topDurationChange':
      case 'topEmptied':
      case 'topEncrypted':
      case 'topEnded':
      case 'topError':
      case 'topInput':
      case 'topInvalid':
      case 'topLoad':
      case 'topLoadedData':
      case 'topLoadedMetadata':
      case 'topLoadStart':
      case 'topPause':
      case 'topPlay':
      case 'topPlaying':
      case 'topProgress':
      case 'topRateChange':
      case 'topReset':
      case 'topSeeked':
      case 'topSeeking':
      case 'topStalled':
      case 'topSubmit':
      case 'topSuspend':
      case 'topTimeUpdate':
      case 'topVolumeChange':
      case 'topWaiting':
        // HTML Events
        // @see http://www.w3.org/TR/html5/index.html#events-0
        EventConstructor = SyntheticEvent;
        break;
      case 'topKeyPress':
        // Firefox creates a keypress event for function keys too. This removes
        // the unwanted keypress events. Enter is however both printable and
        // non-printable. One would expect Tab to be as well (but it isn't).
        if (getEventCharCode(nativeEvent) === 0) {
          return null;
        }
        /* falls through */
      case 'topKeyDown':
      case 'topKeyUp':
        EventConstructor = SyntheticKeyboardEvent;
        break;
      case 'topBlur':
      case 'topFocus':
        EventConstructor = SyntheticFocusEvent;
        break;
      case 'topClick':
        // Firefox creates a click event on right mouse clicks. This removes the
        // unwanted click events.
        if (nativeEvent.button === 2) {
          return null;
        }
        /* falls through */
      case 'topContextMenu':
      case 'topDoubleClick':
      case 'topMouseDown':
      case 'topMouseMove':
      case 'topMouseOut':
      case 'topMouseOver':
      case 'topMouseUp':
        EventConstructor = SyntheticMouseEvent;
        break;
      case 'topDrag':
      case 'topDragEnd':
      case 'topDragEnter':
      case 'topDragExit':
      case 'topDragLeave':
      case 'topDragOver':
      case 'topDragStart':
      case 'topDrop':
        EventConstructor = SyntheticDragEvent;
        break;
      case 'topTouchCancel':
      case 'topTouchEnd':
      case 'topTouchMove':
      case 'topTouchStart':
        EventConstructor = SyntheticTouchEvent;
        break;
      case 'topAnimationEnd':
      case 'topAnimationIteration':
      case 'topAnimationStart':
        EventConstructor = SyntheticAnimationEvent;
        break;
      case 'topTransitionEnd':
        EventConstructor = SyntheticTransitionEvent;
        break;
      case 'topScroll':
        EventConstructor = SyntheticUIEvent;
        break;
      case 'topWheel':
        EventConstructor = SyntheticWheelEvent;
        break;
      case 'topCopy':
      case 'topCut':
      case 'topPaste':
        EventConstructor = SyntheticClipboardEvent;
        break;
    }
    invariant(
      EventConstructor,
      'SimpleEventPlugin: Unhandled event type, `%s`.',
      topLevelType
    );
    var event = EventConstructor.getPooled(
      dispatchConfig,
      targetInst,
      nativeEvent,
      nativeEventTarget
    );
    EventPropagators.accumulateTwoPhaseDispatches(event);
    return event;
  },

  didPutListener: function(inst, registrationName, listener) {
    // Mobile Safari does not fire properly bubble click events on
    // non-interactive elements, which means delegated click listeners do not
    // fire. The workaround for this bug involves attaching an empty click
    // listener on the target node.
    if (registrationName === 'onClick') {
      var key = getDictionaryKey(inst);
      var node = ReactDOMComponentTree.getNodeFromInstance(inst);
      if (!onClickListeners[key]) {
        onClickListeners[key] = EventListener.listen(
          node,
          'click',
          emptyFunction
        );
      }
    }
  },

  willDeleteListener: function(inst, registrationName) {
    if (registrationName === 'onClick') {
      var key = getDictionaryKey(inst);
      onClickListeners[key].remove();
      delete onClickListeners[key];
    }
  },

};

module.exports = SimpleEventPlugin;
<commit_msg>Generate SimpleEventPlugin data structures at runtime (#7616)<commit_after>/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule SimpleEventPlugin
 */

'use strict';

var EventListener = require('EventListener');
var EventPropagators = require('EventPropagators');
var ReactDOMComponentTree = require('ReactDOMComponentTree');
var SyntheticAnimationEvent = require('SyntheticAnimationEvent');
var SyntheticClipboardEvent = require('SyntheticClipboardEvent');
var SyntheticEvent = require('SyntheticEvent');
var SyntheticFocusEvent = require('SyntheticFocusEvent');
var SyntheticKeyboardEvent = require('SyntheticKeyboardEvent');
var SyntheticMouseEvent = require('SyntheticMouseEvent');
var SyntheticDragEvent = require('SyntheticDragEvent');
var SyntheticTouchEvent = require('SyntheticTouchEvent');
var SyntheticTransitionEvent = require('SyntheticTransitionEvent');
var SyntheticUIEvent = require('SyntheticUIEvent');
var SyntheticWheelEvent = require('SyntheticWheelEvent');

var emptyFunction = require('emptyFunction');
var getEventCharCode = require('getEventCharCode');
var invariant = require('invariant');

/**
 * Turns
 * ['abort', ...]
 * into
 * eventTypes = {
 *   'abort': {
 *     phasedRegistrationNames: {
 *       bubbled: 'onAbort',
 *       captured: 'onAbortCapture',
 *     },
 *     dependencies: ['topAbort'],
 *   },
 *   ...
 * };
 * topLevelEventsToDispatchConfig = {
 *   'topAbort': { sameConfig }
 * };
 */
var eventTypes = {};
var topLevelEventsToDispatchConfig = {};
[
  'abort',
  'animationEnd',
  'animationIteration',
  'animationStart',
  'blur',
  'canPlay',
  'canPlayThrough',
  'click',
  'contextMenu',
  'copy',
  'cut',
  'doubleClick',
  'drag',
  'dragEnd',
  'dragEnter',
  'dragExit',
  'dragLeave',
  'dragOver',
  'dragStart',
  'drop',
  'durationChange',
  'emptied',
  'encrypted',
  'ended',
  'error',
  'focus',
  'input',
  'invalid',
  'keyDown',
  'keyPress',
  'keyUp',
  'load',
  'loadedData',
  'loadedMetadata',
  'loadStart',
  'mouseDown',
  'mouseMove',
  'mouseOut',
  'mouseOver',
  'mouseUp',
  'paste',
  'pause',
  'play',
  'playing',
  'progress',
  'rateChange',
  'reset',
  'scroll',
  'seeked',
  'seeking',
  'stalled',
  'submit',
  'suspend',
  'timeUpdate',
  'touchCancel',
  'touchEnd',
  'touchMove',
  'touchStart',
  'transitionEnd',
  'volumeChange',
  'waiting',
  'wheel',
].forEach(event => {
  var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
  var onEvent = 'on' + capitalizedEvent;
  var topEvent = 'top' + capitalizedEvent;

  var type = {
    phasedRegistrationNames: {
      bubbled: onEvent,
      captured: onEvent + 'Capture',
    },
    dependencies: [topEvent],
  };
  eventTypes[event] = type;
  topLevelEventsToDispatchConfig[topEvent] = type;
});

var onClickListeners = {};

function getDictionaryKey(inst) {
  // Prevents V8 performance issue:
  // https://github.com/facebook/react/pull/7232
  return '.' + inst._rootNodeID;
}

var SimpleEventPlugin = {

  eventTypes: eventTypes,

  extractEvents: function(
    topLevelType,
    targetInst,
    nativeEvent,
    nativeEventTarget
  ) {
    var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
    if (!dispatchConfig) {
      return null;
    }
    var EventConstructor;
    switch (topLevelType) {
      case 'topAbort':
      case 'topCanPlay':
      case 'topCanPlayThrough':
      case 'topDurationChange':
      case 'topEmptied':
      case 'topEncrypted':
      case 'topEnded':
      case 'topError':
      case 'topInput':
      case 'topInvalid':
      case 'topLoad':
      case 'topLoadedData':
      case 'topLoadedMetadata':
      case 'topLoadStart':
      case 'topPause':
      case 'topPlay':
      case 'topPlaying':
      case 'topProgress':
      case 'topRateChange':
      case 'topReset':
      case 'topSeeked':
      case 'topSeeking':
      case 'topStalled':
      case 'topSubmit':
      case 'topSuspend':
      case 'topTimeUpdate':
      case 'topVolumeChange':
      case 'topWaiting':
        // HTML Events
        // @see http://www.w3.org/TR/html5/index.html#events-0
        EventConstructor = SyntheticEvent;
        break;
      case 'topKeyPress':
        // Firefox creates a keypress event for function keys too. This removes
        // the unwanted keypress events. Enter is however both printable and
        // non-printable. One would expect Tab to be as well (but it isn't).
        if (getEventCharCode(nativeEvent) === 0) {
          return null;
        }
        /* falls through */
      case 'topKeyDown':
      case 'topKeyUp':
        EventConstructor = SyntheticKeyboardEvent;
        break;
      case 'topBlur':
      case 'topFocus':
        EventConstructor = SyntheticFocusEvent;
        break;
      case 'topClick':
        // Firefox creates a click event on right mouse clicks. This removes the
        // unwanted click events.
        if (nativeEvent.button === 2) {
          return null;
        }
        /* falls through */
      case 'topContextMenu':
      case 'topDoubleClick':
      case 'topMouseDown':
      case 'topMouseMove':
      case 'topMouseOut':
      case 'topMouseOver':
      case 'topMouseUp':
        EventConstructor = SyntheticMouseEvent;
        break;
      case 'topDrag':
      case 'topDragEnd':
      case 'topDragEnter':
      case 'topDragExit':
      case 'topDragLeave':
      case 'topDragOver':
      case 'topDragStart':
      case 'topDrop':
        EventConstructor = SyntheticDragEvent;
        break;
      case 'topTouchCancel':
      case 'topTouchEnd':
      case 'topTouchMove':
      case 'topTouchStart':
        EventConstructor = SyntheticTouchEvent;
        break;
      case 'topAnimationEnd':
      case 'topAnimationIteration':
      case 'topAnimationStart':
        EventConstructor = SyntheticAnimationEvent;
        break;
      case 'topTransitionEnd':
        EventConstructor = SyntheticTransitionEvent;
        break;
      case 'topScroll':
        EventConstructor = SyntheticUIEvent;
        break;
      case 'topWheel':
        EventConstructor = SyntheticWheelEvent;
        break;
      case 'topCopy':
      case 'topCut':
      case 'topPaste':
        EventConstructor = SyntheticClipboardEvent;
        break;
    }
    invariant(
      EventConstructor,
      'SimpleEventPlugin: Unhandled event type, `%s`.',
      topLevelType
    );
    var event = EventConstructor.getPooled(
      dispatchConfig,
      targetInst,
      nativeEvent,
      nativeEventTarget
    );
    EventPropagators.accumulateTwoPhaseDispatches(event);
    return event;
  },

  didPutListener: function(inst, registrationName, listener) {
    // Mobile Safari does not fire properly bubble click events on
    // non-interactive elements, which means delegated click listeners do not
    // fire. The workaround for this bug involves attaching an empty click
    // listener on the target node.
    if (registrationName === 'onClick') {
      var key = getDictionaryKey(inst);
      var node = ReactDOMComponentTree.getNodeFromInstance(inst);
      if (!onClickListeners[key]) {
        onClickListeners[key] = EventListener.listen(
          node,
          'click',
          emptyFunction
        );
      }
    }
  },

  willDeleteListener: function(inst, registrationName) {
    if (registrationName === 'onClick') {
      var key = getDictionaryKey(inst);
      onClickListeners[key].remove();
      delete onClickListeners[key];
    }
  },

};

module.exports = SimpleEventPlugin;
<|endoftext|>


<commit_before>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

let err = false;

const majorNodeVersion = parseInt(/^(\d+)\./.exec(process.versions.node)[1]);

if (majorNodeVersion < 14 || majorNodeVersion >= 17) {
	console.error('\033[1;31m*** Please use node.js versions >=14 and <17.\033[0;0m');
	err = true;
}

const path = require('path');
const fs = require('fs');
const cp = require('child_process');
const yarnVersion = cp.execSync('yarn -v', { encoding: 'utf8' }).trim();
const parsedYarnVersion = /^(\d+)\.(\d+)\./.exec(yarnVersion);
const majorYarnVersion = parseInt(parsedYarnVersion[1]);
const minorYarnVersion = parseInt(parsedYarnVersion[2]);

if (majorYarnVersion < 1 || minorYarnVersion < 10) {
	console.error('\033[1;31m*** Please use yarn >=1.10.1.\033[0;0m');
	err = true;
}

if (!/yarn[\w-.]*\.c?js$|yarnpkg$/.test(process.env['npm_execpath'])) {
	console.error('\033[1;31m*** Please use yarn to install dependencies.\033[0;0m');
	err = true;
}

if (process.platform === 'win32') {
	if (!hasSupportedVisualStudioVersion()) {
		console.error('\033[1;31m*** Invalid C/C++ Compiler Toolchain. Please check https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites.\033[0;0m');
		err = true;
	}
	if (!err) {
		installHeaders();
	}
}

if (err) {
	console.error('');
	process.exit(1);
}

function hasSupportedVisualStudioVersion() {
	const fs = require('fs');
	const path = require('path');
	// Translated over from
	// https://source.chromium.org/chromium/chromium/src/+/master:build/vs_toolchain.py;l=140-175
	const supportedVersions = ['2019', '2017'];

	const availableVersions = [];
	for (const version of supportedVersions) {
		let vsPath = process.env[`vs${version}_install`];
		if (vsPath && fs.existsSync(vsPath)) {
			availableVersions.push(version);
			break;
		}
		const programFiles86Path = process.env['ProgramFiles(x86)'];
		if (programFiles86Path) {
			vsPath = `${programFiles86Path}/Microsoft Visual Studio/${version}`;
			const vsTypes = ['Enterprise', 'Professional', 'Community', 'Preview', 'BuildTools'];
			if (vsTypes.some(vsType => fs.existsSync(path.join(vsPath, vsType)))) {
				availableVersions.push(version);
				break;
			}
		}
	}
	return availableVersions.length;
}

function installHeaders() {
	const yarn = 'yarn.cmd';
	const opts = {
		env: process.env,
		cwd: path.join(__dirname, 'gyp'),
		stdio: 'inherit'
	};
	const yarnResult = cp.spawnSync(yarn, ['install'], opts);
	if (yarnResult.error || yarnResult.status !== 0) {
		console.error(`Installing node-gyp failed`);
		err = true;
		return;
	}

	const node_gyp = path.join(__dirname, 'gyp', 'node_modules', '.bin', 'node-gyp.cmd');
	const result = cp.execSync(`${node_gyp} list`, { encoding: 'utf8' });
	const versions = new Set(result.split(/\n/g).filter(line => !line.startsWith('gyp info')).map(value => `"${value}"`));

	const local = getHeaderInfo(path.join(__dirname, '..', '..', '.yarnrc'));
	const remote = getHeaderInfo(path.join(__dirname, '..', '..', 'remote', '.yarnrc'));

	if (local !== undefined && !versions.has(local.target)) {
		cp.execSync(`${node_gyp} install --dist-url ${local.disturl} ${local.target}`);
	}

	if (remote !== undefined && !versions.has(remote.target)) {
		cp.execSync(`${node_gyp} install --dist-url ${remote.disturl} ${remote.target}`);
	}
}

/**
 * @param {string} rcFile
 * @returns {{ disturl: string; target: string } | undefined}
 */
function getHeaderInfo(rcFile) {
	const lines = fs.readFileSync(rcFile, 'utf8').split(/\r\n?/g);
	let disturl, target;
	for (const line of lines) {
		let match = line.match(/\s*disturl\s*(.*)$/);
		if (match !== null && match.length >= 1) {
			disturl = match[1];
		}
		match = line.match(/\s*target\s*(.*)$/);
		if (match !== null && match.length >= 1) {
			target = match[1];
		}
	}
	return disturl !== undefined && target !== undefined
		? { disturl, target }
		: undefined;
}
<commit_msg>Add some comments to the preinstall script<commit_after>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

let err = false;

const majorNodeVersion = parseInt(/^(\d+)\./.exec(process.versions.node)[1]);

if (majorNodeVersion < 14 || majorNodeVersion >= 17) {
	console.error('\033[1;31m*** Please use node.js versions >=14 and <17.\033[0;0m');
	err = true;
}

const path = require('path');
const fs = require('fs');
const cp = require('child_process');
const yarnVersion = cp.execSync('yarn -v', { encoding: 'utf8' }).trim();
const parsedYarnVersion = /^(\d+)\.(\d+)\./.exec(yarnVersion);
const majorYarnVersion = parseInt(parsedYarnVersion[1]);
const minorYarnVersion = parseInt(parsedYarnVersion[2]);

if (majorYarnVersion < 1 || minorYarnVersion < 10) {
	console.error('\033[1;31m*** Please use yarn >=1.10.1.\033[0;0m');
	err = true;
}

if (!/yarn[\w-.]*\.c?js$|yarnpkg$/.test(process.env['npm_execpath'])) {
	console.error('\033[1;31m*** Please use yarn to install dependencies.\033[0;0m');
	err = true;
}

if (process.platform === 'win32') {
	if (!hasSupportedVisualStudioVersion()) {
		console.error('\033[1;31m*** Invalid C/C++ Compiler Toolchain. Please check https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites.\033[0;0m');
		err = true;
	}
	if (!err) {
		installHeaders();
	}
}

if (err) {
	console.error('');
	process.exit(1);
}

function hasSupportedVisualStudioVersion() {
	const fs = require('fs');
	const path = require('path');
	// Translated over from
	// https://source.chromium.org/chromium/chromium/src/+/master:build/vs_toolchain.py;l=140-175
	const supportedVersions = ['2019', '2017'];

	const availableVersions = [];
	for (const version of supportedVersions) {
		let vsPath = process.env[`vs${version}_install`];
		if (vsPath && fs.existsSync(vsPath)) {
			availableVersions.push(version);
			break;
		}
		const programFiles86Path = process.env['ProgramFiles(x86)'];
		if (programFiles86Path) {
			vsPath = `${programFiles86Path}/Microsoft Visual Studio/${version}`;
			const vsTypes = ['Enterprise', 'Professional', 'Community', 'Preview', 'BuildTools'];
			if (vsTypes.some(vsType => fs.existsSync(path.join(vsPath, vsType)))) {
				availableVersions.push(version);
				break;
			}
		}
	}
	return availableVersions.length;
}

function installHeaders() {
	const yarn = 'yarn.cmd';
	const opts = {
		env: process.env,
		cwd: path.join(__dirname, 'gyp'),
		stdio: 'inherit'
	};
	const yarnResult = cp.spawnSync(yarn, ['install'], opts);
	if (yarnResult.error || yarnResult.status !== 0) {
		console.error(`Installing node-gyp failed`);
		err = true;
		return;
	}

	// The node gyp package got installed using the above yarn command using the gyp/package.json
	// file checked into our repository. So from that point it is save to construct the path
	// to that executable
	const node_gyp = path.join(__dirname, 'gyp', 'node_modules', '.bin', 'node-gyp.cmd');
	const result = cp.execSync(`${node_gyp} list`, { encoding: 'utf8' });
	const versions = new Set(result.split(/\n/g).filter(line => !line.startsWith('gyp info')).map(value => `"${value}"`));

	const local = getHeaderInfo(path.join(__dirname, '..', '..', '.yarnrc'));
	const remote = getHeaderInfo(path.join(__dirname, '..', '..', 'remote', '.yarnrc'));

	if (local !== undefined && !versions.has(local.target)) {
		// Both disturl and target come from a file checked into our repository
		cp.execSync(`${node_gyp} install --dist-url ${local.disturl} ${local.target}`);
	}

	if (remote !== undefined && !versions.has(remote.target)) {
		// Both disturl and target come from a file checked into our repository
		cp.execSync(`${node_gyp} install --dist-url ${remote.disturl} ${remote.target}`);
	}
}

/**
 * @param {string} rcFile
 * @returns {{ disturl: string; target: string } | undefined}
 */
function getHeaderInfo(rcFile) {
	const lines = fs.readFileSync(rcFile, 'utf8').split(/\r\n?/g);
	let disturl, target;
	for (const line of lines) {
		let match = line.match(/\s*disturl\s*(.*)$/);
		if (match !== null && match.length >= 1) {
			disturl = match[1];
		}
		match = line.match(/\s*target\s*(.*)$/);
		if (match !== null && match.length >= 1) {
			target = match[1];
		}
	}
	return disturl !== undefined && target !== undefined
		? { disturl, target }
		: undefined;
}
<|endoftext|>


<commit_before>import "context";

blip.scheduler = function() {

  var lookahead = 25.0, // ms
      scheduleAheadTime = 0.1, // s
      tickQueue = [];

  var tempo, // ticks per minute
      ticks; // number of ticks per cycle

  var currentTick = 0,
      nextTickTime = 0;

  var action = function(tickNum, time) {};

  var timer = 0;

  function my() {}

  function nextTick() {
    var secondsPerTick = 60 / tempo;
    nextTickTime += secondsPerTick;

    // cycle through ticks
    if (currentTick < ticks) {
      currentTick += 1;
    } else {
      currentTick = 0;
    }
  }

  function scheduleTick(tickNum, time) {
    //tickQueue.push({ tick: tickNum, time: when });
    action.call(my, tickNum, time);
  }

  function scheduler() {
    while (nextTickTime < ctx.currentTime + scheduleAheadTime) {
      scheduleTick(currentTick, nextTickTime);
      nextTick();
    }
    timer = window.setTimeout(scheduler, lookahead);
  }

  my.tempo = function(bpm) {
    if (!arguments.length) return tempo;
    tempo = bpm;
    return my;
  };
  my.ticks = function(n) {
    if (!arguments.length) return ticks;
    ticks = n;
    return my;
  };
  my.lookahead = function(ms) {
    if (!arguments.length) return lookahead;
    lookahead = ms;
    return my;
  };
  my.scheduleAheadTime = function(s) {
    if (!arguments.length) return scheduleAheadTime;
    scheduleAheadTime = s;
    return my;
  };
  my.action = function(f) {
    if (!arguments.length) return action;
    action = f;
    return my;
  };
  my.start = function() {
    nextTickTime = ctx.currentTime;
    timer = window.setTimeout(scheduler, lookahead);
  };
  my.stop = function() {
    window.clearTimeout(timer);
  };
  my.reset = function() {
    currentTick = 0;
  }

  return my;

};
<commit_msg>add attribution<commit_after>import "context";

/*
* Precise scheduling for audio events
* Based on the method described in this article by Chris Wilson:
*   http://www.html5rocks.com/en/tutorials/audio/scheduling/
*/
blip.scheduler = function() {

  var lookahead = 25.0, // ms
      scheduleAheadTime = 0.1, // s
      tickQueue = [];

  var tempo, // ticks per minute
      ticks; // number of ticks per cycle

  var currentTick = 0,
      nextTickTime = 0;

  var action = function(tickNum, time) {};

  var timer = 0;

  function my() {}

  function nextTick() {
    var secondsPerTick = 60 / tempo;
    nextTickTime += secondsPerTick;

    // cycle through ticks
    if (currentTick < ticks) {
      currentTick += 1;
    } else {
      currentTick = 0;
    }
  }

  function scheduleTick(tickNum, time) {
    //tickQueue.push({ tick: tickNum, time: when });
    action.call(my, tickNum, time);
  }

  function scheduler() {
    while (nextTickTime < ctx.currentTime + scheduleAheadTime) {
      scheduleTick(currentTick, nextTickTime);
      nextTick();
    }
    timer = window.setTimeout(scheduler, lookahead);
  }

  my.tempo = function(bpm) {
    if (!arguments.length) return tempo;
    tempo = bpm;
    return my;
  };
  my.ticks = function(n) {
    if (!arguments.length) return ticks;
    ticks = n;
    return my;
  };
  my.lookahead = function(ms) {
    if (!arguments.length) return lookahead;
    lookahead = ms;
    return my;
  };
  my.scheduleAheadTime = function(s) {
    if (!arguments.length) return scheduleAheadTime;
    scheduleAheadTime = s;
    return my;
  };
  my.action = function(f) {
    if (!arguments.length) return action;
    action = f;
    return my;
  };
  my.start = function() {
    nextTickTime = ctx.currentTime;
    timer = window.setTimeout(scheduler, lookahead);
  };
  my.stop = function() {
    window.clearTimeout(timer);
  };
  my.reset = function() {
    currentTick = 0;
  }

  return my;

};
<|endoftext|>


<commit_before>import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import device from './device';
import agreements from './agreements';
import services from './services';
import attributes from './attributes';
import configuration from './configuration';

import accountForm from './accountForm';
import deviceForm from './deviceForm';
import servicesForm from './servicesForm';

export default combineReducers({
  device,
  services,
  agreements,
  attributes,
  configuration,
  accountForm,
  deviceForm,
  servicesForm,
  routing: routerReducer
});
<commit_msg>combine pattern reducer to master reducer<commit_after>import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import device from './device';
import agreements from './agreements';
import services from './services';
import attributes from './attributes';
import configuration from './configuration';

import accountForm from './accountForm';
import deviceForm from './deviceForm';
import servicesForm from './servicesForm';
import patterns from './patterns';

export default combineReducers({
  device,
  services,
  agreements,
  attributes,
  configuration,
  accountForm,
  deviceForm,
  servicesForm,
  patterns,
  routing: routerReducer
});
<|endoftext|>


<commit_before>import {BaseError} from 'make-error'
import {CronJob} from 'cron'

import { forEach } from './utils'

const _resolveId = scheduleOrId => scheduleOrId.id || scheduleOrId

export class SchedulerError extends BaseError {}
export class ScheduleOverride extends SchedulerError {
  constructor (scheduleOrId) {
    super('Schedule ID ' + _resolveId(scheduleOrId) + ' is already added')
  }
}
export class NoSuchSchedule extends SchedulerError {
  constructor (scheduleOrId) {
    super('No schedule found for ID ' + _resolveId(scheduleOrId))
  }
}
export class ScheduleNotEnabled extends SchedulerError {
  constructor (scheduleOrId) {
    super('Schedule ' + _resolveId(scheduleOrId)) + ' is not enabled'
  }
}
export class ScheduleAlreadyEnabled extends SchedulerError {
  constructor (scheduleOrId) {
    super('Schedule ' + _resolveId(scheduleOrId) + ' is already enabled')
  }
}
export class ScheduleJobNotFound extends SchedulerError {
  constructor (jobId, scheduleId) {
    super('Job ' + jobId + ' not found for Schedule ' + scheduleId)
  }
}

export default class Scheduler {
  constructor (xo) {
    this.xo = xo
    this._scheduleTable = undefined

    this._runningSchedules = {}
  }

  async _loadSchedules () {
    this._schedules = {}
    const schedules = await this.xo.getAllSchedules()
    this._scheduleTable = {}
    this._cronJobs = {}
    forEach(schedules, schedule => {
      this._add(schedule)
    })
  }

  add (schedule) {
    if (this.exists(schedule)) {
      throw new ScheduleOverride(schedule)
    }
    this._add(schedule)
  }

  _add (schedule) {
    const id = _resolveId(schedule)
    this._schedules[id] = schedule
    this._scheduleTable[id] = false
    if (schedule.enabled) {
      this._enable(schedule)
    }
  }

  remove (id) {
    try {
      this._disable(id)
    } catch (exc) {
      if (!exc instanceof SchedulerError) {
        throw exc
      }
    } finally {
      delete this._schedules[id]
      delete this._scheduleTable[id]
    }
  }

  exists (scheduleOrId) {
    const id_ = _resolveId(scheduleOrId)
    return id_ in this._schedules
  }

  async get (id) {
    if (!this.exists(id)) {
      throw new NoSuchSchedule(id)
    }
    return this._schedules[id]
  }

  async _get (id) {
    const schedule = await this.xo.getSchedule(id)
    if (!schedule) {
      throw new NoSuchSchedule(id)
    }
    return schedule
  }

  async update (schedule) {
    if (!this.exists(schedule)) {
      throw new NoSuchSchedule(schedule)
    }
    const enabled = this.isEnabled(schedule)
    if (enabled) {
      await this._disable(schedule)
    }
    this._add(schedule)
  }

  isEnabled (scheduleOrId) {
    return this._scheduleTable[_resolveId(scheduleOrId)]
  }

  _enable (schedule) {
    const running = this._runningSchedules

    const { id } = schedule
    const jobId = schedule.job

    const cronJob = new CronJob(schedule.cron, async () => {
      if (running[id]) {
        return // Simply ignore.
      }

      try {
        running[id] = true
        await this.runJobSequence([ jobId ])
      } catch (_) {
        // FIXME What do we do ?
      } finally {
        delete running[id]
      }
    })
    this._cronJobs[id] = cronJob
    cronJob.start()
    this._scheduleTable[id] = true
  }

  _disable (scheduleOrId) {
    if (!this.exists(scheduleOrId)) {
      throw new NoSuchSchedule(scheduleOrId)
    }
    if (!this.isEnabled(scheduleOrId)) {
      throw new ScheduleNotEnabled(scheduleOrId)
    }
    const id = _resolveId(scheduleOrId)
    this._cronJobs[id].stop()
    delete this._cronJobs[id]
    this._scheduleTable[id] = false
  }

  disableAll () {
    forEach(this.scheduleTable, (enabled, id) => {
      if (enabled) {
        this._disable(id)
      }
    })
  }

  get scheduleTable () {
    return this._scheduleTable
  }
}
<commit_msg>Scheduler: properly use Xo#runJobSequense() (fix vatesfr/xo-web#657).<commit_after>import {BaseError} from 'make-error'
import {CronJob} from 'cron'

import { forEach } from './utils'

const _resolveId = scheduleOrId => scheduleOrId.id || scheduleOrId

export class SchedulerError extends BaseError {}
export class ScheduleOverride extends SchedulerError {
  constructor (scheduleOrId) {
    super('Schedule ID ' + _resolveId(scheduleOrId) + ' is already added')
  }
}
export class NoSuchSchedule extends SchedulerError {
  constructor (scheduleOrId) {
    super('No schedule found for ID ' + _resolveId(scheduleOrId))
  }
}
export class ScheduleNotEnabled extends SchedulerError {
  constructor (scheduleOrId) {
    super('Schedule ' + _resolveId(scheduleOrId)) + ' is not enabled'
  }
}
export class ScheduleAlreadyEnabled extends SchedulerError {
  constructor (scheduleOrId) {
    super('Schedule ' + _resolveId(scheduleOrId) + ' is already enabled')
  }
}
export class ScheduleJobNotFound extends SchedulerError {
  constructor (jobId, scheduleId) {
    super('Job ' + jobId + ' not found for Schedule ' + scheduleId)
  }
}

export default class Scheduler {
  constructor (xo) {
    this.xo = xo
    this._scheduleTable = undefined

    this._runningSchedules = {}
  }

  async _loadSchedules () {
    this._schedules = {}
    const schedules = await this.xo.getAllSchedules()
    this._scheduleTable = {}
    this._cronJobs = {}
    forEach(schedules, schedule => {
      this._add(schedule)
    })
  }

  add (schedule) {
    if (this.exists(schedule)) {
      throw new ScheduleOverride(schedule)
    }
    this._add(schedule)
  }

  _add (schedule) {
    const id = _resolveId(schedule)
    this._schedules[id] = schedule
    this._scheduleTable[id] = false
    if (schedule.enabled) {
      this._enable(schedule)
    }
  }

  remove (id) {
    try {
      this._disable(id)
    } catch (exc) {
      if (!exc instanceof SchedulerError) {
        throw exc
      }
    } finally {
      delete this._schedules[id]
      delete this._scheduleTable[id]
    }
  }

  exists (scheduleOrId) {
    const id_ = _resolveId(scheduleOrId)
    return id_ in this._schedules
  }

  async get (id) {
    if (!this.exists(id)) {
      throw new NoSuchSchedule(id)
    }
    return this._schedules[id]
  }

  async _get (id) {
    const schedule = await this.xo.getSchedule(id)
    if (!schedule) {
      throw new NoSuchSchedule(id)
    }
    return schedule
  }

  async update (schedule) {
    if (!this.exists(schedule)) {
      throw new NoSuchSchedule(schedule)
    }
    const enabled = this.isEnabled(schedule)
    if (enabled) {
      await this._disable(schedule)
    }
    this._add(schedule)
  }

  isEnabled (scheduleOrId) {
    return this._scheduleTable[_resolveId(scheduleOrId)]
  }

  _enable (schedule) {
    const running = this._runningSchedules

    const { id } = schedule
    const jobId = schedule.job

    const cronJob = new CronJob(schedule.cron, async () => {
      if (running[id]) {
        return // Simply ignore.
      }

      try {
        running[id] = true
        await this.xo.runJobSequence([ jobId ])
      } catch (error) {
        // FIXME: better error handling
        console.error(error && error.stack || error)
      } finally {
        delete running[id]
      }
    })
    this._cronJobs[id] = cronJob
    cronJob.start()
    this._scheduleTable[id] = true
  }

  _disable (scheduleOrId) {
    if (!this.exists(scheduleOrId)) {
      throw new NoSuchSchedule(scheduleOrId)
    }
    if (!this.isEnabled(scheduleOrId)) {
      throw new ScheduleNotEnabled(scheduleOrId)
    }
    const id = _resolveId(scheduleOrId)
    this._cronJobs[id].stop()
    delete this._cronJobs[id]
    this._scheduleTable[id] = false
  }

  disableAll () {
    forEach(this.scheduleTable, (enabled, id) => {
      if (enabled) {
        this._disable(id)
      }
    })
  }

  get scheduleTable () {
    return this._scheduleTable
  }
}
<|endoftext|>


<commit_before>'use strict';
import eventEditingModalData from './logEventModalData';
import eventEditingModalState from './editEventModal';
import seedDataAggregator from './seedDataAggregator';
import batchSelectionState from './batchSelectionState';
import batchSelectionItems from './batchSelectionItems';

export default {
  eventEditingModalData,
  eventEditingModalState,
  seedDataAggregator,
  batchSelectionState,
  batchSelectionItems
};
<commit_msg>chore (Reducer): Include searchEvents reducer<commit_after>'use strict';
import eventEditingModalData from './logEventModalData';
import eventEditingModalState from './editEventModal';
import seedDataAggregator from './seedDataAggregator';
import batchSelectionState from './batchSelectionState';
import batchSelectionItems from './batchSelectionItems';
import searchEvents from './searchEvents';

export default {
  eventEditingModalData,
  eventEditingModalState,
  seedDataAggregator,
  batchSelectionState,
  batchSelectionItems,
  searchEvents
};
<|endoftext|>


<commit_before>const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const { UnusedFilesWebpackPlugin } = require('unused-files-webpack-plugin')
const StyleLintPlugin = require('stylelint-webpack-plugin')

const logger = require('./lib/logger')
const project = require('../project.config')

const inProject = path.resolve.bind(path, project.basePath)
const inProjectSrc = (file) => inProject(project.srcDir, file)

const __DEV__ = project.env === 'development'
const __TEST__ = project.env === 'test'
const __PROD__ = project.env === 'production'

const config = {
  entry: {
    app: [
      inProjectSrc(project.main)
    ]
  },

  devtool: project.sourcemaps
    ? __PROD__ ? 'source-map' : 'cheap-module-eval-source-map'
    : false,

  output: {
    path: inProject(project.outDir),
    filename: __DEV__ ? 'scripts/[name].js' : 'scripts/[name].[chunkhash].js',
    chunkFilename: __DEV__ ? 'scripts/modules/[name].js' : 'scripts/modules/[name].[chunkhash].js',
    publicPath: project.publicPath
  },

  resolve: {
    modules: [
      inProject(project.srcDir),
      inProject('node_modules')
    ],
    extensions: [
      '.js',
      '.jsx',
      '.json'
    ],
    alias: {
      'common': inProject(project.srcDir),

      // We’re aliasing lodash to lodash-es here. We need to make sure
      // that all the versions of lodash used here are compatible.
      // Run `npm ls lodash` and `npm ls lodash-es` to make sure.
      'lodash': 'lodash-es'
    }
  },

  externals: project.externals,

  module: {
    rules: []
  },

  plugins: [
    new webpack.DefinePlugin(Object.assign({
      'process.env': Object.entries(project.environment).reduce((env, entry) => {
        const key = entry[0]
        const value = process.env[key] || entry[1] || ''
        env[key] = JSON.stringify(value)
        return env
      }, {
        NODE_ENV: JSON.stringify(project.env)
      }),

      __DEV__,
      __TEST__,
      __PROD__
    }, project.globals)),

    new UnusedFilesWebpackPlugin({
      pattern: `${project.srcDir}/**/*.*`,
      globOptions: {
        ignore: [
          '**/__test__/**',
          '**/__mocks__/**'
        ]
      }
    })
  ]
}

// preact & preact-compat
// ------------------------------------
if (project.usePreact) {
  logger.info('Compiling with preact')

  config.resolve.alias = {
    ...config.resolve.alias,

    'react': 'preact-compat',
    'react-dom': 'preact-compat'
  }
} else {
  logger.info('Compiling with react')
}

// JavaScript
// ------------------------------------
if (__DEV__) {
  config.module.rules.push({
    test: /\.(js|jsx)$/,
    include: inProject(project.srcDir),
    loader: 'eslint-loader',
    enforce: 'pre'
  })
}

config.module.rules.push({
  test: /\.(js|jsx)$/,
  include: inProject(project.srcDir),
  use: [
    {
      loader: 'babel-loader',
      query: {
        cacheDirectory: true
      }
    }
  ]
})

// Styles
// ------------------------------------
const cssMinimizeOptions = {
  autoprefixer: {
    add: true,
    remove: true,
    browsers: ['last 2 versions']
  },
  discardComments: {
    removeAll: true
  },
  discardUnused: false,
  mergeIdents: false,
  reduceIdents: false,
  safe: true,
  sourcemap: project.sourcemaps
}

// Global styles
const globalStyles = new ExtractTextPlugin({
  filename: 'styles/global.[contenthash].css',
  allChunks: true,
  disable: !__PROD__
})

config.module.rules.push({
  test: /\.(sass|scss)$/,
  include: [
    inProjectSrc('styles')
  ],
  loader: globalStyles.extract({
    fallback: 'style-loader',
    use: [
      {
        loader: 'css-loader',
        options: {
          sourceMap: project.sourcemaps,
          minimize: cssMinimizeOptions
        }
      },
      {
        loader: 'sass-loader',
        options: {
          sourceMap: project.sourcemaps,
          includePaths: [
            inProjectSrc('styles')
          ]
        }
      }
    ]
  })
})

config.plugins.push(globalStyles)

// Local Styles
const localStyles = new ExtractTextPlugin({
  filename: 'styles/[name].[contenthash].css',
  allChunks: true,
  disable: !__PROD__
})

config.module.rules.push({
  test: /\.(sass|scss)$/,
  exclude: [
    inProject('node_module'),
    inProjectSrc('styles')
  ],
  loader: localStyles.extract({
    fallback: 'style-loader',
    use: [
      {
        loader: 'css-loader',
        options: {
          modules: true,
          localIdentName: '[name]-[hash:base64:8]',
          camelCase: 'only',
          sourceMap: project.sourcemaps,
          minimize: cssMinimizeOptions
        }
      },
      {
        loader: 'sass-loader',
        options: {
          sourceMap: project.sourcemaps,
          includePaths: [
            inProjectSrc('styles')
          ]
        }
      }
    ]
  })
})

config.plugins.push(localStyles)

// Vendor Styles
config.module.rules.push({
  test: /\.css$/,
  include: [
    inProject('node_modules')
  ],
  use: [
    {
      loader: 'style-loader',
      options: {
        sourceMap: __DEV__
      }
    },
    {
      loader: 'css-loader',
      options: {
        sourceMap: __DEV__,
        minimize: cssMinimizeOptions
      }
    }
  ]
})

// Images
// ------------------------------------
config.module.rules.push({
  test: /\.(png|jpg|gif|svg)$/,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 8192,
        name: __DEV__ ? 'images/[name].[ext]' : 'images/[name].[hash].[ext]'
      }
    },
    {
      loader: 'imagemin-loader',
      options: {
        enabled: __PROD__,
        plugins: [
          {
            use: 'imagemin-pngquant'
          },
          {
            use: 'imagemin-svgo'
          }
        ]
      }
    }
  ]
})

// Fonts
// ------------------------------------
;[
  ['woff', 'application/font-woff'],
  ['woff2', 'application/font-woff2'],
  ['otf', 'font/opentype'],
  ['ttf', 'application/octet-stream'],
  ['eot', 'application/vnd.ms-fontobject']
].forEach(([ extension, mimetype ]) => {
  config.module.rules.push({
    test: new RegExp(`\\.${extension}$`),
    loader: 'url-loader',
    options: {
      name: __DEV__ ? 'fonts/[name].[ext]' : 'fonts/[name].[hash].[ext]',
      limit: 8192,
      mimetype
    }
  })
})

// HTML Template
// ------------------------------------
config.plugins.push(new HtmlWebpackPlugin({
  template: inProjectSrc('index.html'),
  inject: true,
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeRedundantAttributes: true,
    useShortDoctype: true,
    removeEmptyAttributes: true,
    removeStyleLinkTypeAttributes: true,
    keepClosingSlash: true,
    minifyJS: true,
    minifyCSS: true,
    minifyURLs: true
  }
}))

// Development Tools
// ------------------------------------
if (__DEV__) {
  config.entry.app.push(
    `webpack-hot-middleware/client.js?path=${config.output.publicPath}__webpack_hmr`
  )
  config.plugins.push(
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new StyleLintPlugin()
  )
}

// Bundle Splitting
// ------------------------------------
if (!__TEST__) {
  const bundles = ['manifest']

  if (project.vendors && project.vendors.length) {
    bundles.unshift('vendor')
    config.entry.vendor = project.vendors
  }

  config.plugins.push(new webpack.optimize.CommonsChunkPlugin({ names: bundles }))
  config.plugins.push(new webpack.optimize.CommonsChunkPlugin({
    name: 'app',
    async: 'common',
    minChunks: 2
  }))
}

// Production Optimizations
// ------------------------------------
if (__PROD__) {
  config.plugins.push(
    new webpack.optimize.ModuleConcatenationPlugin(),

    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false
    }),

    new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /fr/),

    new webpack.optimize.UglifyJsPlugin({
      sourceMap: !!config.devtool,
      comments: false,
      compress: {
        warnings: false,
        screw_ie8: true,
        conditionals: true,
        unused: true,
        comparisons: true,
        sequences: true,
        dead_code: true,
        evaluate: true,
        if_return: true,
        join_vars: true
      },
      mangle: {
        screw_ie8: true
      },
      output: {
        comments: false,
        screw_ie8: true
      }
    }),

    new BundleAnalyzerPlugin({
      analyzerMode: 'static',
      openAnalyzer: false,
      reportFilename: path.join('..', project.reportDir, 'bundles.html'),
      defaultSizes: 'gzip'
    })
  )
}

module.exports = config
<commit_msg>Remove resolve.modules from webpack config<commit_after>const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const { UnusedFilesWebpackPlugin } = require('unused-files-webpack-plugin')
const StyleLintPlugin = require('stylelint-webpack-plugin')

const logger = require('./lib/logger')
const project = require('../project.config')

const inProject = path.resolve.bind(path, project.basePath)
const inProjectSrc = (file) => inProject(project.srcDir, file)

const __DEV__ = project.env === 'development'
const __TEST__ = project.env === 'test'
const __PROD__ = project.env === 'production'

const config = {
  entry: {
    app: [
      inProjectSrc(project.main)
    ]
  },

  devtool: project.sourcemaps
    ? __PROD__ ? 'source-map' : 'cheap-module-eval-source-map'
    : false,

  output: {
    path: inProject(project.outDir),
    filename: __DEV__ ? 'scripts/[name].js' : 'scripts/[name].[chunkhash].js',
    chunkFilename: __DEV__ ? 'scripts/modules/[name].js' : 'scripts/modules/[name].[chunkhash].js',
    publicPath: project.publicPath
  },

  resolve: {
    extensions: [
      '.js',
      '.jsx',
      '.json'
    ],
    alias: {
      'common': inProject(project.srcDir),

      // We’re aliasing lodash to lodash-es here. We need to make sure
      // that all the versions of lodash used here are compatible.
      // Run `npm ls lodash` and `npm ls lodash-es` to make sure.
      'lodash': 'lodash-es'
    }
  },

  externals: project.externals,

  module: {
    rules: []
  },

  plugins: [
    new webpack.DefinePlugin(Object.assign({
      'process.env': Object.entries(project.environment).reduce((env, entry) => {
        const key = entry[0]
        const value = process.env[key] || entry[1] || ''
        env[key] = JSON.stringify(value)
        return env
      }, {
        NODE_ENV: JSON.stringify(project.env)
      }),

      __DEV__,
      __TEST__,
      __PROD__
    }, project.globals)),

    new UnusedFilesWebpackPlugin({
      pattern: `${project.srcDir}/**/*.*`,
      globOptions: {
        ignore: [
          '**/__test__/**',
          '**/__mocks__/**'
        ]
      }
    })
  ]
}

// preact & preact-compat
// ------------------------------------
if (project.usePreact) {
  logger.info('Compiling with preact')

  config.resolve.alias = {
    ...config.resolve.alias,

    'react': 'preact-compat',
    'react-dom': 'preact-compat'
  }
} else {
  logger.info('Compiling with react')
}

// JavaScript
// ------------------------------------
if (__DEV__) {
  config.module.rules.push({
    test: /\.(js|jsx)$/,
    include: inProject(project.srcDir),
    loader: 'eslint-loader',
    enforce: 'pre'
  })
}

config.module.rules.push({
  test: /\.(js|jsx)$/,
  include: inProject(project.srcDir),
  use: [
    {
      loader: 'babel-loader',
      query: {
        cacheDirectory: true
      }
    }
  ]
})

// Styles
// ------------------------------------
const cssMinimizeOptions = {
  autoprefixer: {
    add: true,
    remove: true,
    browsers: ['last 2 versions']
  },
  discardComments: {
    removeAll: true
  },
  discardUnused: false,
  mergeIdents: false,
  reduceIdents: false,
  safe: true,
  sourcemap: project.sourcemaps
}

// Global styles
const globalStyles = new ExtractTextPlugin({
  filename: 'styles/global.[contenthash].css',
  allChunks: true,
  disable: !__PROD__
})

config.module.rules.push({
  test: /\.(sass|scss)$/,
  include: [
    inProjectSrc('styles')
  ],
  loader: globalStyles.extract({
    fallback: 'style-loader',
    use: [
      {
        loader: 'css-loader',
        options: {
          sourceMap: project.sourcemaps,
          minimize: cssMinimizeOptions
        }
      },
      {
        loader: 'sass-loader',
        options: {
          sourceMap: project.sourcemaps,
          includePaths: [
            inProjectSrc('styles')
          ]
        }
      }
    ]
  })
})

config.plugins.push(globalStyles)

// Local Styles
const localStyles = new ExtractTextPlugin({
  filename: 'styles/[name].[contenthash].css',
  allChunks: true,
  disable: !__PROD__
})

config.module.rules.push({
  test: /\.(sass|scss)$/,
  exclude: [
    inProject('node_module'),
    inProjectSrc('styles')
  ],
  loader: localStyles.extract({
    fallback: 'style-loader',
    use: [
      {
        loader: 'css-loader',
        options: {
          modules: true,
          localIdentName: '[name]-[hash:base64:8]',
          camelCase: 'only',
          sourceMap: project.sourcemaps,
          minimize: cssMinimizeOptions
        }
      },
      {
        loader: 'sass-loader',
        options: {
          sourceMap: project.sourcemaps,
          includePaths: [
            inProjectSrc('styles')
          ]
        }
      }
    ]
  })
})

config.plugins.push(localStyles)

// Vendor Styles
config.module.rules.push({
  test: /\.css$/,
  include: [
    inProject('node_modules')
  ],
  use: [
    {
      loader: 'style-loader',
      options: {
        sourceMap: __DEV__
      }
    },
    {
      loader: 'css-loader',
      options: {
        sourceMap: __DEV__,
        minimize: cssMinimizeOptions
      }
    }
  ]
})

// Images
// ------------------------------------
config.module.rules.push({
  test: /\.(png|jpg|gif|svg)$/,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 8192,
        name: __DEV__ ? 'images/[name].[ext]' : 'images/[name].[hash].[ext]'
      }
    },
    {
      loader: 'imagemin-loader',
      options: {
        enabled: __PROD__,
        plugins: [
          {
            use: 'imagemin-pngquant'
          },
          {
            use: 'imagemin-svgo'
          }
        ]
      }
    }
  ]
})

// Fonts
// ------------------------------------
;[
  ['woff', 'application/font-woff'],
  ['woff2', 'application/font-woff2'],
  ['otf', 'font/opentype'],
  ['ttf', 'application/octet-stream'],
  ['eot', 'application/vnd.ms-fontobject']
].forEach(([ extension, mimetype ]) => {
  config.module.rules.push({
    test: new RegExp(`\\.${extension}$`),
    loader: 'url-loader',
    options: {
      name: __DEV__ ? 'fonts/[name].[ext]' : 'fonts/[name].[hash].[ext]',
      limit: 8192,
      mimetype
    }
  })
})

// HTML Template
// ------------------------------------
config.plugins.push(new HtmlWebpackPlugin({
  template: inProjectSrc('index.html'),
  inject: true,
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeRedundantAttributes: true,
    useShortDoctype: true,
    removeEmptyAttributes: true,
    removeStyleLinkTypeAttributes: true,
    keepClosingSlash: true,
    minifyJS: true,
    minifyCSS: true,
    minifyURLs: true
  }
}))

// Development Tools
// ------------------------------------
if (__DEV__) {
  config.entry.app.push(
    `webpack-hot-middleware/client.js?path=${config.output.publicPath}__webpack_hmr`
  )
  config.plugins.push(
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new StyleLintPlugin()
  )
}

// Bundle Splitting
// ------------------------------------
if (!__TEST__) {
  const bundles = ['manifest']

  if (project.vendors && project.vendors.length) {
    bundles.unshift('vendor')
    config.entry.vendor = project.vendors
  }

  config.plugins.push(new webpack.optimize.CommonsChunkPlugin({ names: bundles }))
  config.plugins.push(new webpack.optimize.CommonsChunkPlugin({
    name: 'app',
    async: 'common',
    minChunks: 2
  }))
}

// Production Optimizations
// ------------------------------------
if (__PROD__) {
  config.plugins.push(
    new webpack.optimize.ModuleConcatenationPlugin(),

    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false
    }),

    new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /fr/),

    new webpack.optimize.UglifyJsPlugin({
      sourceMap: !!config.devtool,
      comments: false,
      compress: {
        warnings: false,
        screw_ie8: true,
        conditionals: true,
        unused: true,
        comparisons: true,
        sequences: true,
        dead_code: true,
        evaluate: true,
        if_return: true,
        join_vars: true
      },
      mangle: {
        screw_ie8: true
      },
      output: {
        comments: false,
        screw_ie8: true
      }
    }),

    new BundleAnalyzerPlugin({
      analyzerMode: 'static',
      openAnalyzer: false,
      reportFilename: path.join('..', project.reportDir, 'bundles.html'),
      defaultSizes: 'gzip'
    })
  )
}

module.exports = config
<|endoftext|>


<commit_before>/**
 * @author Ryan Johnson <http://syntacticx.com/>
 * @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
 * @package LivePipe UI
 * @license MIT
 * @url http://livepipe.net/control/scrollbar
 * @require prototype.js, slider.js, livepipe.js
 */

if(typeof(Prototype) == "undefined")
    throw "Control.ScrollBar requires Prototype to be loaded.";
if(typeof(Control.Slider) == "undefined")
    throw "Control.ScrollBar requires Control.Slider to be loaded.";
if(typeof(Object.Event) == "undefined")
    throw "Control.ScrollBar requires Object.Event to be loaded.";

Control.ScrollBar = Class.create({
    initialize: function(container,track,options){
        Control.ScrollBar.instances.push(this);
        this.enabled = false;
        this.notificationTimeout = false;
        this.container = $(container);
        this.boundMouseWheelEvent = this.onMouseWheel.bindAsEventListener(this);
        this.boundResizeObserver = this.onWindowResize.bind(this);
        this.track = $(track);
        this.handle = this.track.firstDescendant();
        this.options = Object.extend({
            active_class_name: 'scrolling',
            apply_active_class_name_to: this.container,
            notification_timeout_length: 125,
            handle_minimum_length: 25,
            scroll_to_smoothing: 0.01,
            scroll_to_steps: 15,
            scroll_to_precision: 100,
            proportional: true,
            custom_event: null,
            custom_event_handler: null,
            scroll_axis: 'vertical',
            slider_options: {}
        },options || {});
        this.slider = new Control.Slider(this.handle,this.track,Object.extend({
            axis: this.options.scroll_axis,
            onSlide: this.onChange.bind(this),
            onChange: this.onChange.bind(this)
        },this.options.slider_options));
        this.recalculateLayout();
        Event.observe(window,'resize',this.boundResizeObserver);
        if (this.options.custom_event) {
            if (Object.isFunction(this.options.custom_event_handler)) {
                this.container.observe(this.options.custom_event, this.options.custom_event_handler);
            } else {
                this.container.observe(this.options.custom_event, this.boundResizeObserver);
            }
        }
        this.handle.observe('mousedown',function(){
            if(this.auto_sliding_executer)
                this.auto_sliding_executer.stop();
        }.bind(this));
    },
    destroy: function(){
        Event.stopObserving(window,'resize',this.boundResizeObserver);
        if(this.options.active_class_name)
            $(this.options.apply_active_class_name_to).removeClassName(this.options.active_class_name);
        if (this.options.custom_event) {
            this.container.stopObserving(this.options.custom_event);
        }
    },
    scrollLength: function(){
        return (this.options.scroll_axis == 'vertical') ? this.container.scrollHeight : this.container.scrollWidth;
    },
    offsetLength: function(){
        return (this.options.scroll_axis == 'vertical') ? this.container.offsetHeight : this.container.offsetWidth;
    },
    enable: function(){
        this.enabled = true;
        this.container.observe('mouse:wheel',this.boundMouseWheelEvent);
        this.slider.setEnabled();
        this.track.show();
        if(this.options.active_class_name)
            $(this.options.apply_active_class_name_to).addClassName(this.options.active_class_name);
        this.notify('enabled');
    },
    disable: function(){
        this.enabled = false;
        this.container.stopObserving('mouse:wheel',this.boundMouseWheelEvent);
        this.slider.setDisabled();
        this.track.hide();
        if(this.options.active_class_name)
            $(this.options.apply_active_class_name_to).removeClassName(this.options.active_class_name);
        this.notify('disabled');
        this.reset();
    },
    reset: function(){
        this.slider.setValue(0);
    },
    recalculateLayout: function(){
        if(this.scrollLength() <= this.offsetLength())
            this.disable();
        else{
            this.enable();
            this.slider.trackLength = this.slider.maximumOffset() - this.slider.minimumOffset();
            if(this.options.proportional){
                this.slider.handleLength = Math.max(this.offsetLength() * (this.offsetLength() / this.scrollLength()),this.options.handle_minimum_length);
                if (this.options.scroll_axis == 'vertical')
                    this.handle.style.height = this.slider.handleLength + 'px';
                else
                    this.handle.style.width = this.slider.handleLength + 'px';
            }
            this.scrollBy(0);
        }
    },
    onWindowResize: function(){
        this.recalculateLayout();
        this.scrollBy(0);
    },
    onMouseWheel: function(event){
        if(this.auto_sliding_executer)
            this.auto_sliding_executer.stop();
        this.slider.setValueBy(-(event.memo.delta / 20)); //put in math to account for the window height
        event.stop();
        return false;
    },
    onChange: function(value){
        var scroll_pos = Math.round(value / this.slider.maximum * (this.scrollLength() - this.offsetLength()));
        if (this.options.scroll_axis == 'vertical')
            this.container.scrollTop = scroll_pos;
        else
            this.container.scrollLeft = scroll_pos;
        if(this.notification_timeout)
            window.clearTimeout(this.notificationTimeout);
        this.notificationTimeout = window.setTimeout(function(){
            this.notify('change',value);
        }.bind(this),this.options.notification_timeout_length);
    },
    getCurrentMaximumDelta: function(){
        return this.slider.maximum * (this.scrollLength() - this.offsetLength());
    },
    getContainerOffset: function(element) {
        var offset = element.positionedOffset();
        while (element.getOffsetParent() != this.container)
        {
            element         = element.getOffsetParent();
            offset[0]      += element.positionedOffset()[0];
            offset[1]      += element.positionedOffset()[1];
            offset.top     += element.positionedOffset().top;
            offset.left    += element.positionedOffset().left;
        }
        return offset;
    },
    getDeltaToElement: function(element){

        if (this.options.scroll_axis == 'vertical')
            return this.slider.maximum * ((this.getContainerOffset(element).top + (element.getHeight() / 2)) - (this.container.getHeight() / 2));
        else
            return this.slider.maximum * ((this.getContainerOffset(element).left + (element.getWidth() / 2)) - (this.container.getWidth() / 2));
    },
    scrollTo: function(y,animate){
        var precision = this.options.scroll_to_precision,
            current_maximum_delta = this.getCurrentMaximumDelta();
        if (precision == 'auto')
            precision = Math.pow(10, Math.ceil(Math.log(current_maximum_delta)/Math.log(10)));
        if(y == 'top')
            y = 0;
        else if(y == 'bottom')
            y = current_maximum_delta;
        else if(typeof(y) != "number")
            y = this.getDeltaToElement($(y));
        if(this.enabled){
            y = Math.max(0,Math.min(y,current_maximum_delta));
            if(this.auto_sliding_executer)
                this.auto_sliding_executer.stop();
            var target_value = y / current_maximum_delta;
            var original_slider_value = this.slider.value;
            var delta = (target_value - original_slider_value) * current_maximum_delta;
            if(animate){
                this.auto_sliding_executer = new PeriodicalExecuter(function(){
                    if(Math.round(this.slider.value * precision) / precision < Math.round(target_value * precision) / precision || Math.round(this.slider.value * precision) / precision > Math.round(target_value * precision) / precision){
                        this.scrollBy(delta / this.options.scroll_to_steps);
                    }else{
                        this.auto_sliding_executer.stop();
                        this.auto_sliding_executer = null;
                        if(typeof(animate) == "function")
                            animate();
                    }
                }.bind(this),this.options.scroll_to_smoothing);
            }else
                this.scrollBy(delta);
        }else if(typeof(animate) == "function")
            animate();
    },
    scrollBy: function(y){
        if(!this.enabled)
            return false;
        this.slider.setValueBy(y / (this.getCurrentMaximumDelta() == 0 ? 1 : this.getCurrentMaximumDelta()) );
    }
});
Object.extend(Control.ScrollBar,
{
    instances: [],

    findByElementId: function(id)
    {
        return Control.ScrollBar.instances.find(function(instance)
        {
            return (instance.container.id && instance.container.id == id);
        });
    }
});
Object.Event.extend(Control.ScrollBar);
<commit_msg>Mouse wheel fixed. Was previously 20 steps always (for scrolling 100 pixels down as well as for 50-pages-content); now the wheel scrolls by a fixed number of pixels (as it usually does).<commit_after>/**
 * @author Ryan Johnson <http://syntacticx.com/>
 * @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
 * @package LivePipe UI
 * @license MIT
 * @url http://livepipe.net/control/scrollbar
 * @require prototype.js, slider.js, livepipe.js
 */

if(typeof(Prototype) == "undefined")
    throw "Control.ScrollBar requires Prototype to be loaded.";
if(typeof(Control.Slider) == "undefined")
    throw "Control.ScrollBar requires Control.Slider to be loaded.";
if(typeof(Object.Event) == "undefined")
    throw "Control.ScrollBar requires Object.Event to be loaded.";

Control.ScrollBar = Class.create({
    initialize: function(container,track,options){
        Control.ScrollBar.instances.push(this);
        this.enabled = false;
        this.notificationTimeout = false;
        this.container = $(container);
        this.boundMouseWheelEvent = this.onMouseWheel.bindAsEventListener(this);
        this.boundResizeObserver = this.onWindowResize.bind(this);
        this.track = $(track);
        this.handle = this.track.firstDescendant();
        this.options = Object.extend({
            active_class_name: 'scrolling',
            apply_active_class_name_to: this.container,
            notification_timeout_length: 125,
            handle_minimum_length: 25,
            scroll_to_smoothing: 0.01,
            scroll_to_steps: 15,
            scroll_to_precision: 100,
            proportional: true,
            custom_event: null,
            custom_event_handler: null,
            scroll_axis: 'vertical',
            slider_options: {}
        },options || {});
        this.slider = new Control.Slider(this.handle,this.track,Object.extend({
            axis: this.options.scroll_axis,
            onSlide: this.onChange.bind(this),
            onChange: this.onChange.bind(this)
        },this.options.slider_options));
        this.recalculateLayout();
        Event.observe(window,'resize',this.boundResizeObserver);
        if (this.options.custom_event) {
            if (Object.isFunction(this.options.custom_event_handler)) {
                this.container.observe(this.options.custom_event, this.options.custom_event_handler);
            } else {
                this.container.observe(this.options.custom_event, this.boundResizeObserver);
            }
        }
        this.handle.observe('mousedown',function(){
            if(this.auto_sliding_executer)
                this.auto_sliding_executer.stop();
        }.bind(this));
    },
    destroy: function(){
        Event.stopObserving(window,'resize',this.boundResizeObserver);
        if(this.options.active_class_name)
            $(this.options.apply_active_class_name_to).removeClassName(this.options.active_class_name);
        if (this.options.custom_event) {
            this.container.stopObserving(this.options.custom_event);
        }
    },
    scrollLength: function(){
        return (this.options.scroll_axis == 'vertical') ? this.container.scrollHeight : this.container.scrollWidth;
    },
    offsetLength: function(){
        return (this.options.scroll_axis == 'vertical') ? this.container.offsetHeight : this.container.offsetWidth;
    },
    enable: function(){
        this.enabled = true;
        this.container.observe('mouse:wheel',this.boundMouseWheelEvent);
        this.slider.setEnabled();
        this.track.show();
        if(this.options.active_class_name)
            $(this.options.apply_active_class_name_to).addClassName(this.options.active_class_name);
        this.notify('enabled');
    },
    disable: function(){
        this.enabled = false;
        this.container.stopObserving('mouse:wheel',this.boundMouseWheelEvent);
        this.slider.setDisabled();
        this.track.hide();
        if(this.options.active_class_name)
            $(this.options.apply_active_class_name_to).removeClassName(this.options.active_class_name);
        this.notify('disabled');
        this.reset();
    },
    reset: function(){
        this.slider.setValue(0);
    },
    recalculateLayout: function(){
        if(this.scrollLength() <= this.offsetLength())
            this.disable();
        else{
            this.enable();
            this.slider.trackLength = this.slider.maximumOffset() - this.slider.minimumOffset();
            if(this.options.proportional){
                this.slider.handleLength = Math.max(this.offsetLength() * (this.offsetLength() / this.scrollLength()),this.options.handle_minimum_length);
                if (this.options.scroll_axis == 'vertical')
                    this.handle.style.height = this.slider.handleLength + 'px';
                else
                    this.handle.style.width = this.slider.handleLength + 'px';
            }
            this.scrollBy(0);
        }
    },
    onWindowResize: function(){
        this.recalculateLayout();
        this.scrollBy(0);
    },
    onMouseWheel: function(event){
        if(this.auto_sliding_executer)
            this.auto_sliding_executer.stop();
        // Move the content by 30 pixels each wheel event
        this.slider.setValueBy(-(30 * event.memo.delta / (this.scrollLength()-this.slider.trackLength)));
        event.stop();
        return false;
    },
    onChange: function(value){
        var scroll_pos = Math.round(value / this.slider.maximum * (this.scrollLength() - this.offsetLength()));
        if (this.options.scroll_axis == 'vertical')
            this.container.scrollTop = scroll_pos;
        else
            this.container.scrollLeft = scroll_pos;
        if(this.notification_timeout)
            window.clearTimeout(this.notificationTimeout);
        this.notificationTimeout = window.setTimeout(function(){
            this.notify('change',value);
        }.bind(this),this.options.notification_timeout_length);
    },
    getCurrentMaximumDelta: function(){
        return this.slider.maximum * (this.scrollLength() - this.offsetLength());
    },
    getContainerOffset: function(element) {
        var offset = element.positionedOffset();
        while (element.getOffsetParent() != this.container)
        {
            element         = element.getOffsetParent();
            offset[0]      += element.positionedOffset()[0];
            offset[1]      += element.positionedOffset()[1];
            offset.top     += element.positionedOffset().top;
            offset.left    += element.positionedOffset().left;
        }
        return offset;
    },
    getDeltaToElement: function(element){

        if (this.options.scroll_axis == 'vertical')
            return this.slider.maximum * ((this.getContainerOffset(element).top + (element.getHeight() / 2)) - (this.container.getHeight() / 2));
        else
            return this.slider.maximum * ((this.getContainerOffset(element).left + (element.getWidth() / 2)) - (this.container.getWidth() / 2));
    },
    scrollTo: function(y,animate){
        var precision = this.options.scroll_to_precision,
            current_maximum_delta = this.getCurrentMaximumDelta();
        if (precision == 'auto')
            precision = Math.pow(10, Math.ceil(Math.log(current_maximum_delta)/Math.log(10)));
        if(y == 'top')
            y = 0;
        else if(y == 'bottom')
            y = current_maximum_delta;
        else if(typeof(y) != "number")
            y = this.getDeltaToElement($(y));
        if(this.enabled){
            y = Math.max(0,Math.min(y,current_maximum_delta));
            if(this.auto_sliding_executer)
                this.auto_sliding_executer.stop();
            var target_value = y / current_maximum_delta;
            var original_slider_value = this.slider.value;
            var delta = (target_value - original_slider_value) * current_maximum_delta;
            if(animate){
                this.auto_sliding_executer = new PeriodicalExecuter(function(){
                    if(Math.round(this.slider.value * precision) / precision < Math.round(target_value * precision) / precision || Math.round(this.slider.value * precision) / precision > Math.round(target_value * precision) / precision){
                        this.scrollBy(delta / this.options.scroll_to_steps);
                    }else{
                        this.auto_sliding_executer.stop();
                        this.auto_sliding_executer = null;
                        if(typeof(animate) == "function")
                            animate();
                    }
                }.bind(this),this.options.scroll_to_smoothing);
            }else
                this.scrollBy(delta);
        }else if(typeof(animate) == "function")
            animate();
    },
    scrollBy: function(y){
        if(!this.enabled)
            return false;
        this.slider.setValueBy(y / (this.getCurrentMaximumDelta() == 0 ? 1 : this.getCurrentMaximumDelta()) );
    }
});
Object.extend(Control.ScrollBar,
{
    instances: [],

    findByElementId: function(id)
    {
        return Control.ScrollBar.instances.find(function(instance)
        {
            return (instance.container.id && instance.container.id == id);
        });
    }
});
Object.Event.extend(Control.ScrollBar);
<|endoftext|>


<commit_before>import { combineReducers } from 'redux';

const attributes = (state = {}, action) => {
  switch (action.type) {
    case 'UPDATE_ATTRIBUTE':
      return {...state, [action.attributeName]: action.value};
    default:
      return state;
  }
};

const score = (state = '', action) => {
  return state;
}

const reducer = combineReducers({ attributes, score });

export default reducer;
<commit_msg>add getPillow function to main reducer and add scores reducer to it<commit_after>import { combineReducers } from 'redux';

import attributes from './attributes';
import scores, * as fromScores from './scores';

const sumTotal = (total, current) => total + parseInt(current, 10)

const reducer = combineReducers({ attributes, scores });

export default reducer;

export const getPillow = (state) => {
  const initialTotal = 0;
  const totalScore = Object.values(state.scores).reduce(sumTotal, initialTotal);
  return fromScores.getPillowForScore(totalScore);
};
<|endoftext|>


<commit_before>const
  path           = require( 'path' ),
  webpack        = require( 'webpack' ),
  UglifyJsPlugin = require( 'uglifyjs-webpack-plugin' ),

  config  = require( './build.config' );

/**
 * Define plugins based on environment
 *
 * @param {boolean} isDev If in development mode
 *
 * @return {Array}
 */
function getPlugins( isDev ) {
  const plugins = [];

  if ( !isDev ) {
    plugins.push( new webpack.NoEmitOnErrorsPlugin());
  }

  return plugins;
}

module.exports = ({
  includeToolkit,
  includeFabricator,
} = { includeToolkit: true, includeFabricator: true }) => {
  // Add properties: { 'dests_relative_path': 'source' }
  const entries    = {},
    libraryEntries = {};

  if ( includeToolkit ) {
    entries.toolkit = `./${config.paths.toolkit.scriptsIndex}`;

    if ( !config.devMode ) entries['toolkit.min'] = `./${config.paths.toolkit.scriptsIndex}`;

    const minificationExtension = ( !config.devMode ) ? '.min' : '';

    // Add listed standalone modules and libraries to the build
    //TODO: Automate this!
    [
      'tracking',
      'popups',
      'tooltips',
      'lazyloader',
      'toolbar',
      'filtering',
      'urls',
      'core',
    ].forEach(( moduleName ) => {
      libraryEntries[`toolkit.${moduleName}${minificationExtension}`] = `./${config.paths.toolkit.scriptModules}/${moduleName}.js`;
    });
  }

  if ( includeFabricator ) {
    entries[`${config.names.fabricator.dist}/f`] = `./${config.paths.fabricator.scriptIndex}`;
  }

  return [
    {
      entry: entries,

      output: {
        path:     path.resolve( __dirname, '..', config.paths.tmp ),
        filename: '[name].js',
      },

      // (default) devtool: 'eval',

      resolve: {
        extensions: [
          '.js',
        ],
      },

      plugins: getPlugins( config.devMode ),

      mode: config.devMode ? 'development' : 'production',

      module:  {
        rules: [
          {
            test:    /\.js$/,
            exclude: /(node_modules|\.tmp|dist)/,
            loader:  'babel-loader',
          }, {
            test:   /(\.jpg|\.png)$/,
            loader: 'url-loader?limit=10000',
          },
        ],
      },

      externals: {
        jquery: 'jQuery',
      },

      optimization: {
        minimizer: [
          new UglifyJsPlugin({
            uglifyOptions: {
              output: {
                comments: false,
              },
            },
            exclude: 'toolkit.js', // Don't minify!
          }),
        ],
      },
    },

    // Config for standalone libraries compilation
    {
      entry: libraryEntries,

      output: {
        path:     path.resolve( __dirname, '..', config.paths.tmp ),
        filename: '[name].js',
      },

      // (default) devtool: 'eval',

      resolve: {
        extensions: [
          '.js',
        ],
      },

      plugins: getPlugins( config.devMode ),

      mode: config.devMode ? 'development' : 'production',

      module:  {
        rules: [
          {
            test:    /\.js$/,
            exclude: /(node_modules|\.tmp|dist)/,
            loader:  'babel-loader',
          }, {
            test:   /(\.jpg|\.png)$/,
            loader: 'url-loader?limit=10000',
          },
        ],
      },

      externals: {
        'jquery':     'jQuery',
        'cookies-js': 'Cookies',
      },

      optimization: {
        minimizer: [
          new UglifyJsPlugin({
            uglifyOptions: {
              output: {
                comments: false,
              },
            },
          }),
        ],
      },
    },
  ];

};
<commit_msg>Generate min and non min js libs<commit_after>const
  path           = require( 'path' ),
  webpack        = require( 'webpack' ),
  UglifyJsPlugin = require( 'uglifyjs-webpack-plugin' ),

  config  = require( './build.config' );

/**
 * Define plugins based on environment
 *
 * @param {boolean} isDev If in development mode
 *
 * @return {Array}
 */
function getPlugins( isDev ) {
  const plugins = [];

  if ( !isDev ) {
    plugins.push( new webpack.NoEmitOnErrorsPlugin());
  }

  return plugins;
}

module.exports = ({
  includeToolkit,
  includeFabricator,
} = { includeToolkit: true, includeFabricator: true }) => {
  // Add properties: { 'dests_relative_path': 'source' }
  const entries    = {},
    libraryEntries = {};

  if ( includeToolkit ) {
    entries.toolkit = `./${config.paths.toolkit.scriptsIndex}`;

    if ( !config.devMode ) entries['toolkit.min'] = `./${config.paths.toolkit.scriptsIndex}`;

    // const minificationExtension = ( !config.devMode ) ? '.min' : '';

    // Add listed standalone modules and libraries to the build
    //TODO: Automate this!
    [
      'tracking',
      'popups',
      'tooltips',
      'lazyloader',
      'toolbar',
      'filtering',
      'urls',
      'core',
    ].forEach(( moduleName ) => {
      libraryEntries[`toolkit.${moduleName}`] = `./${config.paths.toolkit.scriptModules}/${moduleName}.js`;
      libraryEntries[`toolkit.${moduleName}.min`] = `./${config.paths.toolkit.scriptModules}/${moduleName}.js`;
    });
  }

  if ( includeFabricator ) {
    entries[`${config.names.fabricator.dist}/f`] = `./${config.paths.fabricator.scriptIndex}`;
  }

  return [
    {
      entry: entries,

      output: {
        path:     path.resolve( __dirname, '..', config.paths.tmp ),
        filename: '[name].js',
      },

      // (default) devtool: 'eval',

      resolve: {
        extensions: [
          '.js',
        ],
      },

      plugins: getPlugins( config.devMode ),

      mode: config.devMode ? 'development' : 'production',

      module:  {
        rules: [
          {
            test:    /\.js$/,
            exclude: /(node_modules|\.tmp|dist)/,
            loader:  'babel-loader',
          }, {
            test:   /(\.jpg|\.png)$/,
            loader: 'url-loader?limit=10000',
          },
        ],
      },

      externals: {
        jquery: 'jQuery',
      },

      optimization: {
        minimizer: [
          new UglifyJsPlugin({
            uglifyOptions: {
              output: {
                comments: false,
              },
            },
            exclude: 'toolkit.js', // Don't minify!
          }),
        ],
      },
    },

    // Config for standalone libraries compilation
    {
      entry: libraryEntries,

      output: {
        path:     path.resolve( __dirname, '..', config.paths.tmp ),
        filename: '[name].js',
      },

      // (default) devtool: 'eval',

      resolve: {
        extensions: [
          '.js',
        ],
      },

      plugins: getPlugins( config.devMode ),

      mode: config.devMode ? 'development' : 'production',

      module:  {
        rules: [
          {
            test:    /\.js$/,
            exclude: /(node_modules|\.tmp|dist)/,
            loader:  'babel-loader',
          }, {
            test:   /(\.jpg|\.png)$/,
            loader: 'url-loader?limit=10000',
          },
        ],
      },

      externals: {
        'jquery':     'jQuery',
        'cookies-js': 'Cookies',
      },

      optimization: {
        minimizer: [
          new UglifyJsPlugin({
            uglifyOptions: {
              output: {
                comments: false,
              },
            },
          }),
        ],
      },
    },
  ];

};
<|endoftext|>