<commit_before>import React, { Component, PropTypes } from 'react';
import { Animated, Easing } from 'react-native';
import wrapStyleTransforms from './wrapStyleTransforms';
import getStyleValues from './getStyleValues';
import createAnimation from './createAnimation';
import { getAnimationByName, getAnimationNames } from './registry';

// These styles are not number based and thus needs to be interpolated
const INTERPOLATION_STYLE_PROPERTIES = [
  // Transform styles
  'rotate',
  'rotateX',
  'rotateY',
  'rotateZ',
  'skewX',
  'skewY',
  'transformMatrix',
  // View styles
  'backgroundColor',
  'borderColor',
  'borderTopColor',
  'borderRightColor',
  'borderBottomColor',
  'borderLeftColor',
  'shadowColor',
  // Text styles
  'color',
  'textDecorationColor',
];

const EASING_FUNCTIONS = {
  linear: Easing.linear,
  ease: Easing.bezier(0.25, 0.1, 0.25, 1),
  'ease-in': Easing.bezier(0.42, 0, 1, 1),
  'ease-out': Easing.bezier(0, 0, 0.58, 1),
  'ease-in-out': Easing.bezier(0.42, 0, 0.58, 1),
};

// Create a copy of `source` without `keys`
function omit(keys, source) {
  const filtered = {};
  Object.keys(source).forEach((key) => {
    if (keys.indexOf(key) === -1) {
      filtered[key] = source[key];
    }
  });
  return filtered;
}

// Determine to what value the animation should tween to
function getAnimationTarget(iteration, direction) {
  switch (direction) {
    case 'reverse': return 0;
    case 'alternate': return (iteration % 2) ? 0 : 1;
    case 'alternate-reverse': return (iteration % 2) ? 1 : 0;
    case 'normal':
    default: return 1;
  }
}

// Like getAnimationTarget but opposite
function getAnimationOrigin(iteration, direction) {
  return getAnimationTarget(iteration, direction) ? 0 : 1;
}

function getCompiledAnimation(animation) {
  if (typeof animation === 'string') {
    const compiledAnimation = getAnimationByName(animation);
    if (!compiledAnimation) {
      throw new Error(`No animation registred by the name of ${animation}`);
    }
    return compiledAnimation;
  }
  return createAnimation(animation);
}

function makeInterpolatedStyle(compiledAnimation, animationValue) {
  const style = {};
  Object.keys(compiledAnimation).forEach((key) => {
    if (key === 'style') {
      Object.assign(style, compiledAnimation.style);
    } else if (key !== 'easing') {
      style[key] = animationValue.interpolate(compiledAnimation[key]);
    }
  });
  return wrapStyleTransforms(style);
}

function transitionToValue(transitionValue, toValue, duration, easing, useNativeDriver = false) {
  if (duration || easing) {
    Animated.timing(transitionValue, {
      toValue,
      duration: duration || 1000,
      easing: EASING_FUNCTIONS[easing || 'ease'],
      useNativeDriver,
    }).start();
  } else {
    Animated.spring(transitionValue, { toValue, useNativeDriver }).start();
  }
}

// Make (almost) any component animatable, similar to Animated.createAnimatedComponent
export default function createAnimatableComponent(WrappedComponent) {
  const wrappedComponentName = WrappedComponent.displayName
    || WrappedComponent.name
    || 'Component';

  const Animatable = Animated.createAnimatedComponent(WrappedComponent);

  return class AnimatableComponent extends Component {
    static displayName = `withAnimatable(${wrappedComponentName})`;

    static propTypes = {
      animation: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.object,
      ]),
      duration: PropTypes.number,
      direction: PropTypes.oneOf(['normal', 'reverse', 'alternate', 'alternate-reverse']),
      delay: PropTypes.number,
      easing: PropTypes.oneOf(Object.keys(EASING_FUNCTIONS)),
      iterationCount(props, propName) {
        const val = props[propName];
        if (val !== 'infinite' && !(typeof val === 'number' && val >= 1)) {
          return new Error('iterationCount must be a positive number or "infinite"');
        }
        return null;
      },
      onAnimationBegin: PropTypes.func,
      onAnimationEnd: PropTypes.func,
      style: PropTypes.oneOfType([
        PropTypes.number,
        PropTypes.array,
        PropTypes.object,
      ]),
      transition: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.arrayOf(PropTypes.string),
      ]),
      useNativeDriver: PropTypes.bool,
    };

    static defaultProps = {
      iterationCount: 1,
      onAnimationBegin() {},
      onAnimationEnd() {},
      useNativeDriver: false,
    };

    constructor(props) {
      super(props);

      const animationValue = new Animated.Value(getAnimationOrigin(0, this.props.direction));
      let animationStyle = {};
      let compiledAnimation = {};
      if (props.animation) {
        compiledAnimation = getCompiledAnimation(props.animation);
        animationStyle = makeInterpolatedStyle(compiledAnimation, animationValue);
      }
      this.state = {
        animationValue,
        animationStyle,
        compiledAnimation,
        transitionStyle: {},
        transitionValues: {},
        currentTransitionValues: {},
      };

      if (props.transition) {
        this.state = {
          ...this.state,
          ...this.initializeTransitionState(props.transition),
        };
      }
      this.delayTimer = null;

      // Alias registered animations for backwards compatibility
      getAnimationNames().forEach((animationName) => {
        if (!(animationName in this)) {
          this[animationName] = this.animate.bind(this, animationName);
        }
      });
    }

    initializeTransitionState(transitionKeys) {
      const transitionValues = {};
      const styleValues = {};

      const currentTransitionValues = getStyleValues(transitionKeys, this.props.style);
      Object.keys(currentTransitionValues).forEach((key) => {
        const value = currentTransitionValues[key];
        if (INTERPOLATION_STYLE_PROPERTIES.indexOf(key) !== -1) {
          transitionValues[key] = new Animated.Value(0);
          styleValues[key] = value;
        } else {
          transitionValues[key] = styleValues[key] = new Animated.Value(value);
        }
      });

      return {
        currentTransitionValues,
        transitionStyle: styleValues,
        transitionValues,
      };
    }

    getTransitionState(keys) {
      const transitionKeys = (typeof keys === 'string' ? [keys] : keys);
      let { transitionValues, currentTransitionValues, transitionStyle } = this.state;
      const missingKeys = transitionKeys.filter(key => !this.state.transitionValues[key]);
      if (missingKeys.length) {
        const transitionState = this.initializeTransitionState(missingKeys);
        transitionValues = {
          ...transitionValues,
          ...transitionState.transitionValues,
        };
        currentTransitionValues = {
          ...currentTransitionValues,
          ...transitionState.currentTransitionValues,
        };
        transitionStyle = {
          ...transitionStyle,
          ...transitionState.transitionStyle,
        };
      }
      return { transitionValues, currentTransitionValues, transitionStyle };
    }

    ref = null;
    handleRef = (ref) => {
      this.ref = ref;
    };

    setNativeProps(nativeProps) {
      if (this.ref) {
        this.ref.setNativeProps(nativeProps);
      }
    }

    componentDidMount() {
      const { animation, duration, delay, onAnimationBegin, onAnimationEnd } = this.props;
      if (animation) {
        const startAnimation = () => {
          onAnimationBegin();
          this.startAnimation(duration, 0, onAnimationEnd);
          this.delayTimer = null;
        };
        if (delay) {
          this.delayTimer = setTimeout(startAnimation, delay);
        } else {
          startAnimation();
        }
      }
    }

    componentWillReceiveProps(props) {
      const { animation, duration, easing, transition, onAnimationBegin, onAnimationEnd } = props;

      if (transition) {
        const values = getStyleValues(transition, props.style);
        this.transitionTo(values, duration, easing);
      } else if (animation !== this.props.animation) {
        if (animation) {
          if (this.delayTimer) {
            this.setAnimation(animation);
          } else {
            onAnimationBegin();
            this.animate(animation, duration).then(onAnimationEnd);
          }
        } else {
          this.stopAnimation();
        }
      }
    }

    componentWillUnmount() {
      if (this.delayTimer) {
        clearTimeout(this.delayTimer);
      }
    }

    setAnimation(animation, callback) {
      const compiledAnimation = getCompiledAnimation(animation);
      const animationStyle = makeInterpolatedStyle(compiledAnimation, this.state.animationValue);
      this.setState({ animationStyle, compiledAnimation }, callback);
    }

    animate(animation, duration) {
      return new Promise((resolve) => {
        this.setAnimation(animation, () => {
          this.startAnimation(duration, 0, resolve);
        });
      });
    }

    stopAnimation() {
      this.setState({
        scheduledAnimation: false,
        animationStyle: {},
      });
      this.state.animationValue.stopAnimation();
      if (this.delayTimer) {
        clearTimeout(this.delayTimer);
        this.delayTimer = null;
      }
    }

    startAnimation(duration, iteration, callback) {
      const { animationValue, compiledAnimation } = this.state;
      const { direction, iterationCount, useNativeDriver } = this.props;
      let easing = compiledAnimation.easing || 'ease';
      let currentIteration = iteration || 0;
      const fromValue = getAnimationOrigin(currentIteration, direction);
      const toValue = getAnimationTarget(currentIteration, direction);
      animationValue.setValue(fromValue);

      if (typeof easing === 'string') {
        easing = EASING_FUNCTIONS[easing];
      }
      // Reverse easing if on the way back
      const reversed = (
        (direction === 'reverse') ||
        (direction === 'alternate' && !toValue) ||
        (direction === 'alternate-reverse' && !toValue)
      );
      if (reversed) {
        easing = Easing.out(easing);
      }

      Animated.timing(animationValue, {
        toValue,
        easing,
        isInteraction: !iterationCount,
        duration: duration || this.props.duration || 1000,
        useNativeDriver,
      }).start((endState) => {
        currentIteration += 1;
        if (endState.finished && this.props.animation && (iterationCount === 'infinite' || currentIteration < iterationCount)) {
          this.startAnimation(duration, currentIteration, callback);
        } else if (callback) {
          callback(endState);
        }
      });
    }

    transition(fromValues, toValues, duration, easing) {
      const transitionKeys = Object.keys(toValues);
      const {
        transitionValues,
        currentTransitionValues,
        transitionStyle,
      } = this.getTransitionState(transitionKeys);

      transitionKeys.forEach((property) => {
        const fromValue = fromValues[property];
        const toValue = toValues[property];
        let transitionValue = transitionValues[property];
        if (!transitionValue) {
          transitionValue = new Animated.Value(0);
        }
        transitionStyle[property] = transitionValue;
        const needsInterpolation = INTERPOLATION_STYLE_PROPERTIES.indexOf(property) !== -1;
        if (needsInterpolation) {
          transitionValue.setValue(0);
          transitionStyle[property] = transitionValue.interpolate({
            inputRange: [0, 1],
            outputRange: [fromValue, toValue],
          });
          currentTransitionValues[property] = toValue;
          toValues[property] = 1; // eslint-disable-line no-param-reassign
        } else {
          transitionValue.setValue(fromValue);
        }
      });
      this.setState({ transitionValues, transitionStyle, currentTransitionValues }, () => {
        this.transitionToValues(toValues, duration || this.props.duration, easing);
      });
    }

    transitionTo(toValues, duration, easing) {
      const { currentTransitionValues } = this.state;

      const transitions = {
        from: {},
        to: {},
      };

      Object.keys(toValues).forEach((property) => {
        const toValue = toValues[property];
        const needsInterpolation = INTERPOLATION_STYLE_PROPERTIES.indexOf(property) !== -1;
        const transitionStyle = this.state.transitionStyle[property];
        const transitionValue = this.state.transitionValues[property];
        if (!needsInterpolation && transitionStyle && transitionStyle === transitionValue) {
          transitionToValue(transitionValue, toValue, duration, easing);
        } else {
          let currentTransitionValue = currentTransitionValues[property];
          if (typeof currentTransitionValue === 'undefined' && this.props.style) {
            const style = getStyleValues(property, this.props.style);
            currentTransitionValue = style[property];
          }
          transitions.from[property] = currentTransitionValue;
          transitions.to[property] = toValue;
        }
      });

      if (Object.keys(transitions.from).length) {
        this.transition(transitions.from, transitions.to, duration, easing);
      }
    }

    transitionToValues(toValues, duration, easing) {
      Object.keys(toValues).forEach((property) => {
        const transitionValue = this.state.transitionValues[property];
        const toValue = toValues[property];
        transitionToValue(transitionValue, toValue, duration, easing);
      });
    }

    render() {
      const { style, animation, transition } = this.props;
      if (animation && transition) {
        throw new Error('You cannot combine animation and transition props');
      }
      const restProps = omit(Object.keys(AnimatableComponent.propTypes), this.props);

      return (
        <Animatable
          ref={this.handleRef}
          style={[
            style,
            this.state.animationStyle,
            wrapStyleTransforms(this.state.transitionStyle),
          ]}
          {...restProps}
        />
      );
    }
  };
}
<commit_msg>Fix imperative transition with transforms #72<commit_after>import React, { Component, PropTypes } from 'react';
import { Animated, Easing } from 'react-native';
import wrapStyleTransforms from './wrapStyleTransforms';
import getStyleValues from './getStyleValues';
import flattenStyle from './flattenStyle';
import createAnimation from './createAnimation';
import { getAnimationByName, getAnimationNames } from './registry';

