<commit_before>'use strict';

/**
 * @file
 * Creates a list of tokens
 *
 * This component is only used internally for the TokenSearchField
 *
 * Properties:
 * query: array of strings
 * remove: callback function for removing elements with a certain index
 *
 */

import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';
import Token from './Token.component.js';

/**
 * Get a random color. This function is used for development only.
 * Should be exchanged with a colorscheme
 *
 * @returns {string}
 * @private
 */
function _getRandomColor() {
  var letters = '0123456789ABCDEF'.split('');
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

/**
 * Return a color depending on the type
 *
 * @param type
 * @returns {*}
 */
function getColor(type) {
  switch (type) {
    case 'text':
      return '#222';
    default:
      return '#61b6d9';
  }
}

export default React.createClass({
  displayName: 'TokenList.component',
  propTypes: {
    hasFocus: PropTypes.bool,
    setFocus: PropTypes.func,
    query: PropTypes.array.isRequired,
    remove: PropTypes.func.isRequired,
    translations: PropTypes.object
  },

  getInitialState() {
    let queries = this.props.query.map((query)=> {
      return {
        text: query,
        color: _getRandomColor()
      };
    });
    return {
      query: queries
    };
  },
  getTranslation(type, text) {
    if (this.props.translations && type !== 'text' && this.props.translations[text]) {
      return this.props.translations[text];
    }

    return text;
  },

  replaceAll(str, find, replace) {
    return str.replace(new RegExp(find, 'g'), replace);
  },

  getListWidth(tokens) {
    const padding = 4;
    const emptySpace = 75;
    return tokens
        .map(element => element && ReactDOM.findDOMNode(element).offsetWidth)
        .reduce((sum, width) => sum + width + padding) + emptySpace;
  },

  scrollToEnd(scrollWrapper) {
    ReactDOM.findDOMNode(scrollWrapper).scrollLeft = 10000;
  },

  containsClass(className, list) {
    return Array.prototype.filter.call(list, (listClassName) => className === listClassName).length && true || false;
  },

  onEventListClick(event) {
    if (this.containsClass('tokenlist', event.target.classList) && this.props.setFocus) {
      this.props.setFocus(true);
    }
  },

  updateListWidth(listWidth) {
    if (listWidth !== this.state.listWidth) {
      this.setState({listWidth});
    }
  },

  componentDidUpdate() {
    this.scrollToEnd(this.refs.tokenList);
    this.updateListWidth(this.getListWidth(this._tokens));
  },

  componentDidMount() {
    this.scrollToEnd(this.refs.tokenList);
  },

  render() {
    // _tokens contains a list of Token Components.
    this._tokens = [];
    const {query, remove} = this.props;
    const tokenClasses = !this.props.hasFocus && 'tokens-wrapper' || 'tokens-wrapper hide';

    const tokens = query.map((element, index)=> {
      return (
        <Token
          ref={component => this._tokens.push(component)}
          color={getColor(element.type)}
          index={element.index}
          key={index}
          remove={remove.bind(null, element)}
          text={this.getTranslation(element.type, this.replaceAll(element.value.toString(), ',', ' eller '))}
          />
      );
    });

    return (

 this.onEventListClick(event)}
          >
          {tokens}

    );
  }
});
<commit_msg>Accumulated commit of the following from branch 'origin/ready/svi-scroll-tokenlist':<commit_after>'use strict';

/**
 * @file
 * Creates a list of tokens
 *
 * This component is only used internally for the TokenSearchField
 *
 * Properties:
 * query: array of strings
 * remove: callback function for removing elements with a certain index
 *
 */

import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';
import Token from './Token.component.js';

/**
 * Get a random color. This function is used for development only.
 * Should be exchanged with a colorscheme
 *
 * @returns {string}
 * @private
 */
function _getRandomColor() {
  var letters = '0123456789ABCDEF'.split('');
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

/**
 * Return a color depending on the type
 *
 * @param type
 * @returns {*}
 */
function getColor(type) {
  switch (type) {
    case 'text':
      return '#222';
    default:
      return '#61b6d9';
  }
}

export default React.createClass({
  displayName: 'TokenList.component',
  propTypes: {
    hasFocus: PropTypes.bool,
    setFocus: PropTypes.func,
    query: PropTypes.array.isRequired,
    remove: PropTypes.func.isRequired,
    translations: PropTypes.object
  },

  getInitialState() {
    let queries = this.props.query.map((query)=> {
      return {
        text: query,
        color: _getRandomColor()
      };
    });
    return {
      query: queries
    };
  },
  getTranslation(type, text) {
    if (this.props.translations && type !== 'text' && this.props.translations[text]) {
      return this.props.translations[text];
    }

    return text;
  },

  replaceAll(str, find, replace) {
    return str.replace(new RegExp(find, 'g'), replace);
  },

  getListWidth(tokens) {
    if (!tokens.length) {
      return 0;
    }
    const padding = 4;
    const emptySpace = 75;
    return tokens
        .map(element => element && ReactDOM.findDOMNode(element).offsetWidth)
        .reduce((sum, width) => sum + width + padding) + emptySpace;
  },

  scrollToEnd(scrollWrapper) {
    ReactDOM.findDOMNode(scrollWrapper).scrollLeft = 10000;
  },

  containsClass(className, list) {
    return Array.prototype.filter.call(list, (listClassName) => className === listClassName).length && true || false;
  },

  onEventListClick(event) {
    if (this.containsClass('tokenlist', event.target.classList) && this.props.setFocus) {
      this.props.setFocus(true);
    }
  },

  updateListWidth(listWidth) {
    if (listWidth !== this.state.listWidth) {
      this.setState({listWidth});
    }
  },

  componentDidUpdate() {
    this.scrollToEnd(this.refs.tokenList);
    this.updateListWidth(this.getListWidth(this._tokens));
  },

  componentDidMount() {
    this.scrollToEnd(this.refs.tokenList);
  },

  render() {
    // _tokens contains a list of Token Components.
    this._tokens = [];
    const {query, remove} = this.props;
    const tokenClasses = !this.props.hasFocus && 'tokens-wrapper' || 'tokens-wrapper hide';

    const tokens = query.map((element, index)=> {
      return (
        <Token
          ref={component => this._tokens.push(component)}
          color={getColor(element.type)}
          index={element.index}
          key={index}
          remove={remove.bind(null, element)}
          text={this.getTranslation(element.type, this.replaceAll(element.value.toString(), ',', ' eller '))}
          />
      );
    });

    return (

 this.onEventListClick(event)}
          >
          {tokens}

    );
  }
});
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import autobind from 'core-decorators/es/autobind';
import FormInput from '../../../../../../lib/react/components/forms/FormInput';
import UsersFilter from './UsersFilter';
import Search from '../../components/Search';

import '../../scss/components/_summary-panel.scss';

@autobind
class UserSummary extends React.Component {
	static propTypes = {
		displayCount: PropTypes.number.isRequired,
		displayPaidCount: PropTypes.number.isRequired,
		onSearchChange: PropTypes.func.isRequired,
		searchValue: PropTypes.string.isRequired,
		onFilterChange: PropTypes.func.isRequired,
		filterValue: PropTypes.string.isRequired
	}

	onSearchChange(e) {
		this.props.onSearchChange(e.target.value);
	}

	onFilterChange(e) {
		this.props.onFilterChange(e.target.value);
	}

	render() {
		let intent = 'pt-intent-danger';
		if (this.props.displayPaidCount === this.props.displayCount) intent = 'pt-intent-success';

		return (

				{this.props.displayPaidCount} out of {this.props.displayCount} users have paid.

					<UsersFilter value={this.props.filterValue} onChange={this.onFilterChange}/>
					<Search value={this.props.searchValue} onChange={this.onSearchChange}/>

		);
	}
}

export default UserSummary;
<commit_msg>[ADD] Improve users summary description<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import autobind from 'core-decorators/es/autobind';
import FormInput from '../../../../../../lib/react/components/forms/FormInput';
import UsersFilter from './UsersFilter';
import Search from '../../components/Search';

import '../../scss/components/_summary-panel.scss';

@autobind
class UserSummary extends React.Component {
	static propTypes = {
		displayCount: PropTypes.number.isRequired,
		displayPaidCount: PropTypes.number.isRequired,
		onSearchChange: PropTypes.func.isRequired,
		searchValue: PropTypes.string.isRequired,
		onFilterChange: PropTypes.func.isRequired,
		filterValue: PropTypes.string.isRequired
	}

	onSearchChange(e) {
		this.props.onSearchChange(e.target.value);
	}

