<commit_before>import React, { createRef, PureComponent } from 'react';
import { findScrollParents } from '../../utils';
import { Box } from '../Box';

class InfiniteScroll extends PureComponent {
  static defaultProps = {
    items: [],
    step: 50,
  };

  static getDerivedStateFromProps(nextProps, prevState) {
    const { items, show, step } = nextProps;
    const lastPage = Math.ceil(items.length / step) - 1;
    if (
      prevState.beginPage === undefined ||
      ((show && show >= step * (prevState.lastPage + 1)) ||
        lastPage !== prevState.lastPage)
    ) {
      let endPage = prevState.endPage || 0;
      if (show && show >= step * (endPage + 1)) {
        endPage = Math.floor((show + step) / step) - 1;
      }
      return { beginPage: 0, endPage, lastPage, pageHeight: undefined };
    }
    return null;
  }

  state = {};

  initialScroll = false;

  aboveMarkerRef = createRef();

  belowMarkerRef = createRef();

  componentDidMount() {
    // ride out any animation, 100ms was chosen empirically
    clearTimeout(this.animationDelayTimer);
    this.animationDelayTimer = setTimeout(() => {
      this.setPageHeight();
      this.addScrollListener();
      this.scrollShow();
    }, 100);
  }

  componentDidUpdate() {
    this.setPageHeight();
    this.removeScrollListener();
    this.addScrollListener();
    this.scrollShow();
  }

  componentWillUnmount() {
    this.removeScrollListener();
    clearTimeout(this.animationDelayTimer);
    clearTimeout(this.scrollTimer);
  }

  addScrollListener = () => {
    const { pageHeight } = this.state;
    if (pageHeight && this.belowMarkerRef.current && !this.scrollParents) {
      this.scrollParents = findScrollParents(this.belowMarkerRef.current);
      this.scrollParents.forEach(scrollParent =>
        scrollParent.addEventListener('scroll', this.onScroll),
      );
    }
  };

  removeScrollListener = () => {
    if (this.scrollParents) {
      this.scrollParents.forEach(scrollParent =>
        scrollParent.removeEventListener('scroll', this.place),
      );
      this.scrollParents = undefined;
    }
  };

  scrollShow = () => {
    const { show } = this.props;
    if (show && !this.initialScroll && this.showRef) {
      this.initialScroll = true;
      // on initial render, scroll to any 'show'
      this.showRef.scrollIntoView();
    }
  };

  setPageHeight = () => {
    const { pageHeight } = this.state;
    if (this.firstPageItemRef && this.lasrtPageItemRef && !pageHeight) {
      const beginRect = this.firstPageItemRef.getBoundingClientRect();
      const endRect = this.lasrtPageItemRef.getBoundingClientRect();
      const nextPageHeight = endRect.y + endRect.height - beginRect.y;
      this.setState({ pageHeight: nextPageHeight });
    }
  };

  onScroll = () => {
    // The timer keeps us from re-rendering too much and getting slow
    clearTimeout(this.scrollTimer);
    this.scrollTimer = setTimeout(() => {
      const { onMore, replace } = this.props;
      const { beginPage, endPage, lastPage, pageHeight } = this.state;
      if (this.scrollParents && this.scrollParents[0] && pageHeight) {
        const scrollParent = this.scrollParents[0];
        // Determine the window into the first scroll parent
        let top;
        let height;
        if (scrollParent === document) {
          top = document.documentElement.scrollTop || document.body.scrollTop;
          height = window.innerHeight;
        } else {
          top = scrollParent.scrollTop;
          const rect = scrollParent.getBoundingClientRect();
          ({ height } = rect);
        }
        // Figure out which pages we should make visible based on the scroll
        // window.
        const offset = height / 4;
        const nextBeginPage = replace
          ? Math.min(
              lastPage,
              Math.max(0, Math.floor(Math.max(0, top - offset) / pageHeight)),
            )
          : 0;
        const nextEndPage = Math.min(
          lastPage,
          Math.max(
            (!replace && endPage) || 0,
            Math.floor((top + height + offset) / pageHeight),
          ),
        );
        if (nextBeginPage !== beginPage || nextEndPage !== endPage) {
          this.setState(
            { beginPage: nextBeginPage, endPage: nextEndPage },
            () => {
              if (onMore && nextEndPage === lastPage) {
                onMore();
              }
            },
          );
        }
      }
    }, 10); // 10ms was chosen empirically
  };

  render() {
    const {
      children,
      items,
      onMore,
      renderMarker,
      replace,
      show,
      step,
    } = this.props;
    const { beginPage, endPage, lastPage, pageHeight } = this.state;

    const firstIndex = beginPage * step;
    const lastIndex = (endPage + 1) * step - 1;

    const result = [];

    if (replace && pageHeight && firstIndex) {
      let marker = (
        <Box
          key="above"
          ref={this.aboveMarkerRef}
          flex={false}
          height={`${beginPage * pageHeight}px`}
        />
      );
      if (renderMarker) {
        // need to give it a key
        marker = React.cloneElement(renderMarker(marker), { key: 'above' });
      }
      result.push(marker);
    }

    items.slice(firstIndex, lastIndex + 1).forEach((item, index) => {
      let child = children(item, index);
      if (!pageHeight && index === 0) {
        const { ref } = child;
        child = React.cloneElement(child, {
          ref: node => {
            this.firstPageItemRef = node;
            if (typeof ref === 'function') {
              ref(node);
            }
          },
        });
      } else if (!pageHeight && index === step - 1) {
        const { ref } = child;
        child = React.cloneElement(child, {
          ref: node => {
            this.lasrtPageItemRef = node;
            if (typeof ref === 'function') {
              ref(node);
            }
          },
        });
      }
      if (show && show === index) {
        const { ref } = child;
        child = React.cloneElement(child, {
          key: 'show',
          ref: node => {
            this.showRef = node;
            if (typeof ref === 'function') {
              ref(node);
            }
          },
        });
      }
      result.push(child);
    });

    if (endPage < lastPage || replace || onMore) {
      let marker = (
        <Box
          key="below"
          ref={this.belowMarkerRef}
          flex={false}
          height={`${replace ? (lastPage - endPage) * pageHeight : 0}px`}
        />
      );
      if (renderMarker) {
        // need to give it a key
        marker = React.cloneElement(renderMarker(marker), { key: 'below' });
      }
      result.push(marker);
    }

    return result;
  }
}

let InfiniteScrollDoc;
if (process.env.NODE_ENV !== 'production') {
  InfiniteScrollDoc = require('./doc').doc(InfiniteScroll); // eslint-disable-line global-require
}
const InfiniteScrollWrapper = InfiniteScrollDoc || InfiniteScroll;

export { InfiniteScrollWrapper as InfiniteScroll };
<commit_msg>Remove scroll delay timer to speed up rendering<commit_after>import React, { createRef, PureComponent } from 'react';
import { findScrollParents } from '../../utils';
import { Box } from '../Box';

class InfiniteScroll extends PureComponent {
  static defaultProps = {
    items: [],
    step: 50,
  };

  static getDerivedStateFromProps(nextProps, prevState) {
    const { items, show, step } = nextProps;
    const lastPage = Math.ceil(items.length / step) - 1;
    if (
      prevState.beginPage === undefined ||
      ((show && show >= step * (prevState.lastPage + 1)) ||
        lastPage !== prevState.lastPage)
    ) {
      let endPage = prevState.endPage || 0;
      if (show && show >= step * (endPage + 1)) {
        endPage = Math.floor((show + step) / step) - 1;
      }
      return { beginPage: 0, endPage, lastPage, pageHeight: undefined };
    }
    return null;
  }

  state = {};

  initialScroll = false;

  aboveMarkerRef = createRef();

  belowMarkerRef = createRef();

  componentDidMount() {
    // ride out any animation, 100ms was chosen empirically
    clearTimeout(this.animationDelayTimer);
    this.animationDelayTimer = setTimeout(() => {
      this.setPageHeight();
      this.addScrollListener();
      this.scrollShow();
    }, 100);
  }

  componentDidUpdate() {
    this.setPageHeight();
    this.removeScrollListener();
    this.addScrollListener();
    this.scrollShow();
  }

  componentWillUnmount() {
    this.removeScrollListener();
    clearTimeout(this.animationDelayTimer);
    clearTimeout(this.scrollTimer);
  }

  addScrollListener = () => {
    const { pageHeight } = this.state;
    if (pageHeight && this.belowMarkerRef.current && !this.scrollParents) {
      this.scrollParents = findScrollParents(this.belowMarkerRef.current);
      this.scrollParents.forEach(scrollParent =>
        scrollParent.addEventListener('scroll', this.onScroll),
      );
    }
  };

  removeScrollListener = () => {
    if (this.scrollParents) {
      this.scrollParents.forEach(scrollParent =>
        scrollParent.removeEventListener('scroll', this.place),
      );
      this.scrollParents = undefined;
    }
  };

  scrollShow = () => {
    const { show } = this.props;
    if (show && !this.initialScroll && this.showRef) {
      this.initialScroll = true;
      // on initial render, scroll to any 'show'
      this.showRef.scrollIntoView();
    }
  };

  setPageHeight = () => {
    const { pageHeight } = this.state;
    if (this.firstPageItemRef && this.lasrtPageItemRef && !pageHeight) {
      const beginRect = this.firstPageItemRef.getBoundingClientRect();
      const endRect = this.lasrtPageItemRef.getBoundingClientRect();
      const nextPageHeight = endRect.y + endRect.height - beginRect.y;
      this.setState({ pageHeight: nextPageHeight });
    }
  };

  onScroll = () => {
    const { onMore, replace } = this.props;
    const { beginPage, endPage, lastPage, pageHeight } = this.state;
    if (this.scrollParents && this.scrollParents[0] && pageHeight) {
      const scrollParent = this.scrollParents[0];
      // Determine the window into the first scroll parent
      let top;
      let height;
      if (scrollParent === document) {
        top = document.documentElement.scrollTop || document.body.scrollTop;
        height = window.innerHeight;
      } else {
        top = scrollParent.scrollTop;
        const rect = scrollParent.getBoundingClientRect();
        ({ height } = rect);
      }
      // Figure out which pages we should make visible based on the scroll
      // window.
      const offset = height / 4;
      const nextBeginPage = replace
        ? Math.min(
            lastPage,
            Math.max(0, Math.floor(Math.max(0, top - offset) / pageHeight)),
          )
        : 0;
      const nextEndPage = Math.min(
        lastPage,
        Math.max(
          (!replace && endPage) || 0,
          Math.floor((top + height + offset) / pageHeight),
        ),
      );
      if (nextBeginPage !== beginPage || nextEndPage !== endPage) {
        this.setState(
          { beginPage: nextBeginPage, endPage: nextEndPage },
          () => {
            if (onMore && nextEndPage === lastPage) {
              onMore();
            }
          },
        );
      }
    }
  };