// These styles are not number based and thus needs to be interpolated
const INTERPOLATION_STYLE_PROPERTIES = [
  // Transform styles
  'rotate',
  'rotateX',
  'rotateY',
  'rotateZ',
  'skewX',
  'skewY',
  'transformMatrix',
  // View styles
  'backgroundColor',
  'borderColor',
  'borderTopColor',
  'borderRightColor',
  'borderBottomColor',
  'borderLeftColor',
  'shadowColor',
  // Text styles
  'color',
  'textDecorationColor',
];

const EASING_FUNCTIONS = {
  linear: Easing.linear,
  ease: Easing.bezier(0.25, 0.1, 0.25, 1),
  'ease-in': Easing.bezier(0.42, 0, 1, 1),
  'ease-out': Easing.bezier(0, 0, 0.58, 1),
  'ease-in-out': Easing.bezier(0.42, 0, 0.58, 1),
};

// Create a copy of `source` without `keys`
function omit(keys, source) {
  const filtered = {};
  Object.keys(source).forEach((key) => {
    if (keys.indexOf(key) === -1) {
      filtered[key] = source[key];
    }
  });
  return filtered;
}

// Determine to what value the animation should tween to
function getAnimationTarget(iteration, direction) {
  switch (direction) {
    case 'reverse': return 0;
    case 'alternate': return (iteration % 2) ? 0 : 1;
    case 'alternate-reverse': return (iteration % 2) ? 1 : 0;
    case 'normal':
    default: return 1;
  }
}

// Like getAnimationTarget but opposite
function getAnimationOrigin(iteration, direction) {
  return getAnimationTarget(iteration, direction) ? 0 : 1;
}

function getCompiledAnimation(animation) {
  if (typeof animation === 'string') {
    const compiledAnimation = getAnimationByName(animation);
    if (!compiledAnimation) {
      throw new Error(`No animation registred by the name of ${animation}`);
    }
    return compiledAnimation;
  }
  return createAnimation(animation);
}

function makeInterpolatedStyle(compiledAnimation, animationValue) {
  const style = {};
  Object.keys(compiledAnimation).forEach((key) => {
    if (key === 'style') {
      Object.assign(style, compiledAnimation.style);
    } else if (key !== 'easing') {
      style[key] = animationValue.interpolate(compiledAnimation[key]);
    }
  });
  return wrapStyleTransforms(style);
}

function transitionToValue(transitionValue, toValue, duration, easing, useNativeDriver = false) {
  if (duration || easing) {
    Animated.timing(transitionValue, {
      toValue,
      duration: duration || 1000,
      easing: EASING_FUNCTIONS[easing || 'ease'],
      useNativeDriver,
    }).start();
  } else {
    Animated.spring(transitionValue, { toValue, useNativeDriver }).start();
  }
}