	onFilterChange(e) {
		this.props.onFilterChange(e.target.value);
	}

	render() {
		const { displayPaidCount, displayCount, filterValue, searchValue } = this.props;
		const descriptor = filterValue!=='all' || searchValue ? ' shown ' : ' total ';
		let intent = 'pt-intent-danger';

		if (displayPaidCount === displayCount) intent = 'pt-intent-success';

		return (

				{displayPaidCount} out of {displayCount}{descriptor}users have paid.

					<UsersFilter value={filterValue} onChange={this.onFilterChange}/>
					<Search value={searchValue} onChange={this.onSearchChange}/>

		);
	}
}

export default UserSummary;
<|endoftext|>


<commit_before>var VUELOG_DATABASE = {

  // DO NOT touch this part
  system: {
    name: 'Vuelog',
    description: 'A backend-free blog system built on top of Vue.js',
    version: '0.3.0',
    project: 'https://github.com/myst729/Vuelog',
    release: 'https://github.com/myst729/Vuelog/releases',
    logo: './static/img/logo.svg',
    author: 'Leo Deng'
  },

  // Edit your site from here
  deployment: {
    title: 'Vuelog',
    url: 'https://myst729.github.io/Vuelog/',
    logo: './static/img/logo.svg',
    folder: './docs',
    perPage: 2,
    displayTime: 'YYYY-MM-DD', // 'YYYY', 'YYYY-MM', or 'YYYY-MM-DD'
    routeTime: 'YYYY', // 'YYYY', 'YYYY-MM', or 'YYYY-MM-DD', DO NOT include '/'
    useHomepage: true
  },

  // Search functionality is served with Algolia
  search: {
    enable: true,
    appId: '',
    apiKey: '',
    indexName: '',
    displayKey: ''
  },

  navigation: [
    {
      label: 'Blog',
      type: 'blog',
      path: '/blog'
    },
    {
      label: 'Archive',
      type: 'archive',
      path: '/archive'
    },
    {
      label: 'Talk Is Cheap',
      type: 'page',
      path: '/page/talk-is-cheap'
    },
    {
      label: 'Links',
      type: 'dropdown',
      children: [
        {
          label: 'Weibo',
          type: 'outgoing',
          link: 'http://weibo.com/myst729'
        },
        {
          label: 'GitHub',
          type: 'outgoing',
          link: 'https://github.com/myst729'
        },
        {
          label: 'StackOverflow',
          type: 'outgoing',
          link: 'https://stackoverflow.com/users/1032492'
        }
      ]
    }
  ],

  pages: [
    {
      title: 'Talk Is Cheap',
      slug: 'talk-is-cheap'
    }
  ],

  categories: [
    {
      title: 'Chandeen',
      slug: 'chandeen'
    },
    {
      title: 'Lorem Ipsum',
      slug: 'lorem-ipsum'
    }
  ],

  posts: [
    {
      title: 'Lorem Ipsum Samples',
      slug: 'lorem-ipsum-samples',
      category: 'lorem-ipsum',
      date: 20160116
    },
    {
      title: 'Lorem Ipsum on Wikipedia',
      slug: 'lorem-ipsum-on-wikipedia',
      category: 'lorem-ipsum',
      date: 20150214
    },
    {
      title: 'Lorem Ipsum Demystified',
      slug: 'lorem-ipsum-demystified',
      category: 'lorem-ipsum',
      date: 20150212
    },
    {
      title: 'Chandeen on Wikipedia',
      slug: 'chandeen-on-wikipedia',
      category: 'chandeen',
      date: 20120214
    }
  ]

}
<commit_msg>update version number<commit_after>var VUELOG_DATABASE = {

  // DO NOT touch this part
  system: {
    name: 'Vuelog',
    description: 'A backend-free blog system built on top of Vue.js',
    version: '0.3.1',
    project: 'https://github.com/myst729/Vuelog',
    release: 'https://github.com/myst729/Vuelog/releases',
    logo: './static/img/logo.svg',
    author: 'Leo Deng'
  },

  // Edit your site from here
  deployment: {
    title: 'Vuelog',
    url: 'https://myst729.github.io/Vuelog/',
    logo: './static/img/logo.svg',
    folder: './docs',
    perPage: 2,
    displayTime: 'YYYY-MM-DD', // 'YYYY', 'YYYY-MM', or 'YYYY-MM-DD'
    routeTime: 'YYYY', // 'YYYY', 'YYYY-MM', or 'YYYY-MM-DD', DO NOT include '/'
    useHomepage: true
  },

  // Search functionality is served with Algolia
  search: {
    enable: true,
    appId: '',
    apiKey: '',
    indexName: '',
    displayKey: ''
  },

  navigation: [
    {
      label: 'Blog',
      type: 'blog',
      path: '/blog'
    },
    {
      label: 'Archive',
      type: 'archive',
      path: '/archive'
    },
    {
      label: 'Talk Is Cheap',
      type: 'page',
      path: '/page/talk-is-cheap'
    },
    {
      label: 'Links',
      type: 'dropdown',
      children: [
        {
          label: 'Weibo',
          type: 'outgoing',
          link: 'http://weibo.com/myst729'
        },
        {
          label: 'GitHub',
          type: 'outgoing',
          link: 'https://github.com/myst729'
        },
        {
          label: 'StackOverflow',
          type: 'outgoing',
          link: 'https://stackoverflow.com/users/1032492'
        }
      ]
    }
  ],

  pages: [
    {
      title: 'Talk Is Cheap',
      slug: 'talk-is-cheap'
    }
  ],

  categories: [
    {
      title: 'Chandeen',
      slug: 'chandeen'
    },
    {
      title: 'Lorem Ipsum',
      slug: 'lorem-ipsum'
    }
  ],

  posts: [
    {
      title: 'Lorem Ipsum Samples',
      slug: 'lorem-ipsum-samples',
      category: 'lorem-ipsum',
      date: 20160116
    },
    {
      title: 'Lorem Ipsum on Wikipedia',
      slug: 'lorem-ipsum-on-wikipedia',
      category: 'lorem-ipsum',
      date: 20150214
    },
    {
      title: 'Lorem Ipsum Demystified',
      slug: 'lorem-ipsum-demystified',
      category: 'lorem-ipsum',
      date: 20150212
    },
    {
      title: 'Chandeen on Wikipedia',
      slug: 'chandeen-on-wikipedia',
      category: 'chandeen',
      date: 20120214
    }
  ]

}
<|endoftext|>