  render() {
    const {
      children,
      items,
      onMore,
      renderMarker,
      replace,
      show,
      step,
    } = this.props;
    const { beginPage, endPage, lastPage, pageHeight } = this.state;

    const firstIndex = beginPage * step;
    const lastIndex = (endPage + 1) * step - 1;

    const result = [];

    if (replace && pageHeight && firstIndex) {
      let marker = (
        <Box
          key="above"
          ref={this.aboveMarkerRef}
          flex={false}
          height={`${beginPage * pageHeight}px`}
        />
      );
      if (renderMarker) {
        // need to give it a key
        marker = React.cloneElement(renderMarker(marker), { key: 'above' });
      }
      result.push(marker);
    }

    items.slice(firstIndex, lastIndex + 1).forEach((item, index) => {
      let child = children(item, index);
      if (!pageHeight && index === 0) {
        const { ref } = child;
        child = React.cloneElement(child, {
          ref: node => {
            this.firstPageItemRef = node;
            if (typeof ref === 'function') {
              ref(node);
            }
          },
        });
      } else if (!pageHeight && index === step - 1) {
        const { ref } = child;
        child = React.cloneElement(child, {
          ref: node => {
            this.lasrtPageItemRef = node;
            if (typeof ref === 'function') {
              ref(node);
            }
          },
        });
      }
      if (show && show === index) {
        const { ref } = child;
        child = React.cloneElement(child, {
          key: 'show',
          ref: node => {
            this.showRef = node;
            if (typeof ref === 'function') {
              ref(node);
            }
          },
        });
      }
      result.push(child);
    });

    if (endPage < lastPage || replace || onMore) {
      let marker = (
        <Box
          key="below"
          ref={this.belowMarkerRef}
          flex={false}
          height={`${replace ? (lastPage - endPage) * pageHeight : 0}px`}
        />
      );
      if (renderMarker) {
        // need to give it a key
        marker = React.cloneElement(renderMarker(marker), { key: 'below' });
      }
      result.push(marker);
    }

    return result;
  }
}

let InfiniteScrollDoc;
if (process.env.NODE_ENV !== 'production') {
  InfiniteScrollDoc = require('./doc').doc(InfiniteScroll); // eslint-disable-line global-require
}
const InfiniteScrollWrapper = InfiniteScrollDoc || InfiniteScroll;

export { InfiniteScrollWrapper as InfiniteScroll };
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2017-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

const React = require('react')

const CompLibrary = require('../../core/CompLibrary.js')

const Container = CompLibrary.Container
const GridBlock = CompLibrary.GridBlock

function Help(props) {
  const { config: siteConfig, language = '' } = props
  const { baseUrl, docsUrl, slackUrl, repoUrl } = siteConfig
  const docsPart = `${docsUrl ? `${docsUrl}/` : ''}`
  const langPart = `${language ? `${language}/` : ''}`
  const docUrl = doc => `${baseUrl}${docsPart}${langPart}${doc}`

  const supportLinks = [
    {
      content: `Learn more using the [documentation on this site.](${docUrl('getting-started')})`,
      title: 'Browse Docs',
    },
    {
      content: `Ask questions about the documentation and project in [our Slack channel](${slackUrl})`,
      title: 'Join the community',
    },
    {
      content: `Believe you have found a bug? Please [open an issue](https://github.com/tulios/kafkajs/issues) describing the issue as clearly as you can.`,
      title: 'Open an issue',
    },
  ]

  return (

      <Container className="mainContainer documentContainer postContainer">

Need help?

            This free, open-source project is developed and maintained by a small group of
            volunteers. Please check if your question is answered already on the{' '}
            Frequently Asked Questions page or among the{' '}
            Github issues.

            If you're still unable to find a solution to your problem, feel free to check out the
            links below.

          <GridBlock contents={supportLinks} layout="threeColumn" />

      </Container>

  )
}

module.exports = Help
<commit_msg>Add commercial support option to help page<commit_after>/**
 * Copyright (c) 2017-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

const React = require('react')

const CompLibrary = require('../../core/CompLibrary.js')

const Container = CompLibrary.Container
const GridBlock = CompLibrary.GridBlock

function Help(props) {
  const { config: siteConfig, language = '' } = props
  const { baseUrl, docsUrl, slackUrl, repoUrl } = siteConfig
  const docsPart = `${docsUrl ? `${docsUrl}/` : ''}`
  const langPart = `${language ? `${language}/` : ''}`
  const docUrl = doc => `${baseUrl}${docsPart}${langPart}${doc}`

  const supportLinks = [
    {
      content: `Learn more using the [documentation on this site.](${docUrl('getting-started')})`,
      title: 'Browse Docs',
    },
    {
      content: `Ask questions about the documentation and project in [our Slack channel](${slackUrl})`,
      title: 'Join the community',
    },
    {
      content: `Commercial support is [available directly from the KafkaJS developers](${baseUrl}#support).`,
      title: 'Get dedicated support',
    },
    {
      content: `Believe you have found a bug? Please [open an issue](https://github.com/tulios/kafkajs/issues) describing the issue as clearly as you can.`,
      title: 'Open an issue',
    },
  ]

  return (

      <Container className="mainContainer documentContainer postContainer">

Need help?

            This free, open-source project is developed and maintained by a small group of
            volunteers. Please check if your question is answered already on the{' '}
            Frequently Asked Questions page or among the{' '}
            Github issues.

            If you're still unable to find a solution to your problem, feel free to check out the
            links below.

          <GridBlock contents={supportLinks} layout="fourColumn" />

      </Container>

  )
}

module.exports = Help
<|endoftext|>


<commit_before>const express = require('express');
const router = express.Router();
const Buffer = require('buffer/').Buffer;
const request = require('request');

let songs = [];

router.post('/login', function(req, res, next) {
  const body = (req.body);
  const authOptions = {
    url: 'https://accounts.spotify.com/api/token',
    form: {
      code: body.code,
      redirect_uri: body.redirect_uri,
      grant_type: 'authorization_code'
    },
    headers: {
      'Authorization': 'Basic ' + (new Buffer(body.client_id + ':' + body.client_secret).toString('base64')),
      'Accept': 'application/json',
      'Content-Type':'application/json'
    },
    json: true
  };
  request.post(authOptions, function(error, response, body) {
    let user_id;
    if (!error && response.statusCode === 200) {
      //make api request to retrieve user profile
      const access_token = response.body.access_token;
      const options = {
        headers: { 'Authorization': 'Bearer ' + access_token },
        json: true
      };

      // retreive user profile
      options['url'] = 'https://api.spotify.com/v1/me';

      request.get(options, (error, response, body) => {
        user_id = body.id;

        // retrieve current user's playlists
        options['url'] = 'https://api.spotify.com/v1/me/playlists';
        request.get(options, (error, response, body) => {
          const playlists = body.items.map((playlist) => playlist.id);

          // iterate thru each playlist to retrieve all songs
          playlists.map((playlist_id) => {
            options['url'] = `https://api.spotify.com/v1/users/${user_id}/playlists/${playlist_id}/tracks`;
            request.get(options, (error, response, body) => {
                songs = body.items.map((song) => song.track.id);
                res.send({ songs });
            });
          });
        });
      });

  } else res.send({ error });
  });
});

module.exports = router;
<commit_msg>refactor: set access_token as global var<commit_after>const express = require('express');
const router = express.Router();
const Buffer = require('buffer/').Buffer;
const request = require('request');

let songs = [];
let access_token = '';

router.post('/login', function(req, res, next) {
  const body = (req.body);
  const authOptions = {
    url: 'https://accounts.spotify.com/api/token',
    form: {
      code: body.code,
      redirect_uri: body.redirect_uri,
      grant_type: body.grant_type
    },
    headers: {
      'Authorization': 'Basic ' + (new Buffer(body.client_id + ':' + body.client_secret).toString('base64')),
      'Accept': 'application/json',
      'Content-Type':'application/json'
    },
    json: true
  };
  request.post(authOptions, function(error, response, body) {
    let user_id;
    if (!error && response.statusCode === 200) {
      //make api request to retrieve user profile
      access_token = response.body.access_token;
      const options = {
        headers: { 'Authorization': 'Bearer ' + access_token },
        json: true
      };

      // retreive user profile
      options['url'] = 'https://api.spotify.com/v1/me';

      request.get(options, (error, response, body) => {
        user_id = body.id;

        // retrieve current user's playlists
        options['url'] = 'https://api.spotify.com/v1/me/playlists';
        request.get(options, (error, response, body) => {
          const playlists = body.items.map((playlist) => playlist.id);

          // iterate thru each playlist to retrieve all songs
          playlists.map((playlist_id) => {
            options['url'] = `https://api.spotify.com/v1/users/${user_id}/playlists/${playlist_id}/tracks`;
            request.get(options, (error, response, body) => {
                songs = body.items.map((song) => song.track.id);
                res.send({ songs });
            });
          });
        });
      });

  } else res.send({ error });
  });
});

module.exports = router;
<|endoftext|>


<commit_before>#!/usr/bin/env node

var fs = require('fs');
var program = require('commander');
var exec = require('child_process').exec;

var walk = function(dir) {
    var results = []
    var list = fs.readdirSync(dir)
    list.forEach(function(file) {
        var ext = file.split('.');
        var isJs = ext[ext.length - 1] === "js";
        if (isJs) {
            file = dir + '/' + file
            var stat = fs.statSync(file)
            if (stat && stat.isDirectory()) results = results.concat(walk(file))
            else results.push(file)
        }
    })
    return results
}

var parseJsFiles = function(dir){
  console.log(typeof(dir));
  // var fileList = walk(dir);
  // fileList.forEach((file)=>{
  //   child_process.execSync(jscodeshift,['-t','transform.js','file','-p','-d'])
  // })
}

var rewrite = function(fileList){

}

program
  .command('dir [dir]')
  .description('Give the directory to remove console.log')
  .action(function(dir){
    var fileList = walk(dir);
    fileList.forEach((file)=>{
      // execSync('jscodeshift',['-t','transform.js','file','-p','-d']);
      exec(`jscodeshift -t transform.js ${file} -p -d`, function(err,stdout, stderr ){
        console.log(stdout);
      });
    })
  });

//
program
  .version('0.0.1')
  .option('-o, --ovr', 'Original files will be overwritten with output')
  .parse(process.argv);
<commit_msg>more modular code<commit_after>#!/usr/bin/env node

const fs = require('fs');
const program = require('commander');
const exec = require('child_process').exec;

const walk = (dir) => {
    var results = []
    var list = fs.readdirSync(dir)
    list.forEach(function(file) {
        var ext = file.split('.');
        var isJs = ext[ext.length - 1] === "js";
        if (isJs) {
            file = dir + '/' + file
            var stat = fs.statSync(file)
            if (stat && stat.isDirectory()) results = results.concat(walk(file))
            else results.push(file)
        }
    })
    return results
}

const removeFromDir = (dir) => {
    var fileList = walk(dir);
    fileList.forEach((file) => {
        exec(`jscodeshift -t transform.js ${file} -p -d`, function(err, stdout, stderr) {
            (err) ? console.log(stderr): console.log(stdout);;
        });
    });
}

const removeFromFile = (file) => {
  exec(`jscodeshift -t transform.js ${file} -p -d`, function(err, stdout, stderr) {
      (err) ? console.log(stderr): console.log(stdout);;
  });
}
program
    .command('dir [dir]')
    .description('Give the directory to remove console.log')
    .action(function(dir) {
        removeFromDir(dir);
    });

program
    .command('current')
    .description('takes the current directory to remove logs')
    .action(function() {
        removeFromDir(__dirname);
    });

program
    .command('file [path]')
    .description('Give the directory to remove console.log')
    .action(function(path) {
        removeFromFile();
    });

program
    .version('0.0.1')
    .option('-o, --ovr', 'Original files will be overwritten with output')
    .parse(process.argv);
<|endoftext|>


<commit_before>/**
 * @author Anthony
 * created on Oct 17, 2017
 */