// Make (almost) any component animatable, similar to Animated.createAnimatedComponent
export default function createAnimatableComponent(WrappedComponent) {
  const wrappedComponentName = WrappedComponent.displayName
    || WrappedComponent.name
    || 'Component';

  const Animatable = Animated.createAnimatedComponent(WrappedComponent);

  return class AnimatableComponent extends Component {
    static displayName = `withAnimatable(${wrappedComponentName})`;

    static propTypes = {
      animation: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.object,
      ]),
      duration: PropTypes.number,
      direction: PropTypes.oneOf(['normal', 'reverse', 'alternate', 'alternate-reverse']),
      delay: PropTypes.number,
      easing: PropTypes.oneOf(Object.keys(EASING_FUNCTIONS)),
      iterationCount(props, propName) {
        const val = props[propName];
        if (val !== 'infinite' && !(typeof val === 'number' && val >= 1)) {
          return new Error('iterationCount must be a positive number or "infinite"');
        }
        return null;
      },
      onAnimationBegin: PropTypes.func,
      onAnimationEnd: PropTypes.func,
      style: PropTypes.oneOfType([
        PropTypes.number,
        PropTypes.array,
        PropTypes.object,
      ]),
      transition: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.arrayOf(PropTypes.string),
      ]),
      useNativeDriver: PropTypes.bool,
    };

    static defaultProps = {
      iterationCount: 1,
      onAnimationBegin() {},
      onAnimationEnd() {},
      useNativeDriver: false,
    };

    constructor(props) {
      super(props);

      const animationValue = new Animated.Value(getAnimationOrigin(0, this.props.direction));
      let animationStyle = {};
      let compiledAnimation = {};
      if (props.animation) {
        compiledAnimation = getCompiledAnimation(props.animation);
        animationStyle = makeInterpolatedStyle(compiledAnimation, animationValue);
      }
      this.state = {
        animationValue,
        animationStyle,
        compiledAnimation,
        transitionStyle: {},
        transitionValues: {},
        currentTransitionValues: {},
      };

      if (props.transition) {
        this.state = {
          ...this.state,
          ...this.initializeTransitionState(props.transition),
        };
      }
      this.delayTimer = null;

      // Alias registered animations for backwards compatibility
      getAnimationNames().forEach((animationName) => {
        if (!(animationName in this)) {
          this[animationName] = this.animate.bind(this, animationName);
        }
      });
    }

    initializeTransitionState(transitionKeys) {
      const transitionValues = {};
      const styleValues = {};

      const currentTransitionValues = getStyleValues(transitionKeys, this.props.style);
      Object.keys(currentTransitionValues).forEach((key) => {
        const value = currentTransitionValues[key];
        if (INTERPOLATION_STYLE_PROPERTIES.indexOf(key) !== -1) {
          transitionValues[key] = new Animated.Value(0);
          styleValues[key] = value;
        } else {
          transitionValues[key] = styleValues[key] = new Animated.Value(value);
        }
      });

      return {
        currentTransitionValues,
        transitionStyle: styleValues,
        transitionValues,
      };
    }

    getTransitionState(keys) {
      const transitionKeys = (typeof keys === 'string' ? [keys] : keys);
      let { transitionValues, currentTransitionValues, transitionStyle } = this.state;
      const missingKeys = transitionKeys.filter(key => !this.state.transitionValues[key]);
      if (missingKeys.length) {
        const transitionState = this.initializeTransitionState(missingKeys);
        transitionValues = {
          ...transitionValues,
          ...transitionState.transitionValues,
        };
        currentTransitionValues = {
          ...currentTransitionValues,
          ...transitionState.currentTransitionValues,
        };
        transitionStyle = {
          ...transitionStyle,
          ...transitionState.transitionStyle,
        };
      }
      return { transitionValues, currentTransitionValues, transitionStyle };
    }

    ref = null;
    handleRef = (ref) => {
      this.ref = ref;
    };

    setNativeProps(nativeProps) {
      if (this.ref) {
        this.ref.setNativeProps(nativeProps);
      }
    }

    componentDidMount() {
      const { animation, duration, delay, onAnimationBegin, onAnimationEnd } = this.props;
      if (animation) {
        const startAnimation = () => {
          onAnimationBegin();
          this.startAnimation(duration, 0, onAnimationEnd);
          this.delayTimer = null;
        };
        if (delay) {
          this.delayTimer = setTimeout(startAnimation, delay);
        } else {
          startAnimation();
        }
      }
    }

    componentWillReceiveProps(props) {
      const { animation, duration, easing, transition, onAnimationBegin, onAnimationEnd } = props;

      if (transition) {
        const values = getStyleValues(transition, props.style);
        this.transitionTo(values, duration, easing);
      } else if (animation !== this.props.animation) {
        if (animation) {
          if (this.delayTimer) {
            this.setAnimation(animation);
          } else {
            onAnimationBegin();
            this.animate(animation, duration).then(onAnimationEnd);
          }
        } else {
          this.stopAnimation();
        }
      }
    }

    componentWillUnmount() {
      if (this.delayTimer) {
        clearTimeout(this.delayTimer);
      }
    }

    setAnimation(animation, callback) {
      const compiledAnimation = getCompiledAnimation(animation);
      const animationStyle = makeInterpolatedStyle(compiledAnimation, this.state.animationValue);
      this.setState({ animationStyle, compiledAnimation }, callback);
    }

    animate(animation, duration) {
      return new Promise((resolve) => {
        this.setAnimation(animation, () => {
          this.startAnimation(duration, 0, resolve);
        });
      });
    }

    stopAnimation() {
      this.setState({
        scheduledAnimation: false,
        animationStyle: {},
      });
      this.state.animationValue.stopAnimation();
      if (this.delayTimer) {
        clearTimeout(this.delayTimer);
        this.delayTimer = null;
      }
    }

    startAnimation(duration, iteration, callback) {
      const { animationValue, compiledAnimation } = this.state;
      const { direction, iterationCount, useNativeDriver } = this.props;
      let easing = compiledAnimation.easing || 'ease';
      let currentIteration = iteration || 0;
      const fromValue = getAnimationOrigin(currentIteration, direction);
      const toValue = getAnimationTarget(currentIteration, direction);
      animationValue.setValue(fromValue);

      if (typeof easing === 'string') {
        easing = EASING_FUNCTIONS[easing];
      }
      // Reverse easing if on the way back
      const reversed = (
        (direction === 'reverse') ||
        (direction === 'alternate' && !toValue) ||
        (direction === 'alternate-reverse' && !toValue)
      );
      if (reversed) {
        easing = Easing.out(easing);
      }

      Animated.timing(animationValue, {
        toValue,
        easing,
        isInteraction: !iterationCount,
        duration: duration || this.props.duration || 1000,
        useNativeDriver,
      }).start((endState) => {
        currentIteration += 1;
        if (endState.finished && this.props.animation && (iterationCount === 'infinite' || currentIteration < iterationCount)) {
          this.startAnimation(duration, currentIteration, callback);
        } else if (callback) {
          callback(endState);
        }
      });
    }

    transition(fromValues, toValues, duration, easing) {
      const fromValuesFlat = flattenStyle(fromValues);
      const toValuesFlat = flattenStyle(toValues);
      const transitionKeys = Object.keys(toValuesFlat);
      const {
        transitionValues,
        currentTransitionValues,
        transitionStyle,
      } = this.getTransitionState(transitionKeys);

      transitionKeys.forEach((property) => {
        const fromValue = fromValuesFlat[property];
        const toValue = toValuesFlat[property];
        let transitionValue = transitionValues[property];
        if (!transitionValue) {
          transitionValue = new Animated.Value(0);
        }
        transitionStyle[property] = transitionValue;
        const needsInterpolation = INTERPOLATION_STYLE_PROPERTIES.indexOf(property) !== -1;
        if (needsInterpolation) {
          transitionValue.setValue(0);
          transitionStyle[property] = transitionValue.interpolate({
            inputRange: [0, 1],
            outputRange: [fromValue, toValue],
          });
          currentTransitionValues[property] = toValue;
          toValuesFlat[property] = 1;
        } else {
          transitionValue.setValue(fromValue);
        }
      });
      this.setState({ transitionValues, transitionStyle, currentTransitionValues }, () => {
        this.transitionToValues(toValuesFlat, duration || this.props.duration, easing);
      });
    }

    transitionTo(toValues, duration, easing) {
      const { currentTransitionValues } = this.state;
      const toValuesFlat = flattenStyle(toValues);
      const transitions = {
        from: {},
        to: {},
      };

      Object.keys(toValuesFlat).forEach((property) => {
        const toValue = toValuesFlat[property];
        const needsInterpolation = INTERPOLATION_STYLE_PROPERTIES.indexOf(property) !== -1;
        const transitionStyle = this.state.transitionStyle[property];
        const transitionValue = this.state.transitionValues[property];
        if (!needsInterpolation && transitionStyle && transitionStyle === transitionValue) {
          transitionToValue(transitionValue, toValue, duration, easing);
        } else {
          let currentTransitionValue = currentTransitionValues[property];
          if (typeof currentTransitionValue === 'undefined' && this.props.style) {
            const style = getStyleValues(property, this.props.style);
            currentTransitionValue = style[property];
          }
          transitions.from[property] = currentTransitionValue;
          transitions.to[property] = toValue;
        }
      });

      if (Object.keys(transitions.from).length) {
        this.transition(transitions.from, transitions.to, duration, easing);
      }
    }

    transitionToValues(toValues, duration, easing) {
      Object.keys(toValues).forEach((property) => {
        const transitionValue = this.state.transitionValues[property];
        const toValue = toValues[property];
        transitionToValue(transitionValue, toValue, duration, easing);
      });
    }

    render() {
      const { style, animation, transition } = this.props;
      if (animation && transition) {
        throw new Error('You cannot combine animation and transition props');
      }
      const restProps = omit(Object.keys(AnimatableComponent.propTypes), this.props);

      return (
        <Animatable
          ref={this.handleRef}
          style={[
            style,
            this.state.animationStyle,
            wrapStyleTransforms(this.state.transitionStyle),
          ]}
          {...restProps}
        />
      );
    }
  };
}
<|endoftext|>


<commit_before>/* jshint esversion: 6 */
'use strict';

var testSauceLabs = require('test-saucelabs');

// https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities
var platforms = [{
	browserName: 'internet explorer',
	platform: 'Windows 7',
	version: '9'
}, {
	browserName: 'internet explorer',
	platform: 'Windows 8',
	version: '10.0'
}, {
	browserName: 'internet explorer',
	platform: 'Windows 10',
	version: '11.0'
}, {
	browserName: 'safari',
	platform: 'OS X 10.12',
	version: 'latest'
}, {
	browserName: 'MicrosoftEdge',
	platform: 'Windows 10'
}, {
	browserName: 'firefox',
	platform: 'Windows 10',
	version: 'latest'
}, {
	browserName: 'googlechrome',
	platform: 'Windows 10',
	version: 'latest'
}, {
	browserName: 'Safari',
	'appium-version': '1.7.1',
	platformName: 'iOS',
	platformVersion: '11.0',
	deviceName: 'iPhone 8 Simulator'
}];

var url = 'http://canjs.test:3000/test/index.html?hidepassed';

testSauceLabs({
	urls: [{ name: "canjs", url : url }],
	platforms: platforms,
	zeroAssertionsPass: false
});
<commit_msg>Increase suacelabs timeouts<commit_after>/* jshint esversion: 6 */
'use strict';

var testSauceLabs = require('test-saucelabs');

var maxDuration = 10800; // seconds, default 1800, max 10800
var commandTimeout = 600; // seconds, default 300, max 600
var idleTimeout = 1000; // seconds, default 90, max 1000

// https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities
var platforms = [{
	browserName: 'internet explorer',
	platform: 'Windows 7',
	version: '9',
	maxDuration: maxDuration,
	commandTimeout: commandTimeout,
	idleTimeout: idleTimeout
}, {
	browserName: 'internet explorer',
	platform: 'Windows 8',
	version: '10.0',
	maxDuration: maxDuration,
	commandTimeout: commandTimeout,
	idleTimeout: idleTimeout
}, {
	browserName: 'internet explorer',
	platform: 'Windows 10',
	version: '11.0',
	maxDuration: maxDuration,
	commandTimeout: commandTimeout,
	idleTimeout: idleTimeout
}, {
	browserName: 'safari',
	platform: 'OS X 10.12',
	version: 'latest',
	maxDuration: maxDuration,
	commandTimeout: commandTimeout,
	idleTimeout: idleTimeout
}, {
	browserName: 'MicrosoftEdge',
	platform: 'Windows 10',
	maxDuration: maxDuration,
	commandTimeout: commandTimeout,
	idleTimeout: idleTimeout
}, {
	browserName: 'firefox',
	platform: 'Windows 10',
	version: 'latest',
	maxDuration: maxDuration,
	commandTimeout: commandTimeout,
	idleTimeout: idleTimeout
}, {
	browserName: 'googlechrome',
	platform: 'Windows 10',
	version: 'latest',
	maxDuration: maxDuration,
	commandTimeout: commandTimeout,
	idleTimeout: idleTimeout
}, {
	browserName: 'Safari',
	'appium-version': '1.7.1',
	platformName: 'iOS',
	platformVersion: '11.0',
	deviceName: 'iPhone 8 Simulator',
	maxDuration: maxDuration,
	commandTimeout: commandTimeout,
	idleTimeout: idleTimeout
}];

var url = 'http://canjs.test:3000/test/index.html?hidepassed';

testSauceLabs({
	urls: [{ name: "canjs", url : url }],
	platforms: platforms,
	zeroAssertionsPass: false
});
<|endoftext|>


<commit_before>/** @babel */

import {Emitter, Disposable, CompositeDisposable} from "event-kit"