<commit_before>(function($) {

    'use strict';

    /*
     * jquery.closestchild 0.1.1
     *
     * Author: Andrey Mikhaylov aka lolmaus
     * Email: lolmaus@gmail.com
     *
     */
    $.fn.closestChild = function(selector) {
        var $children, $results;

        $children = this.children();

        if ($children.length === 0) {
            return $();
        }

        $results = $children.filter(selector);

        if ($results.length > 0) {
            return $results;
        } else {
            return $children.closestChild(selector);
        }
    };

    var instance = 0;

    $.fn.tabtab = function(options) {

        /*
         * Plugin default options
         */
        var settings = $.extend({
            tabMenu: '.tabs__menu',             // direct container of the tab menu items
            tabContent: '.tabs__content',       // direct container of the tab content items
            next: '.tabs-controls__next',       // next slide trigger
            prev: '.tabs-controls__prev',       // previous slide trigger

            startSlide: 2,                      // starting slide on pageload
            arrows: true,                       // keyboard arrow navigation
            animateHeight: true,                // if true the height will dynamic and animated.
            fixedHeight: true,                  // if set to true the container will use the heighest height.
            useAnimations: true,                // disables animations.

            easing: [200, 20],                  // http://julian.com/research/velocity/#easing
            speed: 700,                         // animation speed
            slideDelay: 0,                      // delay the animation
            perspective: 1500,                  // set 3D perspective
            transformOrigin: 'center top',      // set the center point of the 3d animation
            perspectiveOrigin: '50% 50%',       // camera angle

            translateY: 0,                      // animate along the Y axis (val: px or ‘slide’)
            translateX: 0,                      // animate along the X axis (val: px or ‘slide’)
            scale: 1.05,                           // animate scale (val: 0-2)
            rotateX: 20,                        // animate rotation (val: 0deg-360deg)
            rotateY: 0,                         // animate Y acces rotation (val: 0deg-360deg)
            skewY: 0,                           // animate Y skew (val: 0deg-360deg)
            skewX: 0,                           // animate X skew (val: 0deg-360deg)

            tabSwitched: function() {}          //callback after a tab has switched
        }, options);

        return this.each(function() {

            /*
             * Plugin vars
             */
            var _this = $(this);
            var menu = _this.closestChild(settings.tabMenu);
            var menuItem = menu.closestChild('li');
            var menuItemCount = menuItem.length;
            var content = _this.closestChild(settings.tabContent);
            var contentItem = content.children();
            var previousIndex;
            var maxHeight;

            //prevent users from entering a startslide that doesn't exist
            if (settings.startSlide < 1) {
                previousIndex = 0;
            } else if (settings.startSlide > menuItemCount) {
                previousIndex = menuItemCount - 1;
            } else {
                previousIndex = settings.startSlide - 1;
            }

            /*
             * Check if X or Y value is set to slide so we can
             * animate it like a default slider
             */
            if (settings.translateX === 'slide') {
                settings.translateX = $(contentItem).outerWidth();
            }

            if (settings.translateY === 'slide') {
                settings.translateY = $(contentItem).outerHeight();
            }

            var index = settings.startSlide - 1;
            var from = 'left';
            var next = _this.find(settings.next);
            var prev = _this.find(settings.prev);
            var velocity = settings.useAnimations;

            //Count the number of instances to disable arrow keys
            instance++;

            /*
             * If velocity.js does not exist
             */
            if (settings.useAnimations) {
                if (!$.isFunction($.fn.velocity)) {
                    velocity = false;
                    console.log('Animations wil not work because you did not include the www.velocityjs.org library');
                }
            }

            /*
             * This is meant as a backup
             * Add position absolute to the slides in your css
             */
            contentItem.css('position', 'absolute');

            /*
             * Set height
             */
            maxHeight = 0;
            content.wrapInner('

');
            if (settings.animateHeight === true && settings.fixedHeight === false) {

                /*
                 * Animate height
                 */
                maxHeight = contentItem.eq(previousIndex).outerHeight();
                _this.find('.js-tabs-height').height(maxHeight);

            }else if (settings.fixedHeight === true){

                /*
                 * Sets tab content container to the highest height
                 */
                contentItem.each(function() {
                    maxHeight = maxHeight > $(this).outerHeight() ? maxHeight : $(this).outerHeight();
                });
                _this.find('.js-tabs-height').height(maxHeight);

            }else{
                maxHeight = contentItem.eq(previousIndex).outerHeight();
                _this.find('.js-tabs-height').height(maxHeight);
            }

            /*
             * Get clicked index and activate its content
             */
            menuItem.on('click', function(index) {
                index = $(this).index();

                /*
                 * Call tabswitch to switch tab content
                 */
                if (index !== previousIndex) {
                    tabSwitch(index, previousIndex);
                }

                /*
                 * Set previous index to compare
                 */
                previousIndex = index;
                return false;
            });

            /*
             * Next/Prev controls
             */
            next.on('click', function() {
                index = previousIndex + 1;
                tabSwitch(index, previousIndex);
                return false;
            });

            prev.on('click', function() {
                index = previousIndex - 1;
                tabSwitch(index, previousIndex);
                return false;
            });

            /*
             * Use arrow keys to switch between content
             */
            if (settings.arrows === true && instance <= 1) {
                $(document).keydown(function(e) {
                    if (!$('input').is(':focus')) {
                        if (e.keyCode === 37) {
                            index = previousIndex - 1;
                            tabSwitch(index, previousIndex);

                        } else if (e.keyCode === 39) {
                            index = previousIndex + 1;
                            tabSwitch(index, previousIndex);
                        }
                    }
                });
            }

            /*
             * Switch to selected tab function
             */
            var tabSwitch = function(selectedItem, previousItem) {

                if (selectedItem >= menuItemCount || selectedItem < 0) {
                    if (index < 1) {
                        index = 0;
                    } else if (selectedItem >= menuItemCount) {
                        index = menuItemCount - 1;
                    }
                    return false;
                } else {

                    /*
                     * Add active class to current tab menu item
                     */
                    menuItem.eq(previousItem).removeClass('active').attr('aria-hidden', 'true');
                    menuItem.eq(selectedItem).addClass('active').attr('aria-hidden', 'false');

                    /*
                     * Add active class to current tab content item
                     */
                    contentItem.eq(previousItem).removeClass('active').attr('aria-hidden', 'true');
                    contentItem.eq(selectedItem).addClass('active').attr('aria-hidden', 'false');

                    if (selectedItem > previousItem) {

                        from = 'right';

                        /*
                         * Store current index so we can compare on next click
                         */
                        previousIndex = index;
                        index = selectedItem;

                    } else if (selectedItem < previousItem) {

                        from = 'left';

                        /*
                         * Store current index so we can compare on next click
                         */
                        previousIndex = index;
                        index = selectedItem;

                    }

                    if (velocity) {
                        /*
                         * Animate elements in view
                         */
                        contentItem.eq(selectedItem)
                            .velocity({
                                translateX: function() {
                                    if (from === 'left') {
                                        return -settings.translateX;
                                    } else {
                                        return settings.translateX;
                                    }
                                },
                                translateY: function() {
                                    if (from === 'left') {
                                        return -settings.translateY;
                                    } else {
                                        return settings.translateY;
                                    }
                                },
                                scale: function() {
                                    if (from === 'left') {
                                        return settings.scale - (settings.scale - 1) * 2;
                                    } else {
                                        return settings.scale + (settings.scale - 1);
                                    }
                                },
                                rotateX: function() {
                                    if (from === 'left') {
                                        return -settings.rotateX;
                                    } else {
                                        return settings.rotateX;
                                    }
                                },
                                rotateY: function() {
                                    if (from === 'left') {
                                        return -settings.rotateY;
                                    } else {
                                        return settings.rotateY;
                                    }
                                },
                                skewY: function() {
                                    if (from === 'left') {
                                        return -settings.skewY;
                                    } else {
                                        return settings.skewY;
                                    }
                                },
                                skewX: function() {
                                    if (from === 'left') {
                                        return -settings.skewX;
                                    } else {
                                        return settings.skewX;
                                    }
                                },
                                opacity: 0
                            }, {
                                duration: 0
                            })
                            .velocity({
                                translateX: 0,
                                translateY: 0,
                                scale: 1,
                                opacity: 1,
                                rotateY: 0,
                                rotateX: 0,
                                skewY: 0,
                                skewX: 0
                            }, {
                                easing: settings.easing,
                                duration: settings.speed,
                                delay: settings.slideDelay,
                                queue: false,
                                complete: function() {
                                    $(this).css('z-index', menuItemCount);
                                }
                            });

                        /*
                         * Animate elements out of view
                         */
                        contentItem.eq(previousItem)
                            .velocity({
                                translateX: function() {
                                    if (from === 'left') {
                                        return settings.translateX;
                                    } else {
                                        return -settings.translateX;
                                    }
                                },
                                translateY: function() {
                                    if (from === 'left') {
                                        return settings.translateY;
                                    } else {
                                        return -settings.translateY;
                                    }
                                },
                                scale: function() {
                                    if (from === 'left') {
                                        return settings.scale + (settings.scale - 1);
                                    } else {
                                        return settings.scale - (settings.scale - 1) * 2;
                                    }
                                },
                                rotateX: function() {
                                    if (from === 'left') {
                                        return settings.rotateX;
                                    } else {
                                        return -settings.rotateX;
                                    }
                                },
                                rotateY: function() {
                                    if (from === 'left') {
                                        return settings.rotateY;
                                    } else {
                                        return -settings.rotateY;
                                    }
                                },
                                rotateZ: function() {
                                    if (from === 'left') {
                                        return settings.rotateZ;
                                    } else {
                                        return -settings.rotateZ;
                                    }
                                },
                                skewX: function() {
                                    if (from === 'left') {
                                        return settings.skewX;
                                    } else {
                                        return -settings.skewX;
                                    }
                                },
                                skewY: function() {
                                    if (from === 'left') {
                                        return settings.skewY;
                                    } else {
                                        return -settings.skewY;
                                    }
                                },
                                opacity: 0,
                                delay: 1000
                            }, {
                                easing: settings.easing,
                                duration: settings.speed,
                                queue: false,
                                complete: function() {
                                    $(this).css('z-index', '-1');
                                }
                            });

                    } else {
                        contentItem.eq(previousItem).hide();
                        contentItem.eq(selectedItem).show();
                    }

                    /*
                     * Animate height
                     */
                    if (settings.animateHeight === true && velocity && settings.fixedHeight !== true) {
                        _this.find('.js-tabs-height')
                        .velocity({
                            height: $(contentItem).eq(selectedItem).outerHeight(),
                        }, {
                            easing: settings.easing,
                            duration: settings.speed,
                            queue: false
                        });

                    } else if(settings.animateHeight === false && settings.fixedHeight === false){
                        _this.find('.js-tabs-height').css('height', $(contentItem).eq(selectedItem).outerHeight());
                    }

                    /*
                     * Check if we should disable prev/next controls
                     */
                    checkIfDisabled();

                }
                settings.tabSwitched.call(this);
            };

            /*
             * Prepare elements to be animated
             */
            contentItem.each(function() {
                if (velocity) {
                    if ($(this).index() !== previousIndex) {
                        $(this)
                            .velocity({
                                opacity: 0
                            }, {
                                display: 'block',
                                duration: 0,
                                complete: function() {
                                    $(this).css({
                                        'z-index': '-1'
                                    });
                                }
                            });
                    } else {
                        $(this).css({
                            'opacity': '1',
                            'z-index': menuItemCount
                        });
                    }
                } else {
                    $(this).hide();
                }
            });

            /*
             * Set tabs menu above slides
             */
            menu.css({
                'z-index': menuItemCount + 1,
                'position': 'relative'
            });

            /*
             * Set perspective to tabcontent container
             */
            if (settings.useAnimations) {
                $('.js-tabs-height').css({
                    'perspective': settings.perspective,
                    'perspective-origin': settings.perspectiveOrigin
                });
                contentItem.css({
                    'transform-origin': settings.transformOrigin
                });
            }

            var checkIfDisabled = function() {
                if (index === menuItemCount - 1) {
                    next.addClass('disabled');
                    prev.removeClass('disabled');
                } else if (index === 0) {
                    prev.addClass('disabled');
                    next.removeClass('disabled');
                } else {
                    next.removeClass('disabled');
                    prev.removeClass('disabled');
                }
            };

            /*
             * Set startslide
             */
            menuItem.attr('aria-hidden', 'true').eq(previousIndex).addClass('active').attr('aria-hidden', 'false');
            contentItem.attr('aria-hidden', 'true').eq(previousIndex).addClass('active').attr('aria-hidden', 'false').css('display', 'block');

            /*
             * Its possible that the startslide is 0
             * so check if we should disable a button
             */
            checkIfDisabled();

        });
    };
}(jQuery));
<commit_msg>layed out basis for autocycle tabs<commit_after>(function($) {

    'use strict';

    /*
     * jquery.closestchild 0.1.1
     *
     * Author: Andrey Mikhaylov aka lolmaus
     * Email: lolmaus@gmail.com
     *
     */
    $.fn.closestChild = function(selector) {
        var $children, $results;

        $children = this.children();

        if ($children.length === 0) {
            return $();
        }

        $results = $children.filter(selector);

        if ($results.length > 0) {
            return $results;
        } else {
            return $children.closestChild(selector);
        }
    };

    var instance = 0;

    $.fn.tabtab = function(options) {

        /*
         * Plugin default options
         */
        var settings = $.extend({
            tabMenu: '.tabs__menu',             // direct container of the tab menu items
            tabContent: '.tabs__content',       // direct container of the tab content items
            next: '.tabs-controls__next',       // next slide trigger
            prev: '.tabs-controls__prev',       // previous slide trigger

            startSlide: 2,                      // starting slide on pageload
            arrows: true,                       // keyboard arrow navigation
            animateHeight: true,                // if true the height will dynamic and animated.
            fixedHeight: true,                  // if set to true the container will use the heighest height.
            useAnimations: true,                // disables animations.
            autoCycle: 2000,                   // To disable set option to false. To enable specify the speed in miliseconds.

            easing: [200, 20],                  // http://julian.com/research/velocity/#easing
            speed: 700,                         // animation speed
            slideDelay: 0,                      // delay the animation
            perspective: 1500,                  // set 3D perspective
            transformOrigin: 'center top',      // set the center point of the 3d animation
            perspectiveOrigin: '50% 50%',       // camera angle

            translateY: 0,                      // animate along the Y axis (val: px or ‘slide’)
            translateX: 0,                      // animate along the X axis (val: px or ‘slide’)
            scale: 1.05,                           // animate scale (val: 0-2)
            rotateX: 20,                        // animate rotation (val: 0deg-360deg)
            rotateY: 0,                         // animate Y acces rotation (val: 0deg-360deg)
            skewY: 0,                           // animate Y skew (val: 0deg-360deg)
            skewX: 0,                           // animate X skew (val: 0deg-360deg)

            tabSwitched: function() {}          //callback after a tab has switched
        }, options);

        return this.each(function() {

            /*
             * Plugin vars
             */
            var _this = $(this);
            var menu = _this.closestChild(settings.tabMenu);
            var menuItem = menu.closestChild('li');
            var menuItemCount = menuItem.length;
            var content = _this.closestChild(settings.tabContent);
            var contentItem = content.children();
            var previousIndex;
            var maxHeight;

            //prevent users from entering a startslide that doesn't exist
            if (settings.startSlide < 1) {
                previousIndex = 0;
            } else if (settings.startSlide > menuItemCount) {
                previousIndex = menuItemCount - 1;
            } else {
                previousIndex = settings.startSlide - 1;
            }

            /*
             * Check if X or Y value is set to slide so we can
             * animate it like a default slider
             */
            if (settings.translateX === 'slide') {
                settings.translateX = $(contentItem).outerWidth();
            }

            if (settings.translateY === 'slide') {
                settings.translateY = $(contentItem).outerHeight();
            }

            var index = settings.startSlide - 1;
            var from = 'left';
            var next = _this.find(settings.next);
            var prev = _this.find(settings.prev);
            var velocity = settings.useAnimations;

            //Count the number of instances to disable arrow keys
            instance++;

            /*
             * If velocity.js does not exist
             */
            if (settings.useAnimations) {
                if (!$.isFunction($.fn.velocity)) {
                    velocity = false;
                    console.log('Animations wil not work because you did not include the www.velocityjs.org library');
                }
            }

            /*
             * This is meant as a backup
             * Add position absolute to the slides in your css
             */
            contentItem.css('position', 'absolute');

            /*
             * Set height
             */
            maxHeight = 0;
            content.wrapInner('

');
            if (settings.animateHeight === true && settings.fixedHeight === false) {

                /*
                 * Animate height
                 */
                maxHeight = contentItem.eq(previousIndex).outerHeight();
                _this.find('.js-tabs-height').height(maxHeight);

            }else if (settings.fixedHeight === true){

                /*
                 * Sets tab content container to the highest height
                 */
                contentItem.each(function() {
                    maxHeight = maxHeight > $(this).outerHeight() ? maxHeight : $(this).outerHeight();
                });
                _this.find('.js-tabs-height').height(maxHeight);

            }else{
                maxHeight = contentItem.eq(previousIndex).outerHeight();
                _this.find('.js-tabs-height').height(maxHeight);
            }

            /*
             * Get clicked index and activate its content
             */
            menuItem.on('click', function(index) {
                index = $(this).index();

                /*
                 * Call tabswitch to switch tab content
                 */
                if (index !== previousIndex) {
                    tabSwitch(index, previousIndex);
                }

                /*
                 * Set previous index to compare
                 */
                previousIndex = index;
                return false;
            });

            /*
             * Next/Prev controls
             */
            next.on('click', function() {
                index = previousIndex + 1;
                tabSwitch(index, previousIndex);
                return false;
            });

            prev.on('click', function() {
                index = previousIndex - 1;
                tabSwitch(index, previousIndex);
                return false;
            });

            /*
             * Use arrow keys to switch between content
             */
            if (settings.arrows === true && instance <= 1) {
                $(document).keydown(function(e) {
                    if (!$('input').is(':focus')) {
                        if (e.keyCode === 37) {
                            index = previousIndex - 1;
                            tabSwitch(index, previousIndex);

                        } else if (e.keyCode === 39) {
                            index = previousIndex + 1;
                            tabSwitch(index, previousIndex);
                        }
                    }
                });
            }

            /**
             * Autocycle tabs
             */
            if (settings.autoCycle){
                var cycle = function() {
                    console.log('cycle');
                    index = previousIndex + 1;
                    if (index >= menuItemCount){
                        index = 0;
                    }
                    tabSwitch(index, previousIndex);
                };

                var interval = setInterval(cycle, settings.autoCycle);

                $(this).on('mouseover', function(){
                    console.log('mouseOver');
                    window.clearInterval(interval)
                });
                $(this).on('mouseleave', function(){interval = setInterval(cycle, settings.autoCycle)});
            };

            /*
             * Switch to selected tab function
             */
            var tabSwitch = function(selectedItem, previousItem) {

                if (selectedItem >= menuItemCount || selectedItem < 0) {
                    if (index < 1) {
                        index = 0;
                    } else if (selectedItem >= menuItemCount) {
                        index = menuItemCount - 1;
                    }
                    return false;
                } else {

                    /*
                     * Add active class to current tab menu item
                     */
                    menuItem.eq(previousItem).removeClass('active').attr('aria-hidden', 'true');
                    menuItem.eq(selectedItem).addClass('active').attr('aria-hidden', 'false');

                    /*
                     * Add active class to current tab content item
                     */
                    contentItem.eq(previousItem).removeClass('active').attr('aria-hidden', 'true');
                    contentItem.eq(selectedItem).addClass('active').attr('aria-hidden', 'false');

                    if (selectedItem > previousItem) {

                        from = 'right';

                        /*
                         * Store current index so we can compare on next click
                         */
                        previousIndex = index;
                        index = selectedItem;

                    } else if (selectedItem < previousItem) {

                        from = 'left';

                        /*
                         * Store current index so we can compare on next click
                         */
                        previousIndex = index;
                        index = selectedItem;

                    }

                    if (velocity) {
                        /*
                         * Animate elements in view
                         */
                        contentItem.eq(selectedItem)
                            .velocity({
                                translateX: function() {
                                    if (from === 'left') {
                                        return -settings.translateX;
                                    } else {
                                        return settings.translateX;
                                    }
                                },
                                translateY: function() {
                                    if (from === 'left') {
                                        return -settings.translateY;
                                    } else {
                                        return settings.translateY;
                                    }
                                },
                                scale: function() {
                                    if (from === 'left') {
                                        return settings.scale - (settings.scale - 1) * 2;
                                    } else {
                                        return settings.scale + (settings.scale - 1);
                                    }
                                },
                                rotateX: function() {
                                    if (from === 'left') {
                                        return -settings.rotateX;
                                    } else {
                                        return settings.rotateX;
                                    }
                                },
                                rotateY: function() {
                                    if (from === 'left') {
                                        return -settings.rotateY;
                                    } else {
                                        return settings.rotateY;
                                    }
                                },
                                skewY: function() {
                                    if (from === 'left') {
                                        return -settings.skewY;
                                    } else {
                                        return settings.skewY;
                                    }
                                },
                                skewX: function() {
                                    if (from === 'left') {
                                        return -settings.skewX;
                                    } else {
                                        return settings.skewX;
                                    }
                                },
                                opacity: 0
                            }, {
                                duration: 0
                            })
                            .velocity({
                                translateX: 0,
                                translateY: 0,
                                scale: 1,
                                opacity: 1,
                                rotateY: 0,
                                rotateX: 0,
                                skewY: 0,
                                skewX: 0
                            }, {
                                easing: settings.easing,
                                duration: settings.speed,
                                delay: settings.slideDelay,
                                queue: false,
                                complete: function() {
                                    $(this).css('z-index', menuItemCount);
                                }
                            });

                        /*
                         * Animate elements out of view
                         */
                        contentItem.eq(previousItem)
                            .velocity({
                                translateX: function() {
                                    if (from === 'left') {
                                        return settings.translateX;
                                    } else {
                                        return -settings.translateX;
                                    }
                                },
                                translateY: function() {
                                    if (from === 'left') {
                                        return settings.translateY;
                                    } else {
                                        return -settings.translateY;
                                    }
                                },
                                scale: function() {
                                    if (from === 'left') {
                                        return settings.scale + (settings.scale - 1);
                                    } else {
                                        return settings.scale - (settings.scale - 1) * 2;
                                    }
                                },
                                rotateX: function() {
                                    if (from === 'left') {
                                        return settings.rotateX;
                                    } else {
                                        return -settings.rotateX;
                                    }
                                },
                                rotateY: function() {
                                    if (from === 'left') {
                                        return settings.rotateY;
                                    } else {
                                        return -settings.rotateY;
                                    }
                                },
                                rotateZ: function() {
                                    if (from === 'left') {
                                        return settings.rotateZ;
                                    } else {
                                        return -settings.rotateZ;
                                    }
                                },
                                skewX: function() {
                                    if (from === 'left') {
                                        return settings.skewX;
                                    } else {
                                        return -settings.skewX;
                                    }
                                },
                                skewY: function() {
                                    if (from === 'left') {
                                        return settings.skewY;
                                    } else {
                                        return -settings.skewY;
                                    }
                                },
                                opacity: 0,
                                delay: 1000
                            }, {
                                easing: settings.easing,
                                duration: settings.speed,
                                queue: false,
                                complete: function() {
                                    $(this).css('z-index', '-1');
                                }
                            });

                    } else {
                        contentItem.eq(previousItem).hide();
                        contentItem.eq(selectedItem).show();
                    }

                    /*
                     * Animate height
                     */
                    if (settings.animateHeight === true && velocity && settings.fixedHeight !== true) {
                        _this.find('.js-tabs-height')
                        .velocity({
                            height: $(contentItem).eq(selectedItem).outerHeight(),
                        }, {
                            easing: settings.easing,
                            duration: settings.speed,
                            queue: false
                        });

                    } else if(settings.animateHeight === false && settings.fixedHeight === false){
                        _this.find('.js-tabs-height').css('height', $(contentItem).eq(selectedItem).outerHeight());
                    }

                    /*
                     * Check if we should disable prev/next controls
                     */
                    checkIfDisabled();

                }
                settings.tabSwitched.call(this);
            };

            /*
             * Prepare elements to be animated
             */
            contentItem.each(function() {
                if (velocity) {
                    if ($(this).index() !== previousIndex) {
                        $(this)
                            .velocity({
                                opacity: 0
                            }, {
                                display: 'block',
                                duration: 0,
                                complete: function() {
                                    $(this).css({
                                        'z-index': '-1'
                                    });
                                }
                            });
                    } else {
                        $(this).css({
                            'opacity': '1',
                            'z-index': menuItemCount
                        });
                    }
                } else {
                    $(this).hide();
                }
            });

            /*
             * Set tabs menu above slides
             */
            menu.css({
                'z-index': menuItemCount + 1,
                'position': 'relative'
            });

            /*
             * Set perspective to tabcontent container
             */
            if (settings.useAnimations) {
                $('.js-tabs-height').css({
                    'perspective': settings.perspective,
                    'perspective-origin': settings.perspectiveOrigin
                });
                contentItem.css({
                    'transform-origin': settings.transformOrigin
                });
            }

            var checkIfDisabled = function() {
                if (index === menuItemCount - 1) {
                    next.addClass('disabled');
                    prev.removeClass('disabled');
                } else if (index === 0) {
                    prev.addClass('disabled');
                    next.removeClass('disabled');
                } else {
                    next.removeClass('disabled');
                    prev.removeClass('disabled');
                }
            };

            /*
             * Set startslide
             */
            menuItem.attr('aria-hidden', 'true').eq(previousIndex).addClass('active').attr('aria-hidden', 'false');
            contentItem.attr('aria-hidden', 'true').eq(previousIndex).addClass('active').attr('aria-hidden', 'false').css('display', 'block');

            /*
             * Its possible that the startslide is 0
             * so check if we should disable a button
             */
            checkIfDisabled();

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


<commit_before>import React, { Component, PropTypes } from 'react';
import cx from 'classnames';
import s from './ControlPanel.scss';
import withStyles from '../../../decorators/withStyles';
import BuyActions from '../../../actions/BuyActions';
import BuyStore from '../../../stores/BuyStore';
import connectToStores from 'alt-utils/lib/connectToStores';

@withStyles(s)
@connectToStores
class ControlPanel extends Component {

	static propTypes = {
		className: PropTypes.string,
		local: PropTypes.bool,
		google: PropTypes.object,
		currentLocation: PropTypes.string,
		suggestions: PropTypes.array,
		navigator: PropTypes.object,
		error: PropTypes.string,
	};

	constructor() {
		super();
		this.showAutocomplete = false;
	}

	static getStores() {
		return [BuyStore];
	}

	static getPropsFromStores() {
		return BuyStore.getState();
	}

	setLocal(l) {
		BuyActions.setLocal(l);
	}

	setOrigin(e) {
		console.log(e.target.value);
		BuyActions.geocode(e.target.value);
		this.showAutocomplete = false;
	}

	handleCurrentLocation() {
		this.props.navigator.geolocation.getCurrentPosition((pos) => {
			BuyActions.setCenter({ lat: pos.coords.latitude, lng: pos.coords.longitude });
		}, (err) => {
			BuyActions.setError(err);
		});
	}

	searchAutocomplete(e) {
		if (!e.target.value || e.target.value.length === 0) {
			return;
		}
		const autocomplete = new this.props.google.maps.places.AutocompleteService();
		autocomplete.getQueryPredictions({ input: e.target.value }, (predictions, status) => {
			if (status !== this.props.google.maps.places.PlacesServiceStatus.OK) {
				BuyActions.setError(status);
			}
			BuyActions.setSuggestions(predictions);
			this.showAutocomplete = true;
		});
	}

	// renderSuggestionsX() {
	// 	const suggestions = [];
	// 	this.props.suggestions.map((suggestion, index) => {
	// 		suggestions.push(<option value={suggestion.description} key={index} >{suggestion.description}</option>);
	// 	});
	// 	return (
	// 		<datalist id="suggestions">{suggestions}</datalist>
	// 	);
	// }

	renderSuggestions() {
		const suggestions = [];
		this.props.suggestions.map((suggestion, index) => {
			suggestions.push(
{suggestion.description}
);
		});
		return (

{suggestions}

		);
	}

	render() {
		return (

							Buy Local

							Buy Online

								Use my Location

							<input type="search" autoComplete="on" className={cx('form-control', 'autocomplete')} placeholder="Search for location" onChange={::this.searchAutocomplete} list="suggestions"/>
							{this.props.suggestions && this.props.suggestions.length && this.showAutocomplete > 0 ? this.renderSuggestions() : null}

						{this.props.error ?
{this.props.error}
 : null}

		);
	}

}

export default ControlPanel;
<commit_msg>deletes unused code<commit_after>import React, { Component, PropTypes } from 'react';
import cx from 'classnames';
import s from './ControlPanel.scss';
import withStyles from '../../../decorators/withStyles';
import BuyActions from '../../../actions/BuyActions';
import BuyStore from '../../../stores/BuyStore';
import connectToStores from 'alt-utils/lib/connectToStores';

@withStyles(s)
@connectToStores
class ControlPanel extends Component {

	static propTypes = {
		className: PropTypes.string,
		local: PropTypes.bool,
		google: PropTypes.object,
		currentLocation: PropTypes.string,
		suggestions: PropTypes.array,
		navigator: PropTypes.object,
		error: PropTypes.string,
	};

	constructor() {
		super();
		this.showAutocomplete = false;
	}

	static getStores() {
		return [BuyStore];
	}

	static getPropsFromStores() {
		return BuyStore.getState();
	}

	setLocal(l) {
		BuyActions.setLocal(l);
	}

	setOrigin(e) {
		BuyActions.geocode(e.target.value);
		this.showAutocomplete = false;
	}

	handleCurrentLocation() {
		this.props.navigator.geolocation.getCurrentPosition((pos) => {
			BuyActions.setCenter({ lat: pos.coords.latitude, lng: pos.coords.longitude });
		}, (err) => {
			BuyActions.setError(err);
		});
	}

	searchAutocomplete(e) {
		if (!e.target.value || e.target.value.length === 0) {
			return;
		}
		const autocomplete = new this.props.google.maps.places.AutocompleteService();
		autocomplete.getQueryPredictions({ input: e.target.value }, (predictions, status) => {
			if (status !== this.props.google.maps.places.PlacesServiceStatus.OK) {
				BuyActions.setError(status);
			}
			BuyActions.setSuggestions(predictions);
			this.showAutocomplete = true;
		});
	}

	renderSuggestions() {
		const suggestions = [];
		this.props.suggestions.map((suggestion, index) => {
			suggestions.push(
{suggestion.description}
);
		});
		return (

{suggestions}

		);
	}

	render() {
		return (

							Buy Local

							Buy Online

								Use my Location

							<input type="search" autoComplete="on" className={cx('form-control', 'autocomplete')} placeholder="Search for location" onChange={::this.searchAutocomplete} list="suggestions"/>
							{this.props.suggestions && this.props.suggestions.length && this.showAutocomplete > 0 ? this.renderSuggestions() : null}

						{this.props.error ?
{this.props.error}
 : null}

		);
	}

}

export default ControlPanel;
<|endoftext|>


<commit_before>
import TestUtils from 'react-addons-test-utils';
import React from 'react';
import ReactDOM from 'react-dom';

import Input from '../';
const { renderIntoDocument, Simulate } = TestUtils;
import { identity } from 'lodash/utility';

import { init } from 'focus-core/translation';

const i18nConfig = {
    resStore: {},
    lng: 'fr-FR'///langOpts.i18nCulture
};

describe('The input text', () => {
    beforeEach(() => {
        init(i18nConfig);
    });

    describe('when called with no props', () => {
        let component;
        beforeEach(
            () => {
                const shallowRenderer = TestUtils.createRenderer();
                shallowRenderer.render(<Input name='test' onChange={(value) => { /* */ }} />);
                component = shallowRenderer.getRenderOutput();
            }
        );
        it('should render an empty input', () => {
            expect(component).toBeInstanceOf(Object);
            expect(component.type).toBe('div');
            expect(component.className).toMatch('mdl-textfield mdl-js-textfield');
        });
    });
    describe('when called with minimal props', () => {
        let component, domNode, onChangeSpy;
        beforeEach(
            () => {
                onChangeSpy = jest.fn();
                component = renderIntoDocument(<Input name='inputName' onChange={onChangeSpy} />);
                domNode = ReactDOM.findDOMNode(component);
            }
        );
        it('should render an empty input', () => {
            expect(domNode.tagName).toBe('DIV');
            expect(domNode.className).toMatch('mdl-textfield mdl-js-textfield');
        });

    });
    describe('when a value is provided', () => {
        let component, onChangeSpy;
        const value = 'testValue';
        beforeEach(
            () => {
                onChangeSpy = jest.fn();
                component = renderIntoDocument(<Input name='inputName' onChange={onChangeSpy} value={value} />);
            }
        );
        it('shoud return the value on getValue call', () => {
            expect(component.getValue()).toBe(value);
        });
        it('should render the value in the DOM', () => {
            expect(ReactDOM.findDOMNode(component.refs.htmlInput).value).toBe(value);
        });

    });
    describe('when a text is typed', () => {
        let component, onChangeSpy;
        const testValue = 'MY_TEST_VALUE';
        beforeEach(
            () => {
                onChangeSpy = jest.fn();
                component = renderIntoDocument(<Input name='inputName' onChange={onChangeSpy} />);

            }
        );
        it('should call onChange with the new value', () => {
            Simulate.change(ReactDOM.findDOMNode(component.refs.htmlInput), { target: { value: testValue } });
            expect(onChangeSpy).toHaveBeenCalledTimes(1);
            expect(onChangeSpy).toHaveBeenCalledWith(testValue);
        });
    });
    describe('when a formatter is provided', () => {
        let component, htmlInput, onChange, isEditFormatterSpy;
        const testValue = 'MY_TEST_VALUE';
        const formatedValue = 'MY_FORMATED_VALUE';
        beforeEach(
            () => {
                onChange = identity;
                isEditFormatterSpy = jest.fn();
                /**
                 * The formatter test.
                 * @return {string} - The formated value
                 */
                function formatter(value, mode) { isEditFormatterSpy(mode); return formatedValue; } // eslint-disable-line
                component = renderIntoDocument(<Input formatter={formatter} name='inputName' onChange={onChange} value={testValue} />);
                htmlInput = ReactDOM.findDOMNode(component.refs.htmlInput);

            }
        );
        it('should format the value in the DOM', () => {
            expect(htmlInput.value).toBe(formatedValue);
        });
        it('should call the isEdit formatter with the mode', () => {
            expect(isEditFormatterSpy).toHaveBeenCalledTimes(1);
            expect(isEditFormatterSpy).toHaveBeenCalledWith({ isEdit: true });
        });
    });
    describe('when an unformatter is provided', () => {
        let component, onChange, unFormatterSpy, componentValue;
        const testValue = 'MY_TEST_VALUE';
        const unformatedValue = 'MY_UN_FORMATED_VALUE';
        beforeEach(
            () => {
                unFormatterSpy = jest.fn();
                onChange = identity;
                /**
                 * The unformatter test.
                 * @return {string} - The formated value
                 */
                function unformatter(value, mode) { unFormatterSpy(mode); return unformatedValue; }//eslint-disable-line
                component = renderIntoDocument(<Input name='inputName' onChange={onChange} unformatter={unformatter} value={testValue} />);
                componentValue = component.getValue();
            }
        );
        it('should unformat the getValue', () => {
            expect(componentValue).toBe(unformatedValue);
        });
        it('should call unformatter with mode', () => {
            expect(unFormatterSpy).toHaveBeenCalledTimes(1);
            expect(unFormatterSpy).toHaveBeenCalledWith({ isEdit: true });
        });
    });
    describe('when an error is provided', () => {
        let component, onChange, htmlInput, htmlError;
        const testValue = 'MY_TEST_VALUE';
        const error = 'MY_ERROR';
        beforeEach(
            () => {
                onChange = identity;
                component = renderIntoDocument(<Input error={error} name='inputName' onChange={onChange} value={testValue} />);
                htmlInput = TestUtils.findRenderedDOMComponentWithTag(component, 'input');
                htmlError = TestUtils.findRenderedDOMComponentWithTag(component, 'span');
            }
        );
        it('should display the error in the HTML', () => {
            expect(htmlError).toBeDefined();
            expect(htmlError.innerHTML).toBe(error);
        });
        it('input should have a pattern attribute', () => {
            expect(htmlInput).toBeDefined();
            expect(htmlInput.getAttribute('pattern')).toBe('hasError');
        });
    });

});
<commit_msg>Correcting input text test<commit_after>
import TestUtils from 'react-addons-test-utils';
import React from 'react';
import ReactDOM from 'react-dom';

import Input from '../';
const { renderIntoDocument, Simulate } = TestUtils;
import { identity } from 'lodash/utility';

import { init } from 'focus-core/translation';

const i18nConfig = {
    resStore: {},
    lng: 'fr-FR'///langOpts.i18nCulture
};

describe('The input text', () => {
    beforeEach(() => {
        init(i18nConfig);
    });

    describe('when called with no props', () => {
        let component, domNode;
        beforeEach(
            () => {
                component = renderIntoDocument(<Input name='inputName' onChange={(value) => { /* */ }} />);
                domNode = ReactDOM.findDOMNode(component);
            }
        );
        it('should render an empty input', () => {
            // expect(component).toBeInstanceOf(Object);
            expect(domNode.tagName).toBe('DIV');
            expect(domNode.className).toMatch('mdl-textfield mdl-js-textfield');
        });
    });
    describe('when called with minimal props', () => {
        let component, domNode, onChangeSpy;
        beforeEach(
            () => {
                onChangeSpy = jest.fn();
                component = renderIntoDocument(<Input name='inputName' onChange={onChangeSpy} />);
                domNode = ReactDOM.findDOMNode(component);
            }
        );
        it('should render an empty input', () => {
            expect(domNode.tagName).toBe('DIV');
            expect(domNode.className).toMatch('mdl-textfield mdl-js-textfield');
        });

    });
    describe('when a value is provided', () => {
        let component, onChangeSpy;
        const value = 'testValue';
        beforeEach(
            () => {
                onChangeSpy = jest.fn();
                component = renderIntoDocument(<Input name='inputName' onChange={onChangeSpy} value={value} />);
            }
        );
        it('shoud return the value on getValue call', () => {
            expect(component.getValue()).toBe(value);
        });
        it('should render the value in the DOM', () => {
            expect(ReactDOM.findDOMNode(component.refs.htmlInput).value).toBe(value);
        });

    });
    describe('when a text is typed', () => {
        let component, onChangeSpy;
        const testValue = 'MY_TEST_VALUE';
        beforeEach(
            () => {
                onChangeSpy = jest.fn();
                component = renderIntoDocument(<Input name='inputName' onChange={onChangeSpy} />);

            }
        );
        it('should call onChange with the new value', () => {
            Simulate.change(ReactDOM.findDOMNode(component.refs.htmlInput), { target: { value: testValue } });
            expect(onChangeSpy).toHaveBeenCalledTimes(1);
            expect(onChangeSpy).toHaveBeenCalledWith(testValue);
        });
    });
    describe('when a formatter is provided', () => {
        let component, htmlInput, onChange, isEditFormatterSpy;
        const testValue = 'MY_TEST_VALUE';
        const formatedValue = 'MY_FORMATED_VALUE';
        beforeEach(
            () => {
                onChange = identity;
                isEditFormatterSpy = jest.fn();
                /**
                 * The formatter test.
                 * @return {string} - The formated value
                 */
                function formatter(value, mode) { isEditFormatterSpy(mode); return formatedValue; } // eslint-disable-line
                component = renderIntoDocument(<Input formatter={formatter} name='inputName' onChange={onChange} value={testValue} />);
                htmlInput = ReactDOM.findDOMNode(component.refs.htmlInput);

            }
        );
        it('should format the value in the DOM', () => {
            expect(htmlInput.value).toBe(formatedValue);
        });
        it('should call the isEdit formatter with the mode', () => {
            expect(isEditFormatterSpy).toHaveBeenCalledTimes(1);
            expect(isEditFormatterSpy).toHaveBeenCalledWith({ isEdit: true });
        });
    });
    describe('when an unformatter is provided', () => {
        let component, onChange, unFormatterSpy, componentValue;
        const testValue = 'MY_TEST_VALUE';
        const unformatedValue = 'MY_UN_FORMATED_VALUE';
        beforeEach(
            () => {
                unFormatterSpy = jest.fn();
                onChange = identity;
                /**
                 * The unformatter test.
                 * @return {string} - The formated value
                 */
                function unformatter(value, mode) { unFormatterSpy(mode); return unformatedValue; }//eslint-disable-line
                component = renderIntoDocument(<Input name='inputName' onChange={onChange} unformatter={unformatter} value={testValue} />);
                componentValue = component.getValue();
            }
        );
        it('should unformat the getValue', () => {
            expect(componentValue).toBe(unformatedValue);
        });
        it('should call unformatter with mode', () => {
            expect(unFormatterSpy).toHaveBeenCalledTimes(1);
            expect(unFormatterSpy).toHaveBeenCalledWith({ isEdit: true });
        });
    });
    describe('when an error is provided', () => {
        let component, onChange, htmlInput, htmlError;
        const testValue = 'MY_TEST_VALUE';
        const error = 'MY_ERROR';
        beforeEach(
            () => {
                onChange = identity;
                component = renderIntoDocument(<Input error={error} name='inputName' onChange={onChange} value={testValue} />);
                htmlInput = TestUtils.findRenderedDOMComponentWithTag(component, 'input');
                htmlError = TestUtils.findRenderedDOMComponentWithTag(component, 'span');
            }
        );
        it('should display the error in the HTML', () => {
            expect(htmlError).toBeDefined();
            expect(htmlError.innerHTML).toBe(error);
        });
        it('input should have a pattern attribute', () => {
            expect(htmlInput).toBeDefined();
            expect(htmlInput.getAttribute('pattern')).toBe('hasError');
        });
    });

});
<|endoftext|>


<commit_before>/*
Copyright 2020 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from 'react';
import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler';
import Modal from '../../../Modal';
import { replaceableComponent } from '../../../utils/replaceableComponent';
import VerificationRequestDialog from './VerificationRequestDialog';
import BaseDialog from './BaseDialog';
import DialogButtons from '../elements/DialogButtons';
import {verificationMethods} from 'matrix-js-sdk/src/crypto';
import {MatrixClientPeg} from "../../../MatrixClientPeg";
import {SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode";

@replaceableComponent("views.dialogs.NewSessionReviewDialog")
export default class NewSessionReviewDialog extends React.PureComponent {
    static propTypes = {
        userId: PropTypes.string.isRequired,
        device: PropTypes.object.isRequired,
        onFinished: PropTypes.func.isRequired,
    }

    onCancelClick = () => {
        this.props.onFinished(false);
    }

    onContinueClick = async () => {
        const { userId, device } = this.props;
        const cli = MatrixClientPeg.get();
        const request = await cli.requestVerification(
            userId,
            [verificationMethods.SAS, SHOW_QR_CODE_METHOD],
            [device.deviceId],
        );

        this.props.onFinished(true);

        Modal.createTrackedDialog('New Session Verification', 'Starting dialog', VerificationRequestDialog, {
            verificationRequest: request,
        });

        // Modal.createTrackedDialog('New Session Verification', 'Starting dialog', DeviceVerifyDialog, {
        //     userId,
        //     [verificationMethods.SAS, SHOW_QR_CODE_METHOD],
        //     [device.deviceId],
        // );
    }

    render() {
        const { device } = this.props;

        const icon = ;
        const titleText = _t("New session");

        const title =

            {icon}
            {titleText}

;

        return (
            <BaseDialog
                title={title}
                onFinished={this.props.onFinished}
            >

{_t(
                        "Use this session to verify your new one, " +
                        "granting it access to encrypted messages:",
                    )}

                                {device.getDisplayName()}

                                ({device.deviceId})

{_t(
                        "If you didn’t sign in to this session, " +
                        "your account may be compromised.",
                    )}

                    <DialogButtons
                        cancelButton={_t("This wasn't me")}
                        cancelButtonClass="danger"
                        primaryButton={_t("Continue")}
                        onCancel={this.onCancelClick}
                        onPrimaryButtonClick={this.onContinueClick}
                    />

            </BaseDialog>
        );
    }
}
<commit_msg>remove commented out code<commit_after>/*
Copyright 2020 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from 'react';
import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler';
import Modal from '../../../Modal';
import { replaceableComponent } from '../../../utils/replaceableComponent';
import VerificationRequestDialog from './VerificationRequestDialog';
import BaseDialog from './BaseDialog';
import DialogButtons from '../elements/DialogButtons';
import {verificationMethods} from 'matrix-js-sdk/src/crypto';
import {MatrixClientPeg} from "../../../MatrixClientPeg";
import {SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode";

@replaceableComponent("views.dialogs.NewSessionReviewDialog")
export default class NewSessionReviewDialog extends React.PureComponent {
    static propTypes = {
        userId: PropTypes.string.isRequired,
        device: PropTypes.object.isRequired,
        onFinished: PropTypes.func.isRequired,
    }

    onCancelClick = () => {
        this.props.onFinished(false);
    }

    onContinueClick = async () => {
        const { userId, device } = this.props;
        const cli = MatrixClientPeg.get();
        const request = await cli.requestVerification(
            userId,
            [verificationMethods.SAS, SHOW_QR_CODE_METHOD],
            [device.deviceId],
        );

        this.props.onFinished(true);

        Modal.createTrackedDialog('New Session Verification', 'Starting dialog', VerificationRequestDialog, {
            verificationRequest: request,
        });
    }

    render() {
        const { device } = this.props;

        const icon = ;
        const titleText = _t("New session");

        const title =

            {icon}
            {titleText}

;

        return (
            <BaseDialog
                title={title}
                onFinished={this.props.onFinished}
            >

{_t(
                        "Use this session to verify your new one, " +
                        "granting it access to encrypted messages:",
                    )}

                                {device.getDisplayName()}

                                ({device.deviceId})

{_t(
                        "If you didn’t sign in to this session, " +
                        "your account may be compromised.",
                    )}

                    <DialogButtons
                        cancelButton={_t("This wasn't me")}
                        cancelButtonClass="danger"
                        primaryButton={_t("Continue")}
                        onCancel={this.onCancelClick}
                        onPrimaryButtonClick={this.onContinueClick}
                    />

            </BaseDialog>
        );
    }
}
<|endoftext|>


<commit_before>var APP = angular.module('APP');
APP.service('_user', ['_http', function(_http) {
    var current_search = 0; //Keeps track of what search is currently active to prevent callbacks from overlapping each other

    this.user = {
        id: false
    };
    this.users = {}; //Users found in backend - May it be by search result or friends

    this.friend_requests = []; //Contains request made for other users
    this.friends_new = []; //Contains requests from other users
    this.friends = []; //Actual friends

    this.comments = []; //All comments that this user is involved with

    this.search_friends_result = []; //Users found for a current search

    this.is_email_valid = function(email) {
        var mailPattern = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        return mailPattern.test(email);
    };

    this.sign_in = function(data) {
        var _this = this;
        return _http.get("/api/open/user", data)
            .then(function(result) {
                angular.copy(result.data.user, _this.user);
                angular.copy(result.data.friend_requests, _this.friends);
            });
    };

    this.create_user = function(data) {
        var _this = this;
        return _http.post('/api/open/user/', data)
            .then(function(result) {
                angular.copy(result.data.user, _this.user);
            });
    };

    this.sign_out = function() {
        return _http.get("/api/sign_out");
    };

    this.authenticate = function() {
        var _this = this;
        return _http.get("/api/open/user", null, {
                silent: true
            })
            .then(function(result) {
                angular.copy(result.data.user, _this.user);
                angular.copy(result.data.friend_requests, _this.friends);
            });
    };

    this.find_friends = function(query) {
        var _this = this;

        current_search++;
        var cs = current_search;
        _http.get("/api/closed/friends/" + query, null, {
                silent: true
            })
            .then(function(result) {
                if (cs === current_search) {
                    var l = result.data.users.length;
                    for (var i = 0; i < l; i++) {
                        if (!_this.users[result.data.users[i].id]) {
                            _this.users[result.data.users[i].id] = result.data.users[i]
                        }
                    }
                    angular.copy(result.data.users, _this.search_friends_result);
                }
                console.log(_this.users);
            })
            .catch(function() {
                angular.copy([], _this.search_friends_result);
            })
    };

    this.add_friend = function(user_id) {
        var _this = this;
        _http.post("/api/closed/friends/" + user_id)
            .then(function(result) {
                _this.friends.push(result.data.friend_request);
            })
            .catch(function(err) {
                console.trace(err);
            });
    };

    this.get_friend = function(user_id) {
        var _this = this;
        if (_this.users[user_id])
            return _this.users[user_id];
        if (!_this.users[user_id])
            _this.users[user_id] = {};
        var user = _this.users[user_id];

        _http.get("/api/closed/users/" + user_id)
            .then(function(result) {
                console.log(result.data);
                angular.copy(result.data.user, user);
            });
        return user;
    };

	this.update_user = function(data, user_id) {
		var _this = this;
		return _http.put("/api/closed/users/" + user_id, data)
		.then(function(result) {
			angular.copy(result.data.user, _this.user);
		});
	}

}]);<commit_msg>added comment data to user service<commit_after>var APP = angular.module('APP');
APP.service('_user', ['_http', function(_http) {
    var current_search = 0; //Keeps track of what search is currently active to prevent callbacks from overlapping each other

    this.user = {
        id: false
    };
    this.users = {}; //Users found in backend - May it be by search result or friends

    this.friend_requests = []; //Contains request made for other users
    this.friends_new = []; //Contains requests from other users
    this.friends = []; //Actual friends

    this.comments = []; //All comments that this user is involved with

    this.search_friends_result = []; //Users found for a current search

    this.is_email_valid = function(email) {
        var mailPattern = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        return mailPattern.test(email);
    };

    this.sign_in = function(data) {
        var _this = this;
        return _http.get("/api/open/user", data)
            .then(function(result) {
                angular.copy(result.data.user, _this.user);
                angular.copy(result.data.friend_requests, _this.friends);
                angular.copy(result.data.thread, _this.comments);
            });
    };

    this.create_user = function(data) {
        var _this = this;
        return _http.post('/api/open/user/', data)
            .then(function(result) {
                angular.copy(result.data.user, _this.user);
            });
    };

    this.sign_out = function() {
        return _http.get("/api/sign_out");
    };

    this.authenticate = function() {
        var _this = this;
        return _http.get("/api/open/user", null, {
                silent: true
            })
            .then(function(result) {
                angular.copy(result.data.user, _this.user);
                angular.copy(result.data.friend_requests, _this.friends);
                angular.copy(result.data.thread, _this.comments);
            });
    };

    this.find_friends = function(query) {
        var _this = this;

        current_search++;
        var cs = current_search;
        _http.get("/api/closed/friends/" + query, null, {
                silent: true
            })
            .then(function(result) {
                if (cs === current_search) {
                    var l = result.data.users.length;
                    for (var i = 0; i < l; i++) {
                        if (!_this.users[result.data.users[i].id]) {
                            _this.users[result.data.users[i].id] = result.data.users[i]
                        }
                    }
                    angular.copy(result.data.users, _this.search_friends_result);
                }
                console.log(_this.users);
            })
            .catch(function() {
                angular.copy([], _this.search_friends_result);
            })
    };

    this.add_friend = function(user_id) {
        var _this = this;
        _http.post("/api/closed/friends/" + user_id)
            .then(function(result) {
                _this.friends.push(result.data.friend_request);
            })
            .catch(function(err) {
                console.trace(err);
            });
    };

    this.get_friend = function(user_id) {
        var _this = this;
        if (_this.users[user_id])
            return _this.users[user_id];
        if (!_this.users[user_id])
            _this.users[user_id] = {};
        var user = _this.users[user_id];

        _http.get("/api/closed/users/" + user_id)
            .then(function(result) {
                console.log(result.data);
                angular.copy(result.data.user, user);
            });
        return user;
    };

	this.update_user = function(data, user_id) {
		var _this = this;
		return _http.put("/api/closed/users/" + user_id, data)
		.then(function(result) {
			angular.copy(result.data.user, _this.user);
		});
	}

}]);<|endoftext|>