(function() {
  'use strict';
  angular.module('GasNinjasAdmin.pages.orders')
    .controller('OrderCompleteCtrl', OrderCompleteCtrl);

  function OrderCompleteCtrl($scope, $state, $q, $timeout, $ngBootbox, $stateParams, $window, toastr, lodash, appConfig, UserService, OrderService) {
    $scope.onDataLoaded = fnOnDataLoaded;
    $scope.onDataLoadFailed = fnOnDataLoadFailed;
    $scope.next = fnNext;
    $scope.suspend = fnSuspend;
    $scope.refillMore = fnRefillMore;
    $scope.completeRefill = fnCompleteRefill;
    $scope.moveScroll = fnMoveScroll;
    $scope.increasePanelBody = fnIncreasePanelBody;

    $scope.isSubmitting = false;
    $scope.today = new Date();

    $q.all([
      OrderService.getOrderInfo({ id: $stateParams.order_id }).$promise,
      UserService.getUserInfo({ id: $stateParams.user_id }).$promise
    ]).then($scope.onDataLoaded).catch($scope.onDataLoadFailed);

    function fnOnDataLoaded(data) {
      $scope.order = data[0];
      $scope.user = data[1].user;
      $scope.vehicles = {
        list: $scope.user.vehicles,
        page: 1,
        selected: $scope.user.vehicles.length ? $scope.user.vehicles[0] : null,
        loading: false,
        hasMore: false
      };
      $scope.refills = [];

      // Check if the order is not fulfilled yet.
      if ($scope.order.status == 5 || $scope.order.status == 10) {
        toastr.error('The order has been already ' + ($scope.order.status == 10 ? 'completed.' : 'canceled.'));
        $state.go('dashboard');
        return;
      } else if ($scope.order.status !== 1) {
        toastr.error('Failed to load the order details from the server.');
        $state.go('dashboard');
        return;
      }

      $scope.isNumpadOpen = true;
      $("input.numpad-input").numpad({
        hidePlusMinusButton: true,
        decimalSeparator: '.',
        appendKeypadTo: $('#numpad_container'),
        position: 'absolute',
        textCancel: 'Close',
        onKeypadOpen: function() {
          $timeout(function() {
            $scope.isNumpadOpen = true;
            $scope.$apply();
          });
        },
        onKeypadClose: function() {
          $timeout(function() {
            $scope.isNumpadOpen = false;
            $scope.$apply();
          });
        },
        onChange: function(event, value) {
          $timeout(function() {
            if (!value)
              $scope.vehicles.selected.gallon = "";
            else
              $scope.vehicles.selected.gallon = parseFloat(value).toFixed(2);
            $scope.$apply();
          });
        }
      });
      $timeout(function() {
        $scope.moveScroll();
        $scope.increasePanelBody();
        $("input.numpad-input").click();
      });

      $scope.$watch('refills', function(newVal, oldVal) {
        if (newVal == oldVal) return;

        var vehicles_unfiled = [];
        angular.forEach($scope.user.vehicles, function(vehicle, index) {
          var objRefill = $scope.refills.find(function(object) {
            return object.vehicle_id === vehicle.id;
          });
          if (!objRefill) {
            vehicles_unfiled.push(vehicle);
          }
        });

        $scope.vehicles.list = vehicles_unfiled;
        $scope.vehicles.selected = vehicles_unfiled.length ? vehicles_unfiled[0] : null;
      }, true);
    }

    function fnOnDataLoadFailed() {
      toastr.error('Failed to load the order details from the server.');
      $state.go('dashboard');
    }

    function fnMoveScroll() {
      var elemBreadcrumb = angular.element('.breadcrumb')[0];
      var elemPanelHeading = angular.element('.panel-heading')[0];
      if (typeof elemBreadcrumb != "undefined" && typeof elemPanelHeading != "undefined") {
        var rectBreadcrumb = elemBreadcrumb.getBoundingClientRect();
        var rectPanelHeading = elemPanelHeading.getBoundingClientRect();
        var doc = elemBreadcrumb.ownerDocument;
        var docElem = doc.documentElement;
        var top = rectBreadcrumb.top + $window.pageYOffset + docElem.clientTop;
        //iPhone5
        if (docElem.clientWidth <= 430) {
          top+= rectPanelHeading.height + 60;
        } else {
          top-= 10;
        }
        window.scrollTo(0, top);

        // blur the navigation bar
        angular.element('.page-top').addClass('transparent-bg');
      };
    }

    function fnIncreasePanelBody() {
      var elemPanelBody = angular.element('.full-height .panel-body')[0];
      if (typeof elemPanelBody != "undefined") {
        var rectPanelBody = elemPanelBody.getBoundingClientRect();
        var doc = elemPanelBody.ownerDocument;
        var docElem = doc.documentElement;
        var vertical_space = docElem.clientHeight - rectPanelBody.height;
        var threshold = 270;
        //iPad
        if (docElem.clientWidth <= 768) {
          threshold = 250;
        }

        if (vertical_space - threshold > 0) {
          var new_height = rectPanelBody.height + vertical_space - threshold;
          angular.element('.full-height .panel-body').css('height', new_height + 'px');
        }
      }
    }

    function fnNext() {
      var options = {
        message: 'Are you sure to complete the order?',
        title: 'Complete Order',
        onEscape: function() {},
        scope: $scope,
        animate: true,
        backdrop: false,
        buttons: {
          warning: {
            label: $scope.vehicles.list.length > 1 ? "More Vehicles" : "Not Yet",
            className: "btn-default",
            callback: $scope.refillMore
          },
          success: {
            label: "Complete",
            className: "btn-primary",
            callback: $scope.completeRefill
          }
        }
      };

      $ngBootbox.customDialog(options);
    }

    function fnSuspend() {
      $ngBootbox.confirm('Are you sure you want to suspend this task on the Onfleet?')
        .then(function() {
          $scope.isSubmitting = true;

          OrderService.suspendOrder({ id: $scope.order.id }, fnCallbackSuspendOrder);
        });
    }

    function fnCompleteRefill() {
      $scope.refills.push({
        vehicle_id: $scope.vehicles.selected.id,
        vehicle_tag: $scope.vehicles.selected.tag,
        gas_type: $scope.vehicles.selected.gas_type,
        gallon: $scope.vehicles.selected.gallon,
      });

      var data = {
        success: true,
        notes: ""
      };

      angular.forEach($scope.refills, function(item, index) {
        if (index > 0) data.notes += "\n";
        data.notes += item.gallon + " GAL " + item.gas_type + " " + item.vehicle_tag;
      });

      $scope.isSubmitting = true;
      OrderService.completeOrder({ id: $scope.order.id }, data, fnCallbackCompleteOrder);
    }

    function fnRefillMore() {
      if ($scope.vehicles.list.length > 1) {
        $timeout(function() {
          $scope.$apply(function() {
            $scope.refills.push({
              vehicle_id: $scope.vehicles.selected.id,
              vehicle_tag: $scope.vehicles.selected.tag,
              gas_type: $scope.vehicles.selected.gas_type,
              gallon: $scope.vehicles.selected.gallon,
            });
          });
        });
      }
    }

    function fnCallbackCompleteOrder(result) {
      $scope.isSubmitting = false;

      if (result.success == 1) {
        toastr.info('Successfully completed the order!');
        $state.go('dashboard');
      } else {
        $timeout(function() {
          $scope.$apply(function() {
            $scope.refills = [];

          });
        });
        toastr.error(result.message ? result.message : 'Failed to complete the order!');
      }
    }

    function fnCallbackSuspendOrder(result) {
      $scope.isSubmitting = false;

      if (result.success == 1) {
        toastr.info('Successfully suspended the Onfleet Task!');
        $state.go('dashboard');
      } else {
        toastr.error(result.message ? result.message : 'Failed to suspend the Onfleet task!');
      }
    }
  }
})();<commit_msg>fix(DriverInterface-Numpad): scroll down on the android nexus<commit_after>/**
 * @author Anthony
 * created on Oct 17, 2017
 */