const EDITOR_SETTER_NAMES_BY_SETTING_KEY = [
  ['core.fileEncoding', 'setEncoding'],
  ['editor.atomicSoftTabs', 'setAtomicSoftTabs'],
  ['editor.showInvisibles', 'setShowInvisibles'],
  ['editor.tabLength', 'setTabLength'],
  ['editor.invisibles', 'setInvisibles'],
  ['editor.showIndentGuide', 'setShowIndentGuide'],
  ['editor.softWrap', 'setSoftWrapped'],
  ['editor.softWrapHangingIndent', 'setSoftWrapIndentLength'],
  ['editor.softWrapAtPreferredLineLength', 'setSoftWrapAtPreferredLineLength'],
  ['editor.preferredLineLength', 'setPreferredLineLength'],
]

// Experimental: This global registry tracks registered `TextEditors`.
//
// If you want to add functionality to a wider set of text editors than just
// those appearing within workspace panes, use `atom.textEditors.observe` to
// invoke a callback for all current and future registered text editors.
//
// If you want packages to be able to add functionality to your non-pane text
// editors (such as a search field in a custom user interface element), register
// them for observation via `atom.textEditors.add`. **Important:** When you're
// done using your editor, be sure to call `dispose` on the returned disposable
// to avoid leaking editors.
export default class TextEditorRegistry {
  constructor ({config}) {
    this.config = config
    this.subscriptions = new CompositeDisposable()
    this.editors = new Set()
    this.emitter = new Emitter()
    this.scopesWithConfigSubscriptions = new Set()
    this.editorsWithMaintainedConfig = new Set()
  }

  destroy () {
    this.subscriptions.dispose()
    this.editorsWithMaintainedConfig = null
  }

  // Register a `TextEditor`.
  //
  // * `editor` The editor to register.
  //
  // Returns a {Disposable} on which `.dispose()` can be called to remove the
  // added editor. To avoid any memory leaks this should be called when the
  // editor is destroyed.
  add (editor) {
    this.editors.add(editor)
    editor.registered = true
    this.emitter.emit("did-add-editor", editor)

    return new Disposable(() => this.remove(editor))
  }

  // Remove a `TextEditor`.
  //
  // * `editor` The editor to remove.
  //
  // Returns a {Boolean} indicating whether the editor was successfully removed.
  remove (editor) {
    var removed = this.editors.delete(editor)
    editor.registered = false
    return removed
  }

  // Invoke the given callback with all the current and future registered
  // `TextEditors`.
  //
  // * `callback` {Function} to be called with current and future text editors.
  //
  // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
  observe (callback) {
    this.editors.forEach(callback)
    return this.emitter.on("did-add-editor", callback)
  }

  maintainGrammar (editor) {

  }

  maintainConfig (editor) {
    this.editorsWithMaintainedConfig.add(editor)
    this.subscribeToSettingsForEditorScope(editor)

    const configOptions = {scope: editor.getRootScopeDescriptor()}
    for (const [settingKey, setterName] of EDITOR_SETTER_NAMES_BY_SETTING_KEY) {
      editor[setterName](atom.config.get(settingKey, configOptions))
    }

    const updateTabTypes = () => {
      editor.setSoftTabs(shouldEditorUseSoftTabs(
        editor,
        atom.config.get('editor.tabType', configOptions),
        atom.config.get('editor.softTabs', configOptions)
      ))
    }

    updateTabTypes()
    this.subscriptions.add(editor.onDidTokenize(updateTabTypes))
  }

  subscribeToSettingsForEditorScope (editor) {
    const scopeDescriptor = editor.getRootScopeDescriptor()
    const scopeChain = scopeDescriptor.getScopeChain()

    if (!this.scopesWithConfigSubscriptions.has(scopeChain)) {
      this.scopesWithConfigSubscriptions.add(scopeChain)

      const configOptions = {scope: scopeDescriptor}

      for (const [settingKey, setterName] of EDITOR_SETTER_NAMES_BY_SETTING_KEY) {
        this.subscriptions.add(
          this.config.onDidChange(settingKey, configOptions, ({newValue}) => {
            this.editorsWithMaintainedConfig.forEach(editor => {
              if (editor.getRootScopeDescriptor().getScopeChain() === scopeChain) {
                editor[setterName](newValue)
              }
            })
          })
        )
      }

      const updateTabTypes = () => {
        const tabType = this.config.get('editor.tabType', configOptions)
        const softTabs = this.config.get('editor.softTabs', configOptions)

        this.editorsWithMaintainedConfig.forEach(editor => {
          if (editor.getRootScopeDescriptor().getScopeChain() === scopeChain) {
            editor.setSoftTabs(shouldEditorUseSoftTabs(editor, tabType, softTabs))
          }
        })
      }

      this.subscriptions.add(
        this.config.onDidChange('editor.tabType', configOptions, updateTabTypes),
        this.config.onDidChange('editor.softTabs', configOptions, updateTabTypes)
      )
    }
  }
}

function shouldEditorUseSoftTabs (editor, tabType, softTabs) {
  switch (tabType) {
    case 'hard':
      return false
    case 'soft':
      return true
    case 'auto':
      switch (editor.usesSoftTabs()) {
        case true:
          return true
        case false:
          return false
        default:
          return softTabs
      }
  }
}
<commit_msg>Use local config reference in TextEditorRegistry<commit_after>/** @babel */

import {Emitter, Disposable, CompositeDisposable} from "event-kit"

const EDITOR_SETTER_NAMES_BY_SETTING_KEY = [
  ['core.fileEncoding', 'setEncoding'],
  ['editor.atomicSoftTabs', 'setAtomicSoftTabs'],
  ['editor.showInvisibles', 'setShowInvisibles'],
  ['editor.tabLength', 'setTabLength'],
  ['editor.invisibles', 'setInvisibles'],
  ['editor.showIndentGuide', 'setShowIndentGuide'],
  ['editor.softWrap', 'setSoftWrapped'],
  ['editor.softWrapHangingIndent', 'setSoftWrapIndentLength'],
  ['editor.softWrapAtPreferredLineLength', 'setSoftWrapAtPreferredLineLength'],
  ['editor.preferredLineLength', 'setPreferredLineLength'],
]

// Experimental: This global registry tracks registered `TextEditors`.
//
// If you want to add functionality to a wider set of text editors than just
// those appearing within workspace panes, use `atom.textEditors.observe` to
// invoke a callback for all current and future registered text editors.
//
// If you want packages to be able to add functionality to your non-pane text
// editors (such as a search field in a custom user interface element), register
// them for observation via `atom.textEditors.add`. **Important:** When you're
// done using your editor, be sure to call `dispose` on the returned disposable
// to avoid leaking editors.
export default class TextEditorRegistry {
  constructor ({config}) {
    this.config = config
    this.subscriptions = new CompositeDisposable()
    this.editors = new Set()
    this.emitter = new Emitter()
    this.scopesWithConfigSubscriptions = new Set()
    this.editorsWithMaintainedConfig = new Set()
  }

  destroy () {
    this.subscriptions.dispose()
    this.editorsWithMaintainedConfig = null
  }

  // Register a `TextEditor`.
  //
  // * `editor` The editor to register.
  //
  // Returns a {Disposable} on which `.dispose()` can be called to remove the
  // added editor. To avoid any memory leaks this should be called when the
  // editor is destroyed.
  add (editor) {
    this.editors.add(editor)
    editor.registered = true
    this.emitter.emit("did-add-editor", editor)

    return new Disposable(() => this.remove(editor))
  }

  // Remove a `TextEditor`.
  //
  // * `editor` The editor to remove.
  //
  // Returns a {Boolean} indicating whether the editor was successfully removed.
  remove (editor) {
    var removed = this.editors.delete(editor)
    editor.registered = false
    return removed
  }

  // Invoke the given callback with all the current and future registered
  // `TextEditors`.
  //
  // * `callback` {Function} to be called with current and future text editors.
  //
  // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
  observe (callback) {
    this.editors.forEach(callback)
    return this.emitter.on("did-add-editor", callback)
  }

  maintainGrammar (editor) {

  }

  maintainConfig (editor) {
    this.editorsWithMaintainedConfig.add(editor)
    this.subscribeToSettingsForEditorScope(editor)

    const configOptions = {scope: editor.getRootScopeDescriptor()}
    for (const [settingKey, setterName] of EDITOR_SETTER_NAMES_BY_SETTING_KEY) {
      editor[setterName](this.config.get(settingKey, configOptions))
    }

    const updateTabTypes = () => {
      editor.setSoftTabs(shouldEditorUseSoftTabs(
        editor,
        this.config.get('editor.tabType', configOptions),
        this.config.get('editor.softTabs', configOptions)
      ))
    }

    updateTabTypes()
    this.subscriptions.add(editor.onDidTokenize(updateTabTypes))
  }

  subscribeToSettingsForEditorScope (editor) {
    const scopeDescriptor = editor.getRootScopeDescriptor()
    const scopeChain = scopeDescriptor.getScopeChain()

    if (!this.scopesWithConfigSubscriptions.has(scopeChain)) {
      this.scopesWithConfigSubscriptions.add(scopeChain)

      const configOptions = {scope: scopeDescriptor}

      for (const [settingKey, setterName] of EDITOR_SETTER_NAMES_BY_SETTING_KEY) {
        this.subscriptions.add(
          this.config.onDidChange(settingKey, configOptions, ({newValue}) => {
            this.editorsWithMaintainedConfig.forEach(editor => {
              if (editor.getRootScopeDescriptor().getScopeChain() === scopeChain) {
                editor[setterName](newValue)
              }
            })
          })
        )
      }

      const updateTabTypes = () => {
        const tabType = this.config.get('editor.tabType', configOptions)
        const softTabs = this.config.get('editor.softTabs', configOptions)

        this.editorsWithMaintainedConfig.forEach(editor => {
          if (editor.getRootScopeDescriptor().getScopeChain() === scopeChain) {
            editor.setSoftTabs(shouldEditorUseSoftTabs(editor, tabType, softTabs))
          }
        })
      }

      this.subscriptions.add(
        this.config.onDidChange('editor.tabType', configOptions, updateTabTypes),
        this.config.onDidChange('editor.softTabs', configOptions, updateTabTypes)
      )
    }
  }
}