(function() {
  'use strict';
  angular.module('GasNinjasAdmin.pages.orders')
    .controller('OrderCompleteCtrl', OrderCompleteCtrl);

  function OrderCompleteCtrl($scope, $state, $q, $timeout, $ngBootbox, $stateParams, $window, toastr, lodash, appConfig, UserService, OrderService) {
    $scope.onDataLoaded = fnOnDataLoaded;
    $scope.onDataLoadFailed = fnOnDataLoadFailed;
    $scope.next = fnNext;
    $scope.suspend = fnSuspend;
    $scope.refillMore = fnRefillMore;
    $scope.completeRefill = fnCompleteRefill;
    $scope.moveScroll = fnMoveScroll;
    $scope.increasePanelBody = fnIncreasePanelBody;

    $scope.isSubmitting = false;
    $scope.today = new Date();

    $q.all([
      OrderService.getOrderInfo({ id: $stateParams.order_id }).$promise,
      UserService.getUserInfo({ id: $stateParams.user_id }).$promise
    ]).then($scope.onDataLoaded).catch($scope.onDataLoadFailed);

    function fnOnDataLoaded(data) {
      $scope.order = data[0];
      $scope.user = data[1].user;
      $scope.vehicles = {
        list: $scope.user.vehicles,
        page: 1,
        selected: $scope.user.vehicles.length ? $scope.user.vehicles[0] : null,
        loading: false,
        hasMore: false
      };
      $scope.refills = [];

      // Check if the order is not fulfilled yet.
      if ($scope.order.status == 5 || $scope.order.status == 10) {
        toastr.error('The order has been already ' + ($scope.order.status == 10 ? 'completed.' : 'canceled.'));
        $state.go('dashboard');
        return;
      } else if ($scope.order.status !== 1) {
        toastr.error('Failed to load the order details from the server.');
        $state.go('dashboard');
        return;
      }

      $scope.isNumpadOpen = true;
      $("input.numpad-input").numpad({
        hidePlusMinusButton: true,
        decimalSeparator: '.',
        appendKeypadTo: $('#numpad_container'),
        position: 'absolute',
        textCancel: 'Close',
        onKeypadOpen: function() {
          $timeout(function() {
            $scope.isNumpadOpen = true;
            $scope.$apply();
          });
        },
        onKeypadClose: function() {
          $timeout(function() {
            $scope.isNumpadOpen = false;
            $scope.$apply();
          });
        },
        onChange: function(event, value) {
          $timeout(function() {
            if (!value)
              $scope.vehicles.selected.gallon = "";
            else
              $scope.vehicles.selected.gallon = parseFloat(value).toFixed(2);
            $scope.$apply();
          });
        }
      });
      $timeout(function() {
        $scope.increasePanelBody();
        $scope.moveScroll();
        $("input.numpad-input").click();
      });

      $scope.$watch('refills', function(newVal, oldVal) {
        if (newVal == oldVal) return;

        var vehicles_unfiled = [];
        angular.forEach($scope.user.vehicles, function(vehicle, index) {
          var objRefill = $scope.refills.find(function(object) {
            return object.vehicle_id === vehicle.id;
          });
          if (!objRefill) {
            vehicles_unfiled.push(vehicle);
          }
        });

        $scope.vehicles.list = vehicles_unfiled;
        $scope.vehicles.selected = vehicles_unfiled.length ? vehicles_unfiled[0] : null;
      }, true);
    }

    function fnOnDataLoadFailed() {
      toastr.error('Failed to load the order details from the server.');
      $state.go('dashboard');
    }

    function fnMoveScroll() {
      var elemBreadcrumb = angular.element('.breadcrumb')[0];
      var elemPanelHeading = angular.element('.panel-heading')[0];
      if (typeof elemBreadcrumb != "undefined" && typeof elemPanelHeading != "undefined") {
        var rectBreadcrumb = elemBreadcrumb.getBoundingClientRect();
        var rectPanelHeading = elemPanelHeading.getBoundingClientRect();
        var doc = elemBreadcrumb.ownerDocument;
        var docElem = doc.documentElement;
        var top = rectBreadcrumb.top + $window.pageYOffset + docElem.clientTop;
        //iPhone5
        if (docElem.clientWidth <= 430) {
          top+= rectPanelHeading.height + 30;
        } else {
          top-= 10;
        }
        window.scrollTo(0, top);

        // blur the navigation bar
        angular.element('.page-top').addClass('transparent-bg');
      };
    }

    function fnIncreasePanelBody() {
      var elemPanelBody = angular.element('.full-height .panel-body')[0];
      if (typeof elemPanelBody != "undefined") {
        var doc = elemPanelBody.ownerDocument;
        var docElem = doc.documentElement;
        var vertical_space = docElem.clientHeight - elemPanelBody.clientHeight;
        var threshold = 270;
        //iPad
        if (docElem.clientWidth <= 768) {
          threshold = 250;
        }

        if (vertical_space - threshold > 0) {
          var new_height = elemPanelBody.clientHeight + vertical_space - threshold;
          angular.element('.full-height .panel-body').css('height', new_height + 'px');
        }
      }
    }

    function fnNext() {
      var options = {
        message: 'Are you sure to complete the order?',
        title: 'Complete Order',
        onEscape: function() {},
        scope: $scope,
        animate: true,
        backdrop: false,
        buttons: {
          warning: {
            label: $scope.vehicles.list.length > 1 ? "More Vehicles" : "Not Yet",
            className: "btn-default",
            callback: $scope.refillMore
          },
          success: {
            label: "Complete",
            className: "btn-primary",
            callback: $scope.completeRefill
          }
        }
      };

      $ngBootbox.customDialog(options);
    }

    function fnSuspend() {
      $ngBootbox.confirm('Are you sure you want to suspend this task on the Onfleet?')
        .then(function() {
          $scope.isSubmitting = true;

          OrderService.suspendOrder({ id: $scope.order.id }, fnCallbackSuspendOrder);
        });
    }

    function fnCompleteRefill() {
      $scope.refills.push({
        vehicle_id: $scope.vehicles.selected.id,
        vehicle_tag: $scope.vehicles.selected.tag,
        gas_type: $scope.vehicles.selected.gas_type,
        gallon: $scope.vehicles.selected.gallon,
      });

      var data = {
        success: true,
        notes: ""
      };

      angular.forEach($scope.refills, function(item, index) {
        if (index > 0) data.notes += "\n";
        data.notes += item.gallon + " GAL " + item.gas_type + " " + item.vehicle_tag;
      });

      $scope.isSubmitting = true;
      OrderService.completeOrder({ id: $scope.order.id }, data, fnCallbackCompleteOrder);
    }

    function fnRefillMore() {
      if ($scope.vehicles.list.length > 1) {
        $timeout(function() {
          $scope.$apply(function() {
            $scope.refills.push({
              vehicle_id: $scope.vehicles.selected.id,
              vehicle_tag: $scope.vehicles.selected.tag,
              gas_type: $scope.vehicles.selected.gas_type,
              gallon: $scope.vehicles.selected.gallon,
            });
          });
        });
      }
    }

    function fnCallbackCompleteOrder(result) {
      $scope.isSubmitting = false;

      if (result.success == 1) {
        toastr.info('Successfully completed the order!');
        $state.go('dashboard');
      } else {
        $timeout(function() {
          $scope.$apply(function() {
            $scope.refills = [];

          });
        });
        toastr.error(result.message ? result.message : 'Failed to complete the order!');
      }
    }

    function fnCallbackSuspendOrder(result) {
      $scope.isSubmitting = false;

      if (result.success == 1) {
        toastr.info('Successfully suspended the Onfleet Task!');
        $state.go('dashboard');
      } else {
        toastr.error(result.message ? result.message : 'Failed to suspend the Onfleet task!');
      }
    }
  }
})();<|endoftext|>


<commit_before>import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';

const { run } = Ember;
const { isFunction } = window.QUnit;

let component;

moduleForComponent('flash-message-queue', 'Unit | Component | flash message queue component', {
  unit: true,
  needs: ['component:flash-message', 'service:flash-message-queue'],

  beforeEach() {
    component = this.subject({
      flashMessageQueue: Ember.inject.service(),
    });
  },

  afterEach() {
    run(function() {
      component.clear();
    });
  }
});

/* Test the correct data attribtues are set on the component for testing */

test('Data test attribute', function(assert) {

  assert.ok(component.get('dataTest'),
    'Component should have a dataTest property');

  assert.equal(this.$().attr('data-test'), 'flash-message-queue',
    'Component should have a data-test attribute');

});

/* Default component functionality */

test('Default properties and methods', function(assert) {

  /* Check properties */

  const required = ['className', 'interval', 'flashMessageQueue'];

  required.forEach(function(property) {

    assert.ok(!!component.get(property),
      'Component should have a default value for ' + property);

  });

  assert.ok(this.$().hasClass(component.get('className')),
    'Component element should have default class name');

  assert.strictEqual(component.get('shouldShow'), false,
    'shouldShow should be false by default');

  /* Check methods */

  ['clear', 'getQueueLength'].forEach(function(method) {

    isFunction(component[method],
      'Component should have a ' + method + ' method');

  });

});
<commit_msg>shouldShow passing<commit_after>import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';

const { run } = Ember;
const { isFunction } = window.QUnit;

let component;

moduleForComponent('flash-message-queue', 'Unit | Component | flash message queue component', {
  unit: true,
  needs: ['component:flash-message', 'service:flash-message-queue'],

  beforeEach() {
    component = this.subject({
      flashMessageQueue: Ember.inject.service(),
    });
  },

  afterEach() {
    run(function() {
      component.clear();
    });
  }
});

/* Test the correct data attribtues are set on the component for testing */

test('Data test attribute', function(assert) {

  assert.ok(component.get('dataTest'),
    'Component should have a dataTest property');

  assert.equal(this.$().attr('data-test'), 'flash-message-queue',
    'Component should have a data-test attribute');

});

/* Default component functionality */

test('Default properties and methods', function(assert) {

  /* Check properties */

  const required = ['className', 'interval', 'flashMessageQueue'];

  required.forEach(function(property) {

    assert.ok(!!component.get(property),
      'Component should have a default value for ' + property);

  });

  assert.ok(this.$().hasClass(component.get('className')),
    'Component element should have default class name');

  assert.notOk(component.get('shouldShow'),
    'shouldShow should be false by default');

  /* Check methods */

  ['clear', 'getQueueLength'].forEach(function(method) {

    isFunction(component[method],
      'Component should have a ' + method + ' method');

  });

});
<|endoftext|>


<commit_before>"use strict";

var assert = require('assert');

var calculateScore = function(guess, secret) {
    var cows = 0;
    var bulls = 0;

    for (var i=0;i<secret.length;++i) {
	var secretChar = secret[i];
	var found = guess.indexOf(secretChar);
	if (found === i)
	    bulls++
	else if (found !== -1)
	    cows++;
    }

    return { cows: cows, bulls: bulls };
};

describe('cows and bulls', function() {
    describe('scoring', function() {
	it('no matches scores zero cows and bulls', function() {
	    var score = calculateScore('1234','5678');

	    assert.equal(score.cows, 0);
	    assert.equal(score.bulls, 0);
	});

	it('single match in wrong place scores one cows', function() {
	    var score = calculateScore('1234', '5671');

	    assert.equal(score.cows, 1);
	    assert.equal(score.bulls, 0);
	});

	it('single match in right place scores one bull', function() {
	    var score = calculateScore('1234', '1567');

	    assert.equal(score.cows, 0);
	    assert.equal(score.bulls, 1);
	});
    });
});
<commit_msg>refactor tests<commit_after>"use strict";

var assert = require('assert');

var calculateScore = function(guess, secret) {
    var cows = 0;
    var bulls = 0;

    for (var i=0;i<secret.length;++i) {
	var secretChar = secret[i];
	var found = guess.indexOf(secretChar);
	if (found === i)
	    bulls++
	else if (found !== -1)
	    cows++;
    }

    return { cows: cows, bulls: bulls };
};

describe('cows and bulls', function() {
    describe('scoring', function() {
	var assertCowsAndBulls = function(expected, actual) {
	    assert.equal(actual.cows, expected.cows);
	    assert.equal(actual.bulls, expected.bulls);
	};

	it('no matches scores zero cows and bulls', function() {
	    var score = calculateScore('1234','5678');
	    assertCowsAndBulls({cows: 0, bulls: 0}, score);
	});

	it('single match in wrong place scores one cows', function() {
	    var score = calculateScore('1234', '5671');
	    assertCowsAndBulls({cows: 1, bulls: 0}, score);
	});

	it('single match in right place scores one bull', function() {
	    var score = calculateScore('1234', '1567');
	    assertCowsAndBulls({cows: 0, bulls: 1}, score);
	});
    });
});
<|endoftext|>