function shouldEditorUseSoftTabs (editor, tabType, softTabs) {
  switch (tabType) {
    case 'hard':
      return false
    case 'soft':
      return true
    case 'auto':
      switch (editor.usesSoftTabs()) {
        case true:
          return true
        case false:
          return false
        default:
          return softTabs
      }
  }
}
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { get } from 'lodash';

const withServicePoints = WrappedComponent =>
  class WithServicePointsComponent extends React.Component {
    static manifest = {
      ...WrappedComponent.manifest,
      servicePoints: {
        type: 'okapi',
        path: 'service-points',
        records: 'servicepoints',
        accumulate: true,
        fetch: false,
      },
      servicePointUserId: '',
      servicePointsUsers: {
        type: 'okapi',
        path: 'service-points-users?query=(userId==:{id})',
        records: 'servicePointsUsers',
        accumulate: true,
        fetch: false,
        POST: {
          path: 'service-points-users',
        },
        PUT: {
          path: 'service-points-users/%{servicePointUserId}',
        },
      },
    }

    static propTypes = {
      parentResources: PropTypes.object,
      resources: PropTypes.shape({
        servicePoints: PropTypes.shape({
          records: PropTypes.arrayOf(PropTypes.object),
        }),
        servicePointsUsers: PropTypes.shape({
          records: PropTypes.arrayOf(PropTypes.object),
        }),
      }),
      match: PropTypes.shape({
        params: PropTypes.shape({
          id: PropTypes.string,
        }).isRequired,
      }).isRequired,
      mutator: PropTypes.shape({
        servicePoints: PropTypes.shape({
          GET: PropTypes.func.isRequired,
          reset: PropTypes.func.isRequired,
        }),
        servicePointUserId: PropTypes.shape({
          replace: PropTypes.func.isRequired,
        }),
        servicePointsUsers: PropTypes.shape({
          GET: PropTypes.func.isRequired,
          reset: PropTypes.func.isRequired,
          POST: PropTypes.func.isRequired,
          PUT: PropTypes.func.isRequired,
        }),
      }),
      stripes: PropTypes.shape({
        hasPerm: PropTypes.func.isRequired,
      }).isRequired,
    };

    state = {
      userServicePoints: [],
      userPreferredServicePoint: undefined,
    }

    static getDerivedStateFromProps(nextProps, state) {
      // Save the id of the record in the service-points-users table for later use when mutating it.
      const servicePointUserId = get(nextProps.resources.servicePointsUsers, ['records', 0, 'id'], '');
      const localServicePointUserId = nextProps.resources.servicePointUserId;
      if (servicePointUserId !== localServicePointUserId) {
        nextProps.mutator.servicePointUserId.replace(servicePointUserId);
      }

      // Check if new user service points have been received and the list of all service points has also been received.
      const userServicePointsIds = get(nextProps.resources.servicePointsUsers, ['records', 0, 'servicePointsIds'], []);
      const servicePoints = get(nextProps.resources.servicePoints, ['records'], []);
      if ((userServicePointsIds.length !== state.userServicePoints.length) && servicePoints.length) {
        const userServicePoints = userServicePointsIds
          .map(usp => servicePoints.find(sp => sp.id === usp))
          .sort(((a, b) => a.name.localeCompare(b.name, undefined, { numeric: true })));

        const userPreferredServicePoint = get(nextProps.resources.servicePointsUsers, ['records', 0, 'defaultServicePointId'], '-');

        return {
          userServicePoints,
          userPreferredServicePoint,
        };
      }

      return null;
    }

    componentDidMount() {
      this.fetchServicePointsResources();
    }

    componentDidUpdate(prevProps) {
      if (prevProps.match.params.id !== this.props.match.params.id) {
        this.fetchServicePointsResources();
      }

      return {};
    }

    fetchServicePointsResources() {
      // Fetch the records for what service points are associated with this user. We can't
      // automatically fetch them since we have `fetch: false` turned on to avoid fetching
      // if the logged-in user doesn't have permissions to fetch the record.
      if (this.props.stripes.hasPerm('inventory-storage.service-points.collection.get,inventory-storage.service-points-users.collection.get')) {
        this.props.mutator.servicePointsUsers.reset();
        this.props.mutator.servicePointsUsers.GET();
        this.props.mutator.servicePoints.reset();
        this.props.mutator.servicePoints.GET();
      }
    }

    getServicePoints = () => {
      return this.state.userServicePoints;
    }

    getPreferredServicePoint = () => {
      return this.state.userPreferredServicePoint;
    }

    updateServicePoints = (servicePoints, preferredServicePoint) => {
      let mutator;
      let record = get(this.props.resources.servicePointsUsers, ['records', 0]);
      if (record) {
        mutator = this.props.mutator.servicePointsUsers.PUT;
      } else {
        mutator = this.props.mutator.servicePointsUsers.POST;
        record = { userId: this.props.match.params.id };
      }

      record.servicePointsIds = servicePoints.map(sp => sp.id);
      record.defaultServicePointId = preferredServicePoint === '-' ? null : preferredServicePoint;

      mutator(record).then(() => {
        this.props.mutator.servicePointsUsers.reset();
        this.props.mutator.servicePointsUsers.GET();
      });
    }

    render() {
      return (<WrappedComponent
        getServicePoints={this.getServicePoints}
        getPreferredServicePoint={this.getPreferredServicePoint}
        updateServicePoints={this.updateServicePoints}
        {...this.props}
      />);
    }
  };

export default withServicePoints;
<commit_msg>Clean defaultServicePointId when no service points are present<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { get } from 'lodash';

const withServicePoints = WrappedComponent =>
  class WithServicePointsComponent extends React.Component {
    static manifest = {
      ...WrappedComponent.manifest,
      servicePoints: {
        type: 'okapi',
        path: 'service-points',
        records: 'servicepoints',
        accumulate: true,
        fetch: false,
      },
      servicePointUserId: '',
      servicePointsUsers: {
        type: 'okapi',
        path: 'service-points-users?query=(userId==:{id})',
        records: 'servicePointsUsers',
        accumulate: true,
        fetch: false,
        POST: {
          path: 'service-points-users',
        },
        PUT: {
          path: 'service-points-users/%{servicePointUserId}',
        },
      },
    }

    static propTypes = {
      parentResources: PropTypes.object,
      resources: PropTypes.shape({
        servicePoints: PropTypes.shape({
          records: PropTypes.arrayOf(PropTypes.object),
        }),
        servicePointsUsers: PropTypes.shape({
          records: PropTypes.arrayOf(PropTypes.object),
        }),
      }),
      match: PropTypes.shape({
        params: PropTypes.shape({
          id: PropTypes.string,
        }).isRequired,
      }).isRequired,
      mutator: PropTypes.shape({
        servicePoints: PropTypes.shape({
          GET: PropTypes.func.isRequired,
          reset: PropTypes.func.isRequired,
        }),
        servicePointUserId: PropTypes.shape({
          replace: PropTypes.func.isRequired,
        }),
        servicePointsUsers: PropTypes.shape({
          GET: PropTypes.func.isRequired,
          reset: PropTypes.func.isRequired,
          POST: PropTypes.func.isRequired,
          PUT: PropTypes.func.isRequired,
        }),
      }),
      stripes: PropTypes.shape({
        hasPerm: PropTypes.func.isRequired,
      }).isRequired,
    };

    state = {
      userServicePoints: [],
      userPreferredServicePoint: undefined,
    }

    static getDerivedStateFromProps(nextProps, state) {
      // Save the id of the record in the service-points-users table for later use when mutating it.
      const servicePointUserId = get(nextProps.resources.servicePointsUsers, ['records', 0, 'id'], '');
      const localServicePointUserId = nextProps.resources.servicePointUserId;
      if (servicePointUserId !== localServicePointUserId) {
        nextProps.mutator.servicePointUserId.replace(servicePointUserId);
      }

      // Check if new user service points have been received and the list of all service points has also been received.
      const userServicePointsIds = get(nextProps.resources.servicePointsUsers, ['records', 0, 'servicePointsIds'], []);
      const servicePoints = get(nextProps.resources.servicePoints, ['records'], []);
      if ((userServicePointsIds.length !== state.userServicePoints.length) && servicePoints.length) {
        const userServicePoints = userServicePointsIds
          .map(usp => servicePoints.find(sp => sp.id === usp))
          .sort(((a, b) => a.name.localeCompare(b.name, undefined, { numeric: true })));

        const userPreferredServicePoint = get(nextProps.resources.servicePointsUsers, ['records', 0, 'defaultServicePointId'], '-');

        return {
          userServicePoints,
          userPreferredServicePoint,
        };
      }

      return null;
    }

    componentDidMount() {
      this.fetchServicePointsResources();
    }

    componentDidUpdate(prevProps) {
      if (prevProps.match.params.id !== this.props.match.params.id) {
        this.fetchServicePointsResources();
      }

      return {};
    }

    fetchServicePointsResources() {
      // Fetch the records for what service points are associated with this user. We can't
      // automatically fetch them since we have `fetch: false` turned on to avoid fetching
      // if the logged-in user doesn't have permissions to fetch the record.
      if (this.props.stripes.hasPerm('inventory-storage.service-points.collection.get,inventory-storage.service-points-users.collection.get')) {
        this.props.mutator.servicePointsUsers.reset();
        this.props.mutator.servicePointsUsers.GET();
        this.props.mutator.servicePoints.reset();
        this.props.mutator.servicePoints.GET();
      }
    }

    getServicePoints = () => {
      return this.state.userServicePoints;
    }

    getPreferredServicePoint = () => {
      return this.state.userPreferredServicePoint;
    }

    updateServicePoints = (servicePoints, preferredServicePoint) => {
      let mutator;
      let record = get(this.props.resources.servicePointsUsers, ['records', 0]);
      if (record) {
        mutator = this.props.mutator.servicePointsUsers.PUT;
      } else {
        mutator = this.props.mutator.servicePointsUsers.POST;
        record = { userId: this.props.match.params.id };
      }

      record.servicePointsIds = servicePoints.map(sp => sp.id);
      record.defaultServicePointId = (!servicePoints.length || preferredServicePoint === '-') ? null : preferredServicePoint;

      mutator(record).then(() => {
        this.props.mutator.servicePointsUsers.reset();
        this.props.mutator.servicePointsUsers.GET();
      });
    }

    render() {
      return (<WrappedComponent
        getServicePoints={this.getServicePoints}
        getPreferredServicePoint={this.getPreferredServicePoint}
        updateServicePoints={this.updateServicePoints}
        {...this.props}
      />);
    }
  };

export default withServicePoints;
<|endoftext|>


<commit_before>/**
 * Project info config object
 *
 * All params optional unless
 * otherwise noted
 *
 * @params {
 *  string  name               (required) The built theme dirname and the theme text-domain
 *  string  prettyName         (required) The theme name as shown in the theme selector admin
 *  string  themeURI           The theme's URI
 *  string  description        A short description of the theme
 *  string  parentTheme        If this is a child theme, then put the parent
 *                             theme's directory name here
 *  string  version            The theme's version
 *  string  author             The theme's author
 *  string  authorURI          The theme author's URI
 *  string  license            The theme's license
 *  string  licenseURI         The theme license's URI
 *  array   tags               Keywords that could be associated with the theme
 * }
 */
module.exports = {
	name: 'usine',
	prettyName: 'Usine',
	themeURI: 'https://github.com/usine/wp-usine',
	githubThemeURI: 'https://github.com/usine/wp-usine',
	releaseAsset: 'true',
	description: 'The 2016 theme for usine.ch. Built by Mehdi Lahlou',
	version: '1.3.2',
	author: 'Mehdi Lahlou <mehdi.lahlou@free.fr>',
	authorURI: 'https://github.com/medfreeman',
	license: 'GPLv2 or later'
};
<commit_msg>project version bump to 1.3.3<commit_after>/**
 * Project info config object
 *
 * All params optional unless
 * otherwise noted
 *
 * @params {
 *  string  name               (required) The built theme dirname and the theme text-domain
 *  string  prettyName         (required) The theme name as shown in the theme selector admin
 *  string  themeURI           The theme's URI
 *  string  description        A short description of the theme
 *  string  parentTheme        If this is a child theme, then put the parent
 *                             theme's directory name here
 *  string  version            The theme's version
 *  string  author             The theme's author
 *  string  authorURI          The theme author's URI
 *  string  license            The theme's license
 *  string  licenseURI         The theme license's URI
 *  array   tags               Keywords that could be associated with the theme
 * }
 */
module.exports = {
	name: 'usine',
	prettyName: 'Usine',
	themeURI: 'https://github.com/usine/wp-usine',
	githubThemeURI: 'https://github.com/usine/wp-usine',
	releaseAsset: 'true',
	description: 'The 2016 theme for usine.ch. Built by Mehdi Lahlou',
	version: '1.3.3',
	author: 'Mehdi Lahlou <mehdi.lahlou@free.fr>',
	authorURI: 'https://github.com/medfreeman',
	license: 'GPLv2 or later'
};
<|endoftext|>


<commit_before>export { foo } from './j';
<commit_msg>Fix test<commit_after>import { foo } from './j';

function myFunction() {

}

export { foo };
<|endoftext|>


<commit_before>import React from 'react';
import { Footer } from '../../index';

import { injectIntl } from 'react-intl';
import { messages }   from '../translations/defaultMessages';

const copyrightText = 'Pearson Education Inc. All Rights Reserved.';

const FooterPage = (props) => {

  const { intl } = props;

  const testLinks = [{
    text: 'First link',
    href: 'first'
  }, {
    text: 'Second link',
    href: 'second'
  }, {
    text: 'Last link',
    href: 'last'
  }];

  const intlText = {
    copyrightText : intl.formatMessage(messages.copyrightText)
  };

  return (

Footer

Props

Required:

links:Array === {`[{ text: 'First link', href: 'First href'},
              { text: 'Second link', href: 'Second href' }]`}

Optional:

copyrightText:String

Used to insert copyright information.

light:Boolean

The light prop can be used to provide contrast
            on a darker background.

Example usage

            {`const testLinks = [{
              text: 'First link',
              href: 'first'
            }, {
              text: 'Second link',
              href: 'second'
            }, {
              text: 'Last link',
              href: 'last'
            }];`}

            {`const copyrightText= 'Pearson Education Inc.
            All Rights Reserved.'`}
            {`<Footer links={testLinks} />`}

    );
};

export default injectIntl(FooterPage);
<commit_msg>chore: Update design path<commit_after>import React from 'react';
import { Footer } from '../../index';

import { injectIntl } from 'react-intl';
import { messages }   from '../translations/defaultMessages';

const copyrightText = 'Pearson Education Inc. All Rights Reserved.';

const FooterPage = (props) => {

  const { intl } = props;

  const testLinks = [{
    text: 'First link',
    href: 'first'
  }, {
    text: 'Second link',
    href: 'second'
  }, {
    text: 'Last link',
    href: 'last'
  }];

  const intlText = {
    copyrightText : intl.formatMessage(messages.copyrightText)
  };

  return (

Footer

Props

Required:

links:Array === {`[{ text: 'First link', href: 'First href'},
              { text: 'Second link', href: 'Second href' }]`}

Optional:

copyrightText:String

Used to insert copyright information.

light:Boolean

The light prop can be used to provide contrast
            on a darker background.

Example usage

            {`const testLinks = [{
              text: 'First link',
              href: 'first'
            }, {
              text: 'Second link',
              href: 'second'
            }, {
              text: 'Last link',
              href: 'last'
            }];`}

            {`const copyrightText= 'Pearson Education Inc.
            All Rights Reserved.'`}
            {`<Footer links={testLinks} />`}

    );
};

export default injectIntl(FooterPage);
<|endoftext|>


<commit_before>export default (assetData) => ({
    Attributes: reduceAssetData(assetData)
});

const reduceAssetData = (obj) => Object.keys(obj)
    .reduce((output, key) => {
        const attributeData = obj[key];
        if (Array.isArray(attributeData)) {
            return {
                ...output,
                [key]: {
                    name: key,
                    value: attributeData.map(reduceRelationalAttributes),
                    act: 'set'
                }
            };
        }
        if (isFunction(attributeData)) {
            return {
                ...output,
                [key]: {
                    value: obj[key](),
                    act: 'set'
                }
            };
        }
        return {
            ...output,
            [key]: {
                value: obj[key],
                act: 'set'
            }
        };
    }, {});

const reduceRelationalAttributes = (obj) => {
    if (typeof obj === 'string') {
        return {
            idref: obj,
            act: 'add'
        };
    }
    return Object.keys(obj).reduce((output, key)=> {
        output.idref = obj[key];
        output.act = obj.act ? obj.act : 'add';
        return output;
    }, {});
};

const isFunction = (obj) => obj && obj.constructor && obj.call && obj.apply;
<commit_msg>When the attribute is multivalue, then don't add the act of set. Each value in the list is an object that has an act property indicating either add or remove.<commit_after>export default (assetData) => ({
    Attributes: reduceAssetData(assetData)
});

const reduceAssetData = (obj) => Object.keys(obj)
    .reduce((output, key) => {
        const attributeData = obj[key];
        if (Array.isArray(attributeData)) {
            return {
                ...output,
                [key]: {
                    name: key,
                    value: attributeData.map(reduceRelationalAttributes)
                }
            };
        }
        if (isFunction(attributeData)) {
            return {
                ...output,
                [key]: {
                    value: obj[key](),
                    act: 'set'
                }
            };
        }
        return {
            ...output,
            [key]: {
                value: obj[key],
                act: 'set'
            }
        };
    }, {});

const reduceRelationalAttributes = (obj) => {
    if (typeof obj === 'string') {
        return {
            idref: obj,
            act: 'add'
        };
    }
    return Object.keys(obj).reduce((output, key)=> {
        output.idref = obj[key];
        output.act = obj.act ? obj.act : 'add';
        return output;
    }, {});
};

const isFunction = (obj) => obj && obj.constructor && obj.call && obj.apply;
<|endoftext|>


<commit_before>/*:
 * @plugindesc <ActionEnemiesShakeEffect>
 * @author biud436
 * @help
 * EVAL: BattleManager.actionEnemiesShakeEffect(["enemy 0", "enemy 1", "enemy 2"], 15);
 */

var Imported = Imported || {};
Imported.ActionEnemiesShakeEffect = true;

(function () {

    if(!Imported.YEP_BattleEngineCore) return;
    if(!Imported.YEP_X_ActSeqPack1) return;
    if(!Imported.YEP_X_ActSeqPack2) return;

    BattleManager.actionTargetShakeEffect = function (target, offset) {
        "use strict";

        var actionArgs1 = `${target}, base, 3, auto offset x +${offset}`.split(", ");
        var actionArgs2 = `${target}, base, 3, auto offset x -${offset}`.split(", ");

        for(var i = 0; i < 3; i++) {
            this.actionMove(target, actionArgs1);
            this.actionWait(3);
            this.actionMove(target, actionArgs2);
            this.actionWait(3);
        }
    };

    BattleManager.actionEnemiesShakeEffect = function (targets, offset) {
        targets.forEach(function(target) {
            BattleManager.actionTargetShakeEffect(target, offset);
        });
    };

})();
<commit_msg>Remove addon<commit_after><|endoftext|>


<commit_before>var ctx, color = "#000";

var theTop;
var theLeft;
var theWidth;
var aspectRatio = 0.30;
var theBorders = 50;

$(document).ready(function () {
  setTimeout(function(){
    if (!isCanvasSupported()){
      post({'success': 0});
    }
    newCanvas();
  }, 1000);

  $(".palette").click(function(){
    $(".palette").css("border-color", "#777");
    $(".palette").css("border-style", "solid");
    $(this).css("border-color", "#fff");
    $(this).css("border-style", "dashed");
    color = $(this).css("background-color");
    ctx.beginPath();
    ctx.lineJoin="round";
    ctx.strokeStyle = color;
  });
  $("#new").click(function() {
    newCanvas();
  });
  $("#save").click(function() {
    saveCanvas();
  });
  window.scrollTo(0,1);
});