<commit_before>/* global describe, it, expect, Promise, beforeEach, afterEach */
describe('iframe launcher', function() {
  var launcher;

  //WebComponentsReady event is
  //fired only once after custom elments polyfill finished its start up tasks
  //all subequent upgrades are done by MutationObserver hence no more events
  var promise = new Promise(function(resolve, reject){
    window.addEventListener('WebComponentsReady', function() {
      resolve();
    });
  });

  beforeEach(function(done) {
    launcher = document.createElement('versal-component-launcher');
    launcher.setAttribute('data-config', '{"test": "initial-config"}');
    launcher.setAttribute('src', '/base/component-launcher/test/test_gadget.html');
    document.body.appendChild(launcher);

    promise.then(function(){
      done();
    });
  });

  afterEach(function() {
    document.body.removeChild(launcher);
  });

  it("inits one versal-component-launcher with one vs-texthd", function() {
    expect(document.querySelectorAll('versal-component-launcher').length).to.equal(1);
    expect(document.querySelectorAll('vs-texthd').length).to.equal(1);
  });

  it("inits versal-component-launcher with default config", function() {
    var launcherInstance = document.querySelector('versal-component-launcher');
    expect( launcherInstance.getAttribute('data-config') ).to.equal( '{"test": "initial-config"}' );
    expect( launcherInstance.getAttribute('src') ).to.equal( '/base/component-launcher/test/test_gadget.html' );
  });

  it("inits vs-texthd with default config", function() {
    var vsTest = document.querySelector('vs-texthd');
    expect( vsTest.getAttribute('data-config') ).to.equal( '{"test": "initial-config"}' );
  });

  it("child -> launcher, launcher fires 'setAttributes' event when child changes config by itself", function(done) {
    var newConfig = {"test": "changed"};

    launcher.addEventListener('setAttributes', function(payload){
      var detail = payload.detail;
      expect(detail).to.deep.equal(newConfig);
      done();
    }, false);

    var vsTest = document.querySelector('vs-texthd');
    vsTest.setAttribute('data-config', JSON.stringify(newConfig));
  });

  it("launcher -> child, passes data-config to vs-texthd when the launcher changes its config", function(done) {
    var newConfig = {"test": "changed"};

    var vsTest = document.querySelector('vs-texthd');
    vsTest.attributeChangedCallback = function(attrName, oldVal, newVal){
      expect( JSON.parse(newVal) ).to.deep.equal(newConfig);
      done();
    };

    launcher.setAttribute('data-config', JSON.stringify(newConfig));
  });

  it("launcher -> child, child should NOT trigger 'setAttributes' when the launcher changes its config", function(done) {
    var errTimeout = setTimeout(function(){
      expect(true).to.equal(true, 'this should be invoked when tests are passing');
      done();
    }, 100);

    var newConfig = {"test": "changed"};

    launcher.addEventListener('setAttributes', function(){
      clearTimeout(errTimeout);
      expect(false).to.equal(true, 'setAttributes should NOT be fired');
      done();
    }, false);

    launcher.setAttribute('data-config', JSON.stringify(newConfig));
  });

  it("launcher -> child, passes editable to vs-texthd", function(done) {
    var vsTest = document.querySelector('vs-texthd');
    vsTest.attributeChangedCallback = function(attrName, oldVal, newVal){
      expect( attrName ).to.equal('editable');
      expect( oldVal ).to.equal(null);
      expect( newVal ).to.equal('true');
      done();
    };

    launcher.setAttribute('editable', 'true');
  });

  it("launcher -> child, passes non-editable to vs-texthd", function(done) {
    var vsTest = document.querySelector('vs-texthd');
    launcher.setAttribute('editable', 'true');

    vsTest.attributeChangedCallback = function(attrName, oldVal, newVal){
      expect( attrName ).to.equal('editable');
      expect( oldVal ).to.equal('true');
      expect( newVal ).to.equal(null);
      done();
    };

    launcher.removeAttribute('editable');
  });
});
<commit_msg>Del test<commit_after>/* global describe, it, expect, Promise, beforeEach, afterEach */
describe('iframe launcher', function() {
  var launcher;

  //WebComponentsReady event is
  //fired only once after custom elments polyfill finished its start up tasks
  //all subequent upgrades are done by MutationObserver hence no more events
  var promise = new Promise(function(resolve, reject){
    window.addEventListener('WebComponentsReady', function() {
      resolve();
    });
  });

  beforeEach(function(done) {
    launcher = document.createElement('versal-component-launcher');
    launcher.setAttribute('data-config', '{"test": "initial-config"}');
    launcher.setAttribute('src', '/base/component-launcher/test/test_gadget.html');
    document.body.appendChild(launcher);

    promise.then(function(){
      done();
    });
  });

  afterEach(function() {
    document.body.removeChild(launcher);
  });

  it("inits one vs-texthd", function() {
    expect(document.querySelectorAll('vs-texthd').length).to.equal(1);
  });

  it("inits vs-texthd with default config", function() {
    var vsTest = document.querySelector('vs-texthd');
    expect( vsTest.getAttribute('data-config') ).to.equal( '{"test": "initial-config"}' );
  });

  it("child -> launcher, launcher fires 'setAttributes' event when child changes config by itself", function(done) {
    var newConfig = {"test": "changed"};

    launcher.addEventListener('setAttributes', function(payload){
      var detail = payload.detail;
      expect(detail).to.deep.equal(newConfig);
      done();
    }, false);

    var vsTest = document.querySelector('vs-texthd');
    vsTest.setAttribute('data-config', JSON.stringify(newConfig));
  });

  it("launcher -> child, passes data-config to vs-texthd when the launcher changes its config", function(done) {
    var newConfig = {"test": "changed"};

    var vsTest = document.querySelector('vs-texthd');
    vsTest.attributeChangedCallback = function(attrName, oldVal, newVal){
      expect( JSON.parse(newVal) ).to.deep.equal(newConfig);
      done();
    };

    launcher.setAttribute('data-config', JSON.stringify(newConfig));
  });

  it("launcher -> child, child should NOT trigger 'setAttributes' when the launcher changes its config", function(done) {
    var errTimeout = setTimeout(function(){
      expect(true).to.equal(true, 'this should be invoked when tests are passing');
      done();
    }, 100);

    var newConfig = {"test": "changed"};

    launcher.addEventListener('setAttributes', function(){
      clearTimeout(errTimeout);
      expect(false).to.equal(true, 'setAttributes should NOT be fired');
      done();
    }, false);

    launcher.setAttribute('data-config', JSON.stringify(newConfig));
  });

  it("launcher -> child, passes editable to vs-texthd", function(done) {
    var vsTest = document.querySelector('vs-texthd');
    vsTest.attributeChangedCallback = function(attrName, oldVal, newVal){
      expect( attrName ).to.equal('editable');
      expect( oldVal ).to.equal(null);
      expect( newVal ).to.equal('true');
      done();
    };

    launcher.setAttribute('editable', 'true');
  });

  it("launcher -> child, passes non-editable to vs-texthd", function(done) {
    var vsTest = document.querySelector('vs-texthd');
    launcher.setAttribute('editable', 'true');

    vsTest.attributeChangedCallback = function(attrName, oldVal, newVal){
      expect( attrName ).to.equal('editable');
      expect( oldVal ).to.equal('true');
      expect( newVal ).to.equal(null);
      done();
    };

    launcher.removeAttribute('editable');
  });
});
<|endoftext|>


<commit_before>(function($) {
  var NumberProgressBar = function(element, options) {
    var settings = $.extend ({
      duration: 10000,
      min: 0,
      max: 100,
      current: 0,
      shownQuery: '.number-pb-shown',
      numQuery: '.number-pb-num'
    }, options || {});

    this.duration = settings.duration;
    if (settings.min < settings.max) {
      this.min = settings.min;
      this.max = settings.max;
      this.current = (settings.current >= this.min && settings.current <= this.max) ? settings.current : this.min;
    } else {
      this.min = 0;
      this.max = 100;
      this.current = 0;
    }
    this.interval = this.max - this.min;
    this.last = null;
    this.$element = $(element);
    this.$shownBar = this.$element.find(settings.shownQuery);
    this.$num = this.$element.find(settings.numQuery);

    this.reach(this.current);
  }

  NumberProgressBar.prototype.calDestination = function(dest) {
    return (dest < this.min) ? this.min : ( (dest > this.max) ? this.max : dest )
  }

  NumberProgressBar.prototype.udpateLast = function(dest) {
    if (this.last == null) {
      this.last = this.min;
    } else {
      this.last = this.current;
    }
  }

  NumberProgressBar.prototype.calDuration = function() {
    return this.duration * Math.abs(this.current - this.last) / this.interval;
  }

  NumberProgressBar.prototype.shuffle = function(callback) {
    var dest = Math.round(Math.random() * this.interval) + this.min;
    this.reach(dest, null, callback);
  }

  NumberProgressBar.prototype.calPercentage = function() {
    return (this.current - this.min) / this.interval * 100
  }

  NumberProgressBar.prototype.reach = function(dest, duration, callback) {
    this.udpateLast();
    this.current = this.calDestination(dest);
    this.moveShown(duration);
    this.moveNum(duration, callback);
  }

  NumberProgressBar.prototype.moveShown = function(duration) {
    this.$shownBar.velocity({
      width: this.calPercentage() + '%'
    }, {
      duration: duration || this.calDuration()
    })
  }

  NumberProgressBar.prototype.moveNum = function(duration, callback) {
    var self = this;
    var duration = duration || this.calDuration();

    this.$num.velocity({
      left: this.calPercentage() + '%'
    }, {
      duration: duration,
      complete: callback
    });

    // number
    $({num: this.last}).animate({
      num: this.current
    }, {
      queue: true,
      duration: duration,
      step: function() {
        self.$num.text(Math.ceil(this.num));
      },
      complete: function() {
        self.$num.text(self.current);
      }
    })
  }

  $.fn.NumberProgressBar = function(options) {
    return this.each(function () {
      var element = $(this);
      if (element.data('number-pb')) return;
      element.data('number-pb', new NumberProgressBar(this, options));
    })
  }

  $.fn.reach = function(dest, options) {
    var settings = $.extend ({
      duration : null,
      complete : null
    }, options || {});
    return this.each(function() {
      var element = $(this);
      var progressbar = element.data('number-pb');
      if (!progressbar) return;
      if (typeof dest === "undefined") {
        progressbar.shuffle(settings.complete);
      } else {
        progressbar.reach(dest, settings.duration, settings.complete);
      }
    })
  }

})(jQuery);<commit_msg>udpate this.last<commit_after>(function($) {
  var NumberProgressBar = function(element, options) {
    var settings = $.extend ({
      duration: 10000,
      min: 0,
      max: 100,
      current: 0,
      shownQuery: '.number-pb-shown',
      numQuery: '.number-pb-num'
    }, options || {});

    this.duration = settings.duration;
    if (settings.min < settings.max) {
      this.min = settings.min;
      this.max = settings.max;
      this.current = (settings.current >= this.min && settings.current <= this.max) ? settings.current : this.min;
    } else {
      this.min = 0;
      this.max = 100;
      this.current = 0;
    }
    this.interval = this.max - this.min;
    this.last = this.min;
    this.$element = $(element);
    this.$shownBar = this.$element.find(settings.shownQuery);
    this.$num = this.$element.find(settings.numQuery);

    this.reach(this.current);
  }

  NumberProgressBar.prototype.calDestination = function(dest) {
    return (dest < this.min) ? this.min : ( (dest > this.max) ? this.max : dest )
  }

  NumberProgressBar.prototype.calDuration = function() {
    return this.duration * Math.abs(this.current - this.last) / this.interval;
  }

  NumberProgressBar.prototype.shuffle = function(callback) {
    var dest = Math.round(Math.random() * this.interval) + this.min;
    this.reach(dest, null, callback);
  }

  NumberProgressBar.prototype.calPercentage = function() {
    return (this.current - this.min) / this.interval * 100
  }

  NumberProgressBar.prototype.reach = function(dest, duration, callback) {
    this.current = this.calDestination(dest);
    this.moveShown(duration);
    this.moveNum(duration, callback);
    this.last = this.current;
  }

  NumberProgressBar.prototype.moveShown = function(duration) {
    this.$shownBar.velocity({
      width: this.calPercentage() + '%'
    }, {
      duration: duration || this.calDuration()
    })
  }

  NumberProgressBar.prototype.moveNum = function(duration, callback) {
    var self = this;
    var duration = duration || this.calDuration();

    this.$num.velocity({
      left: this.calPercentage() + '%'
    }, {
      duration: duration,
      complete: callback
    });

    // number
    $({num: this.last}).animate({
      num: this.current
    }, {
      queue: true,
      duration: duration,
      step: function() {
        self.$num.text(Math.ceil(this.num));
      },
      complete: function() {
        self.$num.text(self.current);
      }
    })
  }

  $.fn.NumberProgressBar = function(options) {
    return this.each(function () {
      var element = $(this);
      if (element.data('number-pb')) return;
      element.data('number-pb', new NumberProgressBar(this, options));
    })
  }

  $.fn.reach = function(dest, options) {
    var settings = $.extend ({
      duration : null,
      complete : null
    }, options || {});
    return this.each(function() {
      var element = $(this);
      var progressbar = element.data('number-pb');
      if (!progressbar) return;
      if (typeof dest === "undefined") {
        progressbar.shuffle(settings.complete);
      } else {
        progressbar.reach(dest, settings.duration, settings.complete);
      }
    })
  }

})(jQuery);<|endoftext|>