// function to setup a new canvas for drawing

function resizeCanvas(){
  //var cheight = $(window).height()-($("#header").height() + $("#toppart").height() + $("#bottompart").height());
  newCanvas();
  //console.log("I resized");
  return;
  var cheight = $(window).width()*aspectRatio;
  if (cheight > $(window).height()-theTop){
    cheight = $(window).height()-theTop;
  }
  if (cheight > 350){
    cheight = 350;
  }
  var cwidth = $(window).width() - theBorders;

  $("#content").height(cheight);
  //$("#content").css('top', ($("#header").height() + $("#toppart").height()) + "px");
  //$("#bottompart").css('top', (cheight) + "px");
  $("#canvas").width(cwidth);
  $("#canvas").height(cheight);
  theTop = $("#canvas").offset().top;
  theLeft = $("#canvas").offset().left;
  theWidth = cwidth/100.0;
  if (theWidth < 1){
    theWidth = 1;
  }
  return;
}

function saveCanvas(){
  var dataURL = document.getElementById("canvas").toDataURL();
  //console.log(dataURL)
  post({'success': 1, 'theImage': dataURL});
}

function newCanvas(){
  //define and resize canvas
  //var cheight = $(window).height()-($("#header").height() + $("#toppart").height() + $("#bottompart").height());
  var cheight = $(window).width()*aspectRatio;
  if (cheight > $(window).height()-theTop){
    cheight = $(window).height()-theTop;
  }
  if (cheight > 350){
    cheight = 350;
  }
  var cwidth = $(window).width() - theBorders;
  $("#content").height(cheight);
  //$("#bottompart").css('top', (cheight) + "px");
  //$("#content").css('top', ($("#header").height() + $("#toppart").height()) + "px");
  //$("#content").css('bottom', ($("#bottompart").height()) + "px");
  var canvas = '<canvas id="canvas" width="'+(cwidth)+'px" height="'+(cheight)+'px"></canvas>';
  $("#content").html(canvas);
  theTop = $("#canvas").offset().top;
  theLeft = $("#canvas").offset().left;
  theWidth = cwidth/100.0;
  if (theWidth < 1){
    theWidth = 1;
  }

  // setup canvas
  ctx=document.getElementById("canvas").getContext("2d");
  ctx.strokeStyle = color;
  ctx.lineWidth = theWidth;

  // setup to trigger drawing on mouse or touch
  $("#canvas").drawTouch();
  $("#canvas").drawPointer();
  $("#canvas").drawMouse();
  //$(document).on("touchend", function(event){event.preventDefault();});
  //$(document).on("touchcancel", function(event){event.preventDefault();});
  //$(document).on("touchstart", function(event){event.preventDefault();});
  $(document).on("touchmove", function(event){event.preventDefault();});
}

// prototype to	start drawing on touch using canvas moveTo and lineTo
$.fn.drawTouch = function() {
  var start = function(e) {
    e = e.originalEvent;
    ctx.beginPath();
    ctx.lineJoin="round";
    x = e.changedTouches[0].pageX-theLeft;
    y = e.changedTouches[0].pageY-theTop;
    ctx.moveTo(x,y);
  };
  var move = function(e) {
    e.preventDefault();
    e = e.originalEvent;
    x = e.changedTouches[0].pageX-theLeft;
    y = e.changedTouches[0].pageY-theTop;
    ctx.lineTo(x,y);
    ctx.stroke();
  };
  var dot = function(e) {
    e.preventDefault();
    e = e.originalEvent;
    ctx.beginPath();
    ctx.lineJoin="round";
    x = e.pageX-theLeft;
    y = e.pageY-theTop;
    ctx.fillRect(x-0.5*theWidth,y-0.5*theWidth,theWidth,theWidth);
    //console.log("Got click");
  };
  $(this).on("click", dot);
  $(this).on("touchend", move);
  $(this).on("touchcancel", move);
  $(this).on("touchstart", start);
  $(this).on("touchmove", move);
};

// prototype to	start drawing on pointer(microsoft ie) using canvas moveTo and lineTo
$.fn.drawPointer = function() {
  var start = function(e) {
    e = e.originalEvent;
    ctx.beginPath();
    ctx.lineJoin="round";
    x = e.pageX-theLeft;
    y = e.pageY-theTop;
    ctx.moveTo(x,y);
  };
  var move = function(e) {
    e.preventDefault();
    e = e.originalEvent;
    x = e.pageX-theLeft;
    y = e.pageY-theTop;
    ctx.lineTo(x,y);
    ctx.stroke();
  };
  $(this).on("MSPointerDown", start);
  $(this).on("MSPointerMove", move);
  $(this).on("MSPointerUp", move);
};

// prototype to	start drawing on mouse using canvas moveTo and lineTo
$.fn.drawMouse = function() {
  var clicked = 0;
  var start = function(e) {
    clicked = 1;
    ctx.beginPath();
    ctx.lineJoin="round";
    x = e.pageX-theLeft;
    y = e.pageY-theTop;
    ctx.moveTo(x,y);
  };
  var move = function(e) {
    if(clicked){
      x = e.pageX-theLeft;
      y = e.pageY-theTop;
      ctx.lineTo(x,y);
      ctx.stroke();
    }
  };
  var stop = function(e) {
    clicked = 0;
  };
  $(this).on("mousedown", start);
  $(this).on("mousemove", move);
  $(window).on("mouseup", stop);
};

function post(params) {
  for(var key in params) {
    if(params.hasOwnProperty(key)) {
      var hiddenField = document.getElementById(key);
      if (hiddenField != null){
	hiddenField.setAttribute("value", params[key]);
      }
      else{
	console.log("Key does not exist: " + key);
	return;
      }
    }
  }
  $('#imageSubmit').submit();
  return;
}

function isCanvasSupported(){
  var elem = document.createElement('canvas');
  return !!(elem.getContext && elem.getContext('2d'));
}

<commit_msg>signature touch fix<commit_after>var ctx, color = "#000";

var theTop;
var theLeft;
var theWidth;
var aspectRatio = 0.30;
var theBorders = 50;

$(document).ready(function () {
  setTimeout(function(){
    if (!isCanvasSupported()){
      post({'success': 0});
    }
    newCanvas();
  }, 1000);

  $(".palette").click(function(){
    $(".palette").css("border-color", "#777");
    $(".palette").css("border-style", "solid");
    $(this).css("border-color", "#fff");
    $(this).css("border-style", "dashed");
    color = $(this).css("background-color");
    ctx.beginPath();
    ctx.lineJoin="round";
    ctx.strokeStyle = color;
  });
  $("#new").click(function() {
    newCanvas();
  });
  $("#save").click(function() {
    saveCanvas();
  });
  window.scrollTo(0,1);
});

// function to setup a new canvas for drawing

function resizeCanvas(){
  //var cheight = $(window).height()-($("#header").height() + $("#toppart").height() + $("#bottompart").height());
  newCanvas();
  //console.log("I resized");
  return;
  var cheight = $(window).width()*aspectRatio;
  if (cheight > $(window).height()-theTop){
    cheight = $(window).height()-theTop;
  }
  if (cheight > 350){
    cheight = 350;
  }
  var cwidth = $(window).width() - theBorders;

  $("#content").height(cheight);
  //$("#content").css('top', ($("#header").height() + $("#toppart").height()) + "px");
  //$("#bottompart").css('top', (cheight) + "px");
  $("#canvas").width(cwidth);
  $("#canvas").height(cheight);
  theTop = $("#canvas").offset().top;
  theLeft = $("#canvas").offset().left;
  theWidth = cwidth/100.0;
  if (theWidth < 1){
    theWidth = 1;
  }
  return;
}

function saveCanvas(){
  var dataURL = document.getElementById("canvas").toDataURL();
  //console.log(dataURL)
  post({'success': 1, 'theImage': dataURL});
}

function newCanvas(){
  //define and resize canvas
  //var cheight = $(window).height()-($("#header").height() + $("#toppart").height() + $("#bottompart").height());
  var cheight = $(window).width()*aspectRatio;
  if (cheight > $(window).height()-theTop){
    cheight = $(window).height()-theTop;
  }
  if (cheight > 350){
    cheight = 350;
  }
  var cwidth = $(window).width() - theBorders;
  $("#content").height(cheight);
  //$("#bottompart").css('top', (cheight) + "px");
  //$("#content").css('top', ($("#header").height() + $("#toppart").height()) + "px");
  //$("#content").css('bottom', ($("#bottompart").height()) + "px");
  var canvas = '<canvas id="canvas" width="'+(cwidth)+'px" height="'+(cheight)+'px"></canvas>';
  $("#content").html(canvas);
  theTop = $("#canvas").offset().top;
  theLeft = $("#canvas").offset().left;
  theWidth = cwidth/100.0;
  if (theWidth < 1){
    theWidth = 1;
  }

  // setup canvas
  ctx=document.getElementById("canvas").getContext("2d");
  ctx.strokeStyle = color;
  ctx.lineWidth = theWidth;

  // setup to trigger drawing on mouse or touch
  $("#canvas").drawTouch();
  $("#canvas").drawPointer();
  $("#canvas").drawMouse();
  //$(document).on("touchend", function(event){event.preventDefault();});
  //$(document).on("touchcancel", function(event){event.preventDefault();});
  //$(document).on("touchstart", function(event){event.preventDefault();});
  $(document).on("touchmove", function(event){event.preventDefault();});
}