<commit_before>jobsworth.Task = (function($){
  function Task(id) {
    this.load(id);
  }

  Task.prototype.load = function(id) {
    if (window.taskTimer) window.taskTimer.destroy();

    var self = this;
    $.getJSON("/tasks/edit/" + id, function(data) {
      $("#task").fadeOut();
      $("#task").html(data.html);
      $("#task").fadeIn();
      document.title = "Task " + data.task_num + ":" + data.task_name;
      $("#task [rel=tooltip]").tooltip();

      self.init();
    });
  }

  Task.prototype.init = function() {
    $('#taskform').bind("ajax:success", function(event, json, xhr) {
      authorize_ajax_form_callback(json);
      var task = json;
      $('#errorExplanation').remove();
      $("span.fieldWithErrors").removeClass("fieldWithErrors");
      if (task.status == "error") {
        var html = "
";
        html += "
"+ task.messages.length +" error prohibited this template from being saved

There were problems with the following fields:
";
        for (i=0 ; i < task.messages.length ; i++) {html += "

"+ task.messages[i] + "

";}
        html += "
"
        $(html).insertAfter("#task_id");
      }
      else {
        if (window.grid) window.grid.reload();
        //update tags
        $("#tags").replaceWith(html_decode(task.tags));
        new jobsworth.Task(task.tasknum);
        if(jobsworth.tasks.NextTaskPanel.instance) {
            jobsworth.tasks.NextTaskPanel.instance.redraw();
        }
        flash_message(task.message);
      }
    }).bind("ajax:failure", function(event, json, xhr, error) {
      alert('error: ' + error);
    });
  }

  return Task;
})(jQuery)
<commit_msg>Abort the last task-edit XHR request on new task-edit request. Completes https://squish.ish.com.au/tasks/17755<commit_after>jobsworth.Task = (function($){
  function Task(id) {
    this.load(id);
  }

  Task.prototype.load = function(id) {
    if (window.taskTimer) window.taskTimer.destroy();

    var self = this;
    if(jobsworth.Task.lastXhrRequest) {
      jobsworth.Task.lastXhrRequest.abort();
    }
    jobsworth.Task.lastXhrRequest = $.getJSON("/tasks/edit/" + id, function(data) {
      $("#task").fadeOut();
      $("#task").html(data.html);
      $("#task").fadeIn();
      document.title = "Task " + data.task_num + ":" + data.task_name;
      $("#task [rel=tooltip]").tooltip();

      self.init();
    });
  }

  Task.prototype.init = function() {
    $('#taskform').bind("ajax:success", function(event, json, xhr) {
      authorize_ajax_form_callback(json);
      var task = json;
      $('#errorExplanation').remove();
      $("span.fieldWithErrors").removeClass("fieldWithErrors");
      if (task.status == "error") {
        var html = "
";
        html += "
"+ task.messages.length +" error prohibited this template from being saved

There were problems with the following fields:
";
        for (i=0 ; i < task.messages.length ; i++) {html += "

"+ task.messages[i] + "

";}
        html += "
"
        $(html).insertAfter("#task_id");
      }
      else {
        if (window.grid) window.grid.reload();
        //update tags
        $("#tags").replaceWith(html_decode(task.tags));
        new jobsworth.Task(task.tasknum);
        if(jobsworth.tasks.NextTaskPanel.instance) {
            jobsworth.tasks.NextTaskPanel.instance.redraw();
        }
        flash_message(task.message);
      }
    }).bind("ajax:failure", function(event, json, xhr, error) {
      alert('error: ' + error);
    });
  }

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


<commit_before>/*
  Copyright 2010, François de Metz <francois@2metz.fr>
*/
/**
 * Roster Plugin
 * Allow easily roster management
 *
 *  Features
 *  * Get roster from server
 *  * handle presence
 *  * handle roster iq
 *  * subscribe/unsubscribe
 *  * authorize/unauthorize
 *  * roster versioning (xep 237)
 */
Strophe.addConnectionPlugin('roster',
{
    _connection: null,

    _callbacks : [],
    /** Property: items
     * Roster items
     * [
     *    {
     *        name         : "",
     *        jid          : "",
     *        subscription : "",
     *        ask          : "",
     *        groups       : ["", ""],
     *        resources    : {
     *            myresource : {
     *                show   : "",
     *                status : "",
     *                priority : ""
     *            }
     *        }
     *    }
     * ]
     */
    items : [],
    /** Property: ver
     * current roster revision
     * always null if server doesn't support xep 237
     */
    ver : null,
    /** Function: init
     * Plugin init
     *
     * Parameters:
     *   (Strophe.Connection) conn - Strophe connection
     */
    init: function(conn)
    {
    this._connection = conn;
        this.items = [];
        // Override the connect and attach methods to always add presence and roster handlers.
        // They are removed when the connection disconnects, so must be added on connection.
        var oldCallback, roster = this, _connect = conn.connect, _attach = conn.attach;
        var newCallback = function(status)
        {
            if (status == Strophe.Status.ATTACHED || status == Strophe.Status.CONNECTED)
            {
                try
                {
                    // Presence subscription
                    conn.addHandler(roster._onReceivePresence.bind(roster), null, 'presence', null, null, null);
                    conn.addHandler(roster._onReceiveIQ.bind(roster), Strophe.NS.ROSTER, 'iq', "set", null, null);
                }
                catch (e)
                {
                    Strophe.error(e);
                }
            }
            if (oldCallback !== null)
                oldCallback.apply(this, arguments);
        };
        conn.connect = function(jid, pass, callback, wait, hold)
        {
            oldCallback = callback;
            if (typeof arguments[0] == "undefined")
                arguments[0] = null;
            if (typeof arguments[1] == "undefined")
                arguments[1] = null;
            arguments[2] = newCallback;
            _connect.apply(conn, arguments);
        };
        conn.attach = function(jid, sid, rid, callback, wait, hold, wind)
        {
            oldCallback = callback;
            if (typeof arguments[0] == "undefined")
                arguments[0] = null;
            if (typeof arguments[1] == "undefined")
                arguments[1] = null;
            if (typeof arguments[2] == "undefined")
                arguments[2] = null;
            arguments[3] = newCallback;
            _attach.apply(conn, arguments);
        };

        Strophe.addNamespace('ROSTER_VER', 'urn:xmpp:features:rosterver');
    },
    /** Function: supportVersioning
     * return true if roster versioning is enabled on server
     */
    supportVersioning: function()
    {
        return (this._connection.features && this._connection.features.getElementsByTagName('ver').length > 0);
    },
    /** Function: get
     * Get Roster on server
     *
     * Parameters:
     *   (Function) userCallback - callback on roster result
     *   (String) ver - current rev of roster
     *      (only used if roster versioning is enabled)
     *   (Array) items - initial items of ver
     *      (only used if roster versioning is enabled)
     *     In browser context you can use sessionStorage
     *     to store your roster in json (JSON.stringify())
     */
    get: function(userCallback, ver, items)
    {
        var attrs = {xmlns: Strophe.NS.ROSTER};
        this.items = [];
        if (this.supportVersioning())
        {
            // empty rev because i want an rev attribute in the result
            attrs.ver = ver || '';
            this.items = items || [];
        }
        var iq = $iq({type: 'get',  'id' : this._connection.getUniqueId('roster')}).c('query', attrs);
        this._connection.sendIQ(iq,
                                this._onReceiveRosterSuccess.bind(this, userCallback),
                                this._onReceiveRosterError.bind(this, userCallback));
    },
    /** Function: registerCallback
     * register callback on roster (presence and iq)
     *
     * Parameters:
     *   (Function) call_back
     */
    registerCallback: function(call_back)
    {
        this._callbacks.push(call_back);
    },
    /** Function: findItem
     * Find item by JID
     *
     * Parameters:
     *     (String) jid
     */
    findItem : function(jid)
    {
        for (var i = 0; i < this.items.length; i++)
        {
            if (this.items[i] && this.items[i].jid == jid)
            {
                return this.items[i];
            }
        }
        return false;
    },
    /** Function: removeItem
     * Remove item by JID
     *
     * Parameters:
     *     (String) jid
     */
    removeItem : function(jid)
    {
        for (var i = 0; i < this.items.length; i++)
        {
            if (this.items[i] && this.items[i].jid == jid)
            {
                this.items.splice(i, 1);
                return true;
            }
        }
        return false;
    },
    /** Function: subscribe
     * Subscribe presence
     *
     * Parameters:
     *     (String) jid
     *     (String) message
     */
    subscribe: function(jid, message)
    {
        var pres = $pres({to: jid, type: "subscribe"});
        if (message && message != "")
            pres.c("status").t(message);
        this._connection.send(pres);
    },
    /** Function: unsubscribe
     * Unsubscribe presence
     *
     * Parameters:
     *     (String) jid
     *     (String) message
     */
    unsubscribe: function(jid, message)
    {
        var pres = $pres({to: jid, type: "unsubscribe"});
        if (message && message != "")
            pres.c("status").t(message);
        this._connection.send(pres);
    },
    /** Function: authorize
     * Authorize presence subscription
     *
     * Parameters:
     *     (String) jid
     *     (String) message
     */
    authorize: function(jid, message)
    {
        var pres = $pres({to: jid, type: "subscribed"});
        if (message && message != "")
            pres.c("status").t(message);
        this._connection.send(pres);
    },
    /** Function: unauthorize
     * Unauthorize presence subscription
     *
     * Parameters:
     *     (String) jid
     *     (String) message
     */
    unauthorize: function(jid, message)
    {
        var pres = $pres({to: jid, type: "unsubscribed"});
        if (message && message != "")
            pres.c("status").t(message);
        this._connection.send(pres);
    },
    /** Function: add
     * Add roster item
     *
     * Parameters:
     *   (String) jid - item jid
     *   (String) name - name
     *   (Array) groups
     *   (Function) call_back
     */
    add: function(jid, name, groups, call_back)
    {
        var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: jid,
                                                                                name: name});
        for (var i = 0; i < groups.length; i++)
        {
            iq.c('group').t(groups[i]).up();
        }
        this._connection.sendIQ(iq, call_back, call_back);
    },
    /** Function: update
     * Update roster item
     *
     * Parameters:
     *   (String) jid - item jid
     *   (String) name - name
     *   (Array) groups
     *   (Function) call_back
     */
    update: function(jid, name, groups, call_back)
    {
        var item = this.findItem(jid);
        if (!item)
        {
            throw "item not found";
        }
        var newName = name || item.name;
        var newGroups = groups || item.groups;
        var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid,
                                                                                name: newName});
        for (var i = 0; i < newGroups.length; i++)
        {
            iq.c('group').t(newGroups[i]).up();
        }
        this._connection.sendIQ(iq, call_back, call_back);
    },
    /** Function: remove
     * Remove roster item
     *
     * Parameters:
     *   (String) jid - item jid
     *   (Function) call_back
     */
    remove: function(jid, call_back)
    {
        var item = this.findItem(jid);
        if (!item)
        {
            throw "item not found";
        }
        var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid,
                                                                                subscription: "remove"});
        this._connection.sendIQ(iq, call_back, call_back);
    },
    /** PrivateFunction: _onReceiveRosterSuccess
     *
     */
    _onReceiveRosterSuccess: function(userCallback, stanza)
    {
        this._updateItems(stanza);
        userCallback(this.items);
    },
    /** PrivateFunction: _onReceiveRosterError
     *
     */
    _onReceiveRosterError: function(userCallback, stanza)
    {
        userCallback(this.items);
    },
    /** PrivateFunction: _onReceivePresence
     * Handle presence
     */
    _onReceivePresence : function(presence)
    {
        // TODO: from is optional
        var jid = presence.getAttribute('from');
        var from = Strophe.getBareJidFromJid(jid);
        var item = this.findItem(from);
        // not in roster
        if (!item)
        {
            return true;
        }
        var type = presence.getAttribute('type');
        if (type == 'unavailable')
        {
            delete item.resources[Strophe.getResourceFromJid(jid)];
        }
        else if (!type)
        {
            // TODO: add timestamp
            item.resources[Strophe.getResourceFromJid(jid)] = {
                show     : (presence.getElementsByTagName('show').length != 0) ? Strophe.getText(presence.getElementsByTagName('show')[0]) : "",
                status   : (presence.getElementsByTagName('status').length != 0) ? Strophe.getText(presence.getElementsByTagName('status')[0]) : "",
                priority : (presence.getElementsByTagName('priority').length != 0) ? Strophe.getText(presence.getElementsByTagName('priority')[0]) : ""
            };
        }
        else
        {
            // Stanza is not a presence notification. (It's probably a subscription type stanza.)
            return true;
        }
        this._call_backs(this.items, item);
        return true;
    },
    /** PrivateFunction: _call_backs
     *
     */
    _call_backs : function(items, item)
    {
        for (var i = 0; i < this._callbacks.length; i++) // [].forEach my love ...
        {
            this._callbacks[i](items, item);
        }
    },
    /** PrivateFunction: _onReceiveIQ
     * Handle roster push.
     */
    _onReceiveIQ : function(iq)
    {
        var id = iq.getAttribute('id');
        var from = iq.getAttribute('from');
        // Receiving client MUST ignore stanza unless it has no from or from = user's JID.
        if (from && from != "" && from != this._connection.jid && from != Strophe.getBareJidFromJid(this._connection.jid))
            return true;
        var iqresult = $iq({type: 'result', id: id, from: this._connection.jid});
        this._connection.send(iqresult);
        this._updateItems(iq);
        return true;
    },
    /** PrivateFunction: _updateItems
     * Update items from iq
     */
    _updateItems : function(iq)
    {
        var query = iq.getElementsByTagName('query');
        if (query.length != 0)
        {
            this.ver = query.item(0).getAttribute('ver');
            var self = this;
            Strophe.forEachChild(query.item(0), 'item',
                function (item)
                {
                    self._updateItem(item);
                }
           );
        }
        this._call_backs(this.items);
    },
    /** PrivateFunction: _updateItem
     * Update internal representation of roster item
     */
    _updateItem : function(item)
    {
        var jid           = item.getAttribute("jid");
        var name          = item.getAttribute("name");
        var subscription  = item.getAttribute("subscription");
        var ask           = item.getAttribute("ask");
        var groups        = [];
        Strophe.forEachChild(item, 'group',
            function(group)
            {
                groups.push(Strophe.getText(group));
            }
        );

        if (subscription == "remove")
        {
            this.removeItem(jid);
            return;
        }

        var item = this.findItem(jid);
        if (!item)
        {
            this.items.push({
                name         : name,
                jid          : jid,
                subscription : subscription,
                ask          : ask,
                groups       : groups,
                resources    : {}
            });
        }
        else
        {
            item.name = name;
            item.subscription = subscription;
            item.ask = ask;
            item.groups = groups;
        }
    }
});<commit_msg>iq IDs are now returned in roster plugin<commit_after>/*
  Copyright 2010, François de Metz <francois@2metz.fr>
*/
/**
 * Roster Plugin
 * Allow easily roster management
 *
 *  Features
 *  * Get roster from server
 *  * handle presence
 *  * handle roster iq
 *  * subscribe/unsubscribe
 *  * authorize/unauthorize
 *  * roster versioning (xep 237)
 */
Strophe.addConnectionPlugin('roster',
{
    _connection: null,

    _callbacks : [],
    /** Property: items
     * Roster items
     * [
     *    {
     *        name         : "",
     *        jid          : "",
     *        subscription : "",
     *        ask          : "",
     *        groups       : ["", ""],
     *        resources    : {
     *            myresource : {
     *                show   : "",
     *                status : "",
     *                priority : ""
     *            }
     *        }
     *    }
     * ]
     */
    items : [],
    /** Property: ver
     * current roster revision
     * always null if server doesn't support xep 237
     */
    ver : null,
    /** Function: init
     * Plugin init
     *
     * Parameters:
     *   (Strophe.Connection) conn - Strophe connection
     */
    init: function(conn)
    {
    this._connection = conn;
        this.items = [];
        // Override the connect and attach methods to always add presence and roster handlers.
        // They are removed when the connection disconnects, so must be added on connection.
        var oldCallback, roster = this, _connect = conn.connect, _attach = conn.attach;
        var newCallback = function(status)
        {
            if (status == Strophe.Status.ATTACHED || status == Strophe.Status.CONNECTED)
            {
                try
                {
                    // Presence subscription
                    conn.addHandler(roster._onReceivePresence.bind(roster), null, 'presence', null, null, null);
                    conn.addHandler(roster._onReceiveIQ.bind(roster), Strophe.NS.ROSTER, 'iq', "set", null, null);
                }
                catch (e)
                {
                    Strophe.error(e);
                }
            }
            if (oldCallback !== null)
                oldCallback.apply(this, arguments);
        };
        conn.connect = function(jid, pass, callback, wait, hold)
        {
            oldCallback = callback;
            if (typeof arguments[0] == "undefined")
                arguments[0] = null;
            if (typeof arguments[1] == "undefined")
                arguments[1] = null;
            arguments[2] = newCallback;
            _connect.apply(conn, arguments);
        };
        conn.attach = function(jid, sid, rid, callback, wait, hold, wind)
        {
            oldCallback = callback;
            if (typeof arguments[0] == "undefined")
                arguments[0] = null;
            if (typeof arguments[1] == "undefined")
                arguments[1] = null;
            if (typeof arguments[2] == "undefined")
                arguments[2] = null;
            arguments[3] = newCallback;
            _attach.apply(conn, arguments);
        };

        Strophe.addNamespace('ROSTER_VER', 'urn:xmpp:features:rosterver');
    },
    /** Function: supportVersioning
     * return true if roster versioning is enabled on server
     */
    supportVersioning: function()
    {
        return (this._connection.features && this._connection.features.getElementsByTagName('ver').length > 0);
    },
    /** Function: get
     * Get Roster on server
     *
     * Parameters:
     *   (Function) userCallback - callback on roster result
     *   (String) ver - current rev of roster
     *      (only used if roster versioning is enabled)
     *   (Array) items - initial items of ver
     *      (only used if roster versioning is enabled)
     *     In browser context you can use sessionStorage
     *     to store your roster in json (JSON.stringify())
     */
    get: function(userCallback, ver, items)
    {
        var attrs = {xmlns: Strophe.NS.ROSTER};
        this.items = [];
        if (this.supportVersioning())
        {
            // empty rev because i want an rev attribute in the result
            attrs.ver = ver || '';
            this.items = items || [];
        }
        var iq = $iq({type: 'get',  'id' : this._connection.getUniqueId('roster')}).c('query', attrs);
        return this._connection.sendIQ(iq,
                                this._onReceiveRosterSuccess.bind(this, userCallback),
                                this._onReceiveRosterError.bind(this, userCallback));
    },
    /** Function: registerCallback
     * register callback on roster (presence and iq)
     *
     * Parameters:
     *   (Function) call_back
     */
    registerCallback: function(call_back)
    {
        this._callbacks.push(call_back);
    },
    /** Function: findItem
     * Find item by JID
     *
     * Parameters:
     *     (String) jid
     */
    findItem : function(jid)
    {
        for (var i = 0; i < this.items.length; i++)
        {
            if (this.items[i] && this.items[i].jid == jid)
            {
                return this.items[i];
            }
        }
        return false;
    },
    /** Function: removeItem
     * Remove item by JID
     *
     * Parameters:
     *     (String) jid
     */
    removeItem : function(jid)
    {
        for (var i = 0; i < this.items.length; i++)
        {
            if (this.items[i] && this.items[i].jid == jid)
            {
                this.items.splice(i, 1);
                return true;
            }
        }
        return false;
    },
    /** Function: subscribe
     * Subscribe presence
     *
     * Parameters:
     *     (String) jid
     *     (String) message
     */
    subscribe: function(jid, message)
    {
        var pres = $pres({to: jid, type: "subscribe"});
        if (message && message != "")
            pres.c("status").t(message);
        this._connection.send(pres);
    },
    /** Function: unsubscribe
     * Unsubscribe presence
     *
     * Parameters:
     *     (String) jid
     *     (String) message
     */
    unsubscribe: function(jid, message)
    {
        var pres = $pres({to: jid, type: "unsubscribe"});
        if (message && message != "")
            pres.c("status").t(message);
        this._connection.send(pres);
    },
    /** Function: authorize
     * Authorize presence subscription
     *
     * Parameters:
     *     (String) jid
     *     (String) message
     */
    authorize: function(jid, message)
    {
        var pres = $pres({to: jid, type: "subscribed"});
        if (message && message != "")
            pres.c("status").t(message);
        this._connection.send(pres);
    },
    /** Function: unauthorize
     * Unauthorize presence subscription
     *
     * Parameters:
     *     (String) jid
     *     (String) message
     */
    unauthorize: function(jid, message)
    {
        var pres = $pres({to: jid, type: "unsubscribed"});
        if (message && message != "")
            pres.c("status").t(message);
        this._connection.send(pres);
    },
    /** Function: add
     * Add roster item
     *
     * Parameters:
     *   (String) jid - item jid
     *   (String) name - name
     *   (Array) groups
     *   (Function) call_back
     */
    add: function(jid, name, groups, call_back)
    {
        var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: jid,
                                                                                name: name});
        for (var i = 0; i < groups.length; i++)
        {
            iq.c('group').t(groups[i]).up();
        }
        this._connection.sendIQ(iq, call_back, call_back);
    },
    /** Function: update
     * Update roster item
     *
     * Parameters:
     *   (String) jid - item jid
     *   (String) name - name
     *   (Array) groups
     *   (Function) call_back
     */
    update: function(jid, name, groups, call_back)
    {
        var item = this.findItem(jid);
        if (!item)
        {
            throw "item not found";
        }
        var newName = name || item.name;
        var newGroups = groups || item.groups;
        var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid,
                                                                                name: newName});
        for (var i = 0; i < newGroups.length; i++)
        {
            iq.c('group').t(newGroups[i]).up();
        }
        return this._connection.sendIQ(iq, call_back, call_back);
    },
    /** Function: remove
     * Remove roster item
     *
     * Parameters:
     *   (String) jid - item jid
     *   (Function) call_back
     */
    remove: function(jid, call_back)
    {
        var item = this.findItem(jid);
        if (!item)
        {
            throw "item not found";
        }
        var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid,
                                                                                subscription: "remove"});
        this._connection.sendIQ(iq, call_back, call_back);
    },
    /** PrivateFunction: _onReceiveRosterSuccess
     *
     */
    _onReceiveRosterSuccess: function(userCallback, stanza)
    {
        this._updateItems(stanza);
        userCallback(this.items);
    },
    /** PrivateFunction: _onReceiveRosterError
     *
     */
    _onReceiveRosterError: function(userCallback, stanza)
    {
        userCallback(this.items);
    },
    /** PrivateFunction: _onReceivePresence
     * Handle presence
     */
    _onReceivePresence : function(presence)
    {
        // TODO: from is optional
        var jid = presence.getAttribute('from');
        var from = Strophe.getBareJidFromJid(jid);
        var item = this.findItem(from);
        // not in roster
        if (!item)
        {
            return true;
        }
        var type = presence.getAttribute('type');
        if (type == 'unavailable')
        {
            delete item.resources[Strophe.getResourceFromJid(jid)];
        }
        else if (!type)
        {
            // TODO: add timestamp
            item.resources[Strophe.getResourceFromJid(jid)] = {
                show     : (presence.getElementsByTagName('show').length != 0) ? Strophe.getText(presence.getElementsByTagName('show')[0]) : "",
                status   : (presence.getElementsByTagName('status').length != 0) ? Strophe.getText(presence.getElementsByTagName('status')[0]) : "",
                priority : (presence.getElementsByTagName('priority').length != 0) ? Strophe.getText(presence.getElementsByTagName('priority')[0]) : ""
            };
        }
        else
        {
            // Stanza is not a presence notification. (It's probably a subscription type stanza.)
            return true;
        }
        this._call_backs(this.items, item);
        return true;
    },
    /** PrivateFunction: _call_backs
     *
     */
    _call_backs : function(items, item)
    {
        for (var i = 0; i < this._callbacks.length; i++) // [].forEach my love ...
        {
            this._callbacks[i](items, item);
        }
    },
    /** PrivateFunction: _onReceiveIQ
     * Handle roster push.
     */
    _onReceiveIQ : function(iq)
    {
        var id = iq.getAttribute('id');
        var from = iq.getAttribute('from');
        // Receiving client MUST ignore stanza unless it has no from or from = user's JID.
        if (from && from != "" && from != this._connection.jid && from != Strophe.getBareJidFromJid(this._connection.jid))
            return true;
        var iqresult = $iq({type: 'result', id: id, from: this._connection.jid});
        this._connection.send(iqresult);
        this._updateItems(iq);
        return true;
    },
    /** PrivateFunction: _updateItems
     * Update items from iq
     */
    _updateItems : function(iq)
    {
        var query = iq.getElementsByTagName('query');
        if (query.length != 0)
        {
            this.ver = query.item(0).getAttribute('ver');
            var self = this;
            Strophe.forEachChild(query.item(0), 'item',
                function (item)
                {
                    self._updateItem(item);
                }
           );
        }
        this._call_backs(this.items);
    },
    /** PrivateFunction: _updateItem
     * Update internal representation of roster item
     */
    _updateItem : function(item)
    {
        var jid           = item.getAttribute("jid");
        var name          = item.getAttribute("name");
        var subscription  = item.getAttribute("subscription");
        var ask           = item.getAttribute("ask");
        var groups        = [];
        Strophe.forEachChild(item, 'group',
            function(group)
            {
                groups.push(Strophe.getText(group));
            }
        );

        if (subscription == "remove")
        {
            this.removeItem(jid);
            return;
        }

        var item = this.findItem(jid);
        if (!item)
        {
            this.items.push({
                name         : name,
                jid          : jid,
                subscription : subscription,
                ask          : ask,
                groups       : groups,
                resources    : {}
            });
        }
        else
        {
            item.name = name;
            item.subscription = subscription;
            item.ask = ask;
            item.groups = groups;
        }
    }
});<|endoftext|>