// prototype to	start drawing on touch using canvas moveTo and lineTo
$.fn.drawTouch = function() {
  var start = function(e) {
    e = e.originalEvent;
    ctx.beginPath();
    ctx.lineJoin="round";
    x = e.changedTouches[0].pageX-theLeft;
    y = e.changedTouches[0].pageY-theTop;
    ctx.moveTo(x,y);
  };
  var move = function(e) {
    e.preventDefault();
    e = e.originalEvent;
    x = e.changedTouches[0].pageX-theLeft;
    y = e.changedTouches[0].pageY-theTop;
    ctx.lineTo(x,y);
    ctx.stroke();
    ctx.fillRect(x-0.5*theWidth,y-0.5*theWidth,theWidth,theWidth);
  };
  var dot = function(e) {
    e.preventDefault();
    e = e.originalEvent;
    ctx.beginPath();
    ctx.lineJoin="round";
    x = e.pageX-theLeft;
    y = e.pageY-theTop;
    ctx.fillRect(x-0.5*theWidth,y-0.5*theWidth,theWidth,theWidth);
    //console.log("Got click");
  };
  $(this).on("click", dot);
  $(this).on("touchend", move);
  $(this).on("touchcancel", move);
  $(this).on("touchstart", start);
  $(this).on("touchmove", move);
};

// prototype to	start drawing on pointer(microsoft ie) using canvas moveTo and lineTo
$.fn.drawPointer = function() {
  var start = function(e) {
    e = e.originalEvent;
    ctx.beginPath();
    ctx.lineJoin="round";
    x = e.pageX-theLeft;
    y = e.pageY-theTop;
    ctx.moveTo(x,y);
  };
  var move = function(e) {
    e.preventDefault();
    e = e.originalEvent;
    x = e.pageX-theLeft;
    y = e.pageY-theTop;
    ctx.lineTo(x,y);
    ctx.stroke();
  };
  $(this).on("MSPointerDown", start);
  $(this).on("MSPointerMove", move);
  $(this).on("MSPointerUp", move);
};

// prototype to	start drawing on mouse using canvas moveTo and lineTo
$.fn.drawMouse = function() {
  var clicked = 0;
  var start = function(e) {
    clicked = 1;
    ctx.beginPath();
    ctx.lineJoin="round";
    x = e.pageX-theLeft;
    y = e.pageY-theTop;
    ctx.moveTo(x,y);
  };
  var move = function(e) {
    if(clicked){
      x = e.pageX-theLeft;
      y = e.pageY-theTop;
      ctx.lineTo(x,y);
      ctx.stroke();
    }
  };
  var stop = function(e) {
    clicked = 0;
  };
  $(this).on("mousedown", start);
  $(this).on("mousemove", move);
  $(window).on("mouseup", stop);
};

function post(params) {
  for(var key in params) {
    if(params.hasOwnProperty(key)) {
      var hiddenField = document.getElementById(key);
      if (hiddenField != null){
	hiddenField.setAttribute("value", params[key]);
      }
      else{
	console.log("Key does not exist: " + key);
	return;
      }
    }
  }
  $('#imageSubmit').submit();
  return;
}

function isCanvasSupported(){
  var elem = document.createElement('canvas');
  return !!(elem.getContext && elem.getContext('2d'));
}

<|endoftext|>


<commit_before>// ==UserScript==
// @name       Tumblr Big Post
// @namespace  https://github.com/AndersDJohnson/
// @version    0.1.3
// @description Big post dialog for Tumblr.
// @autor      AndersDJohnson
// @require    http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
// @require    http://rawgit.com/Box9/jss/master/jss.min.js
// @match      http://*.tumblr.com/*
// @author     Anders D. Johnson
// @copyright  2014+, Anders D. Johnson
// ==/UserScript==

(function () {

    var waitFor = function (selector, time, callback) {
        var $match = $(selector);
        if ($match.length) {
            return callback($match);
        }
        setTimeout(function () {
            waitFor(selector, time, callback);
        }, time);
    };

    var checkForEditor = function () {
        waitFor('#new_post.active', 100, function ($new_post) {
            if (! $new_post.has('[data-post-type="regular"]:visible').length) {
            	$new_post.removeClass('data-post-type-regular');
                jss.remove('#post_two_ifr');
                return;
            }
            $new_post.addClass('data-post-type-regular');
            var $post_two_ifr = $('#post_two_ifr');
            if (! $post_two_ifr.length) {
                return setTimeout(checkForEditor, 1000);
            }
            var windowHeight = $(window).height();
            var dialogHeight = $new_post.height();
            var initialHeight = $post_two_ifr.height();
            var fixedHeight = dialogHeight - initialHeight;
            var fluidHeight = windowHeight - fixedHeight;
            var height = fluidHeight * 0.8;
        	jss.set('#post_two_ifr', {
                height: height + 'px !important'
            });
        });
    };

    var start = function (label) {
        //console.log('tumblr-big-post: check | ' + label + ' | ' + new Date());
        jss.set('#new_post.editing.active.data-post-type-regular', {
            position: 'absolute !important',
            width: '90% !important',
            left: '5% !important',
            top: '20px !important'
        });

        var $new_post = $('#new_post');
        $new_post.on('click', function () {
            checkForEditor();
        });

        checkForEditor();
    };

    $(function () {
    	start();
    });

})();
<commit_msg>fix author in user script header<commit_after>// ==UserScript==
// @name       Tumblr Big Post
// @namespace  https://github.com/AndersDJohnson/
// @version    0.1.3
// @description Big post dialog for Tumblr.
// @author     Anders D. Johnson
// @require    http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
// @require    http://rawgit.com/Box9/jss/master/jss.min.js
// @match      http://*.tumblr.com/*
// @copyright  2014+, Anders D. Johnson
// ==/UserScript==

(function () {

    var waitFor = function (selector, time, callback) {
        var $match = $(selector);
        if ($match.length) {
            return callback($match);
        }
        setTimeout(function () {
            waitFor(selector, time, callback);
        }, time);
    };

    var checkForEditor = function () {
        waitFor('#new_post.active', 100, function ($new_post) {
            if (! $new_post.has('[data-post-type="regular"]:visible').length) {
            	$new_post.removeClass('data-post-type-regular');
                jss.remove('#post_two_ifr');
                return;
            }
            $new_post.addClass('data-post-type-regular');
            var $post_two_ifr = $('#post_two_ifr');
            if (! $post_two_ifr.length) {
                return setTimeout(checkForEditor, 1000);
            }
            var windowHeight = $(window).height();
            var dialogHeight = $new_post.height();
            var initialHeight = $post_two_ifr.height();
            var fixedHeight = dialogHeight - initialHeight;
            var fluidHeight = windowHeight - fixedHeight;
            var height = fluidHeight * 0.8;
        	jss.set('#post_two_ifr', {
                height: height + 'px !important'
            });
        });
    };

    var start = function (label) {
        //console.log('tumblr-big-post: check | ' + label + ' | ' + new Date());
        jss.set('#new_post.editing.active.data-post-type-regular', {
            position: 'absolute !important',
            width: '90% !important',
            left: '5% !important',
            top: '20px !important'
        });

        var $new_post = $('#new_post');
        $new_post.on('click', function () {
            checkForEditor();
        });

        checkForEditor();
    };

    $(function () {
    	start();
    });

})();
<|endoftext|>


<commit_before>// http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/
const attachEvent = document['attachEvent'];
const isIe = navigator.userAgent.match(/Trident/);

const RESIZE_LISTENERS_KEY = '__RESIZE_LISTENERS__';
const RESIZE_TRIGGER_KEY = '__RESIZE_TRIGGER__';
const RESIZE_ELEMENT_KEY = '__RESIZE_ELEMENT__';

const resizeListener = event => {
	const win = event.target || event.srcElement;
	if (win.__resizeRAF__) {
		cancelAnimationFrame(win.__resizeRAF__);
	}
	win.__resizeRAF__ = requestAnimationFrame(() => {
		const trigger = win.__resizeTrigger__;
		trigger[RESIZE_LISTENERS_KEY].forEach(fn => fn.call(trigger, event));
	});
};

/**
 * Remove resize listiner from elements.
 * @param {HTMLElement} element
 * @param {Function} fn
 */
function removeResizeListener(element, fn) {
	element[RESIZE_LISTENERS_KEY].splice(element[RESIZE_LISTENERS_KEY].indexOf(fn), 1);
	if (!element[RESIZE_LISTENERS_KEY].length) {
		if (attachEvent) {
			element['detachEvent']('onresize', resizeListener);
		} else {
			if (element[RESIZE_LISTENERS_KEY].contentDocument) {
				element[RESIZE_LISTENERS_KEY].contentDocument.defaultView.removeEventListener('resize', resizeListener);
				element[RESIZE_LISTENERS_KEY] = !element.removeChild(element[RESIZE_TRIGGER_KEY]);
			}
		}
	}
}

/**
 * Add listening to resize events on the elements. Calls the event callback for each event for each element.
 * @param {HTMLElement} element
 * @param {Function} fn
 * @returns {Function} clearer function, removing resize listiner
 */
export function addResizeListener(element, fn) {
	if (!element[RESIZE_LISTENERS_KEY]) {
		element[RESIZE_LISTENERS_KEY] = [];
		if (attachEvent) {
			element[RESIZE_TRIGGER_KEY] = element;
			element['attachEvent']('onresize', resizeListener);
		} else {
			if (getComputedStyle(element).position === 'static') {
				element.style.position = 'relative';
			}
			const obj = element[RESIZE_TRIGGER_KEY] = document.createElement('object');
			obj.setAttribute('style', `display: block;
				position: absolute;
				top: 0;
				left: 0;
				height: 100%;
				width: 100%;
				overflow: hidden;
				pointer-events: none;
				z-index: -1;`
			);
			obj[RESIZE_ELEMENT_KEY] = element;
			obj.onload = (event) => {
				const {target} = event;
				target.contentDocument.defaultView.__resizeTrigger__ = target[RESIZE_ELEMENT_KEY];
				target.contentDocument.defaultView.addEventListener('resize', resizeListener);
			};
			obj.type = 'text/html';
			if (isIe) {
				element.appendChild(obj);
			}
			obj.data = 'about:blank';
			if (!isIe) {
				element.appendChild(obj);
			}
		}
	}
	element[RESIZE_LISTENERS_KEY].push(fn);

	return () => removeResizeListener(element, fn);
}
<commit_msg>remove old file<commit_after><|endoftext|>