<commit_before>import React, { Component } from "react";
import Slider from "react-slick";
import injectSheet from "react-jss";

const styles = {
  Page: {
    padding: "20px",
    margin: "auto",
    width: "90%",
    "& *": {
      minHeight: 0,
      minWidth: 0,
    },
  },
  Slider: {
    "& .slick-next:before, .slick-prev:before": {
      fontSize: "20px",
      color: "#00558B",
      opacity: 0.75,
    },
  },
  slideContainer: {
    "& img": {
      margin: "0 auto",
      maxHeight: "50vh",
      maxWidth: "100%",
      border: "5px solid #fff",
    },
    "& p": {
      width: "100%",
      textAlign: "center",
    },
  },
  thumbnailImage: {
    height: "100%",
    width: "100%",
  },
  sliderFooter: {
    display: "-webkit-box",
    display: "-ms-flexbox",
    "-webkit-box-align": "center",
    "-ms-flex-align": "center",
    alignItems: "center",
    display: "flex",
    "-webkit-box-orient": "horizontal",
    "-webkit-box-direction": "normal",
    "-ms-flex-direction": "row",
    flexDirection: "row",
    "-webkit-box-pack": "end",
    "-ms-flex-pack": "end",
    justifyContent: "flex-end",
    marginTop: "20px",
  },
  carouselControls: {
    "-webkit-box-align": "end",
    "-ms-flex-align": "end",
    "align-items": "flex-end",
    display: "-webkit-box",
    display: "-ms-flexbox",
    display: "flex",
  },
  controlButton: {
    background: "#333",
    height: "48px",
    marginLeft: "10px",
    position: "relative",
    width: "48px",
    color: "#bbb",
    fontFamily: "Circular Std",
    fontSize: "14px",
    fontWeight: 500,
    lineHeight: 1,
    border: 0,
    borderRadius: "2px",
    padding: "15px",
    verticalAlign: "middle",
  },
};

const img =
  "https://media.newyorker.com/photos/59096a581c7a8e33fb38ddf5/master/w_1926,c_limit/Fairfield_Bathtub.RGB.LoRes-thumb-300x236-15963.jpg";
class SimpleSlider extends Component {
  constructor(props) {
    super(props);
    this.state = {
      index: 0,
    };
  }
  nextSlide = () => {
    this.slider.slickNext();
  };
  prevSlide = () => {
    this.slider.slickPrev();
  };
  render = () => {
    const { classes, media } = this.props;
    const settings = {
      customPaging: i => {
        return (

        );
      },
      afterChange: currentSlideIndex =>
        this.setState({ index: currentSlideIndex }),
      arrows: false,
      dots: true,
      dotsClass: "slick-dots slick-thumb",
      infinite: true,
      speed: 500,
      slidesToShow: 1,
      slidesToScroll: 1,
    };
    return (

Custom Paging

          <Slider
            {...settings}
            ref={c => (this.slider = c)}
            className={classes.Slider}
          >
            {media.map(image => {
              return (

{image.title}

              );
            })}
          </Slider>

                {this.state.index + 1} of {this.props.media.length}

              <button
                className={classes.controlButton}
                onClick={this.prevSlide}
              >
                <
              </button>
              <button
                className={classes.controlButton}
                onClick={this.nextSlide}
              >
                >
              </button>

    );
  };
}
export default injectSheet(styles)(SimpleSlider);
<commit_msg>slide styling<commit_after>import React, { Component } from "react";
import Slider from "react-slick";
import injectSheet from "react-jss";

const styles = {
  Page: {
    padding: "20px",
    margin: "auto",
    width: "90%",
    "& *": {
      minHeight: 0,
      minWidth: 0,
    },
  },
  Slider: {
    "& .slick-next:before, .slick-prev:before": {
      fontSize: "20px",
      color: "#00558B",
      opacity: 0.75,
    },
  },
  slideContainer: {},
  slide: {
    "-webkit-box-align": "center",
    "-ms-flex-align": "center",
    alignItems: "center",
    height: "100%",
    "-webkit-box-pack": "end",
    "-ms-flex-pack": "end",
    position: "relative",
    display: "flex",
    "-webkit-box-orient": "vertical",
    "-webkit-box-direction": "normal",
    "-ms-flex-direction": "column",
    flexDirection: "column",
    justifyContent: "flex-end",
    margin: 0,
    "& img": {
      margin: "0 auto",
      maxHeight: "50vh",
      maxWidth: "100%",
    },
  },
  slideCaption: {
    alignSelf: "flex-start",
    width: "100%",
    "& p": {
      color: "#fff",
      marginTop: "10px",
      width: "100%",
      fontFamily: "Minion Pro",
      fontStyle: "italic",
      fontSize: "17px",
      textAlign: "center",
    },
  },
  thumbnailImage: {
    height: "100%",
    width: "100%",
  },
  sliderFooter: {
    display: "-webkit-box",
    display: "-ms-flexbox",
    "-webkit-box-align": "center",
    "-ms-flex-align": "center",
    alignItems: "center",
    display: "flex",
    "-webkit-box-orient": "horizontal",
    "-webkit-box-direction": "normal",
    "-ms-flex-direction": "row",
    flexDirection: "row",
    "-webkit-box-pack": "end",
    "-ms-flex-pack": "end",
    justifyContent: "flex-end",
    marginTop: "20px",
  },
  index: {
    color: "#ddd",
    fontFamily: "Circular Std",
  },
  carouselControls: {
    "-webkit-box-align": "end",
    "-ms-flex-align": "end",
    "align-items": "flex-end",
    display: "-webkit-box",
    display: "-ms-flexbox",
    display: "flex",
  },
  controlButton: {
    background: "#333",
    height: "48px",
    outline: "none",
    marginLeft: "10px",
    position: "relative",
    width: "48px",
    color: "#bbb",
    fontFamily: "Circular Std",
    fontSize: "14px",
    fontWeight: 500,
    lineHeight: 1,
    border: 0,
    borderRadius: "2px",
    padding: "15px",
    verticalAlign: "middle",
  },
};

const img =
  "https://media.newyorker.com/photos/59096a581c7a8e33fb38ddf5/master/w_1926,c_limit/Fairfield_Bathtub.RGB.LoRes-thumb-300x236-15963.jpg";
class SimpleSlider extends Component {
  constructor(props) {
    super(props);
    this.state = {
      index: 0,
    };
  }
  nextSlide = () => {
    this.slider.slickNext();
  };
  prevSlide = () => {
    this.slider.slickPrev();
  };
  render = () => {
    const { classes, media } = this.props;
    const settings = {
      customPaging: i => {
        return (

        );
      },
      afterChange: currentSlideIndex =>
        this.setState({ index: currentSlideIndex }),
      arrows: false,
      dots: true,
      dotsClass: "slick-dots slick-thumb",
      infinite: false,
      speed: 500,
      slidesToShow: 1,
      slidesToScroll: 1,
    };
    return (

          <Slider
            {...settings}
            ref={c => (this.slider = c)}
            className={classes.Slider}
          >
            {media.map(image => {
              return (

{image.title}

              );
            })}
          </Slider>

                {this.state.index + 1} of {this.props.media.length}

              <button
                className={classes.controlButton}
                onClick={this.prevSlide}
              >
                <
              </button>
              <button
                className={classes.controlButton}
                onClick={this.nextSlide}
              >
                >
              </button>

    );
  };
}
export default injectSheet(styles)(SimpleSlider);
<|endoftext|>


<commit_before>
function Route(handle, request, response) {
	var pathname = _url.parse(request.url).pathname;

	if (typeof handle[pathname] === 'function') {
		return handle[pathname](request, response);
	} else {
		console.log("No request handler found for: " + pathname);
		response.setResponsCode(404);
		return response;
	}
}

exports.Route = Route;
<commit_msg>typo fix<commit_after>
function Route(handle, request, response) {
	var pathname = _url.parse(request.url).pathname;

	if (typeof handle[pathname] === 'function') {
		return handle[pathname](request, response);
	} else {
		console.log("No request handler found for: " + pathname);
		response.setResponseCode(404);
		return response;
	}
}

exports.Route = Route;
<|endoftext|>