<commit_before>'use strict';

(function () {

  var app = angular.module('antismash.db.ui.query', [

  ]);

  app.controller('QueryController', ['$scope', '$state', '$http',
    function ($scope, $state, $http) {

      var vm = this;

      vm.search_string = '';
      vm.search = search;
      vm.simpleSearch = simpleSearch;
      vm.showCluster = showCluster;
      vm.canLoadMore = canLoadMore;
      vm.loadMore = loadMore;
      vm.getMibigUrl = getMibigUrl;
      vm.addEntry = addEntry;
      vm.removeEntry = removeEntry;
      vm.loadExample = loadExample;
      vm.resetSearch = resetSearch;
      vm.search_pending = false;
      vm.search_done = false;
      vm.loading_more = false;

      vm.search_objects = [
        {category: {val: 'type', desc: 'BGC type'}, term: ''}
      ];

      vm.categories = [
        {val: 'type', desc: 'BGC type'},
        {val: 'monomer', desc: 'Monomer'},
        {val: 'acc', desc: 'NCBI Accession'},
        {val: 'compound_seq', desc: 'Compound sequence'},
        {val: 'species', desc: 'Species'},
        {val: 'genus', desc: 'Genus'},
        {val: 'family', desc: 'Family'}
      ]

      vm.results = {};

      function search() {
        var compiled_search = [];
        vm.search_objects.forEach(function(el) {
          if (el.term != ''){
            compiled_search.push('[' + el.category.val + ']' + el.term);
          }
        }, this);
        vm.search_string = compiled_search.join(' ');
        if (vm.search_string != '') {
          vm.simpleSearch();
        }
      }

      function simpleSearch() {
        vm.search_pending = true;
        $http.post('/api/v1.0/search', {search_string: vm.search_string}).then(
          function(results){
            vm.results = results.data;
            vm.search_pending = false;
            vm.search_done = true;
          }
        )
      };

      function canLoadMore() {
        if (vm.results && vm.results.clusters) {
          return vm.results.clusters.length < vm.results.total;
        }
        return false;
      }

      function loadMore() {
        var next_offset = vm.results.offset + vm.results.paginate;
        var search_obj = {
          search_string: vm.search_string,
          offset: next_offset
        };
        vm.loading_more = true;
        $http.post('/api/v1.0/search', search_obj).then(
          function(results){
            vm.loading_more = false;
            var new_clusters = results.data.clusters;
            for (var i = 0; i < new_clusters.length; i++) {
              vm.results.clusters.push(new_clusters[i]);
            }
            vm.results.offset = results.data.offset;
          }
        )
      }

      function showCluster(entry) {
        var cluster_acc = entry.acc + '_c' + entry.cluster_number;
        window.open('/output/' + entry.acc + '/index.html#cluster-' + entry.cluster_number, '_new');
        //$state.go('show.cluster', {id: cluster_acc});
      };

      function getMibigUrl(accession) {
        if (!accession) {
          return '';
        }
        var acc = accession.split(/_/)[0];
        return "http://mibig.secondarymetabolites.org/repository/" + acc + "/index.html#cluster-1";
      };

      function addEntry(){
        vm.search_objects.push({category: {val: 'type', desc:'BGC type'}, term: ''});
      };

      function removeEntry(entry){
        var idx = vm.search_objects.indexOf(entry);
        if (idx > -1) {
          vm.search_objects.splice(idx, 1);
        }
      };

      function loadExample(entry){
        vm.search_objects = [
          {
            category: {val: 'type', desc: 'BGC type'},
            term: 'lantipeptide'
          },
          {
            category: {val: 'genus', desc: 'Genus'},
            term: 'Streptomyces'
          }
        ];
        vm.search_string = 'lantipeptide Streptomyces';
      };

      function resetSearch(){
        vm.search_done = false;
        vm.search_pending = false;
        vm.results = {};
      }

    }]);

})();
<commit_msg>query: add missing categories<commit_after>'use strict';

(function () {

  var app = angular.module('antismash.db.ui.query', [

  ]);

  app.controller('QueryController', ['$scope', '$state', '$http',
    function ($scope, $state, $http) {

      var vm = this;

      vm.search_string = '';
      vm.search = search;
      vm.simpleSearch = simpleSearch;
      vm.showCluster = showCluster;
      vm.canLoadMore = canLoadMore;
      vm.loadMore = loadMore;
      vm.getMibigUrl = getMibigUrl;
      vm.addEntry = addEntry;
      vm.removeEntry = removeEntry;
      vm.loadExample = loadExample;
      vm.resetSearch = resetSearch;
      vm.search_pending = false;
      vm.search_done = false;
      vm.loading_more = false;

      vm.search_objects = [
        {category: {val: 'type', desc: 'BGC type'}, term: ''}
      ];

      vm.categories = [
        {val: 'type', desc: 'BGC type'},
        {val: 'monomer', desc: 'Monomer'},
        {val: 'acc', desc: 'NCBI Accession'},
        {val: 'compound_seq', desc: 'Compound sequence'},
        {val: 'species', desc: 'Species'},
        {val: 'genus', desc: 'Genus'},
        {val: 'family', desc: 'Family'},
        {val: 'order', desc: 'Order'},
        {val: 'class', desc: 'Class'},
        {val: 'phylum', desc: 'Phylum'},
        {val: 'superkingdom', desc: 'Superkingdom'}
      ]

      vm.results = {};

      function search() {
        var compiled_search = [];
        vm.search_objects.forEach(function(el) {
          if (el.term != ''){
            compiled_search.push('[' + el.category.val + ']' + el.term);
          }
        }, this);
        vm.search_string = compiled_search.join(' ');
        if (vm.search_string != '') {
          vm.simpleSearch();
        }
      }

      function simpleSearch() {
        vm.search_pending = true;
        $http.post('/api/v1.0/search', {search_string: vm.search_string}).then(
          function(results){
            vm.results = results.data;
            vm.search_pending = false;
            vm.search_done = true;
          }
        )
      };

      function canLoadMore() {
        if (vm.results && vm.results.clusters) {
          return vm.results.clusters.length < vm.results.total;
        }
        return false;
      }

      function loadMore() {
        var next_offset = vm.results.offset + vm.results.paginate;
        var search_obj = {
          search_string: vm.search_string,
          offset: next_offset
        };
        vm.loading_more = true;
        $http.post('/api/v1.0/search', search_obj).then(
          function(results){
            vm.loading_more = false;
            var new_clusters = results.data.clusters;
            for (var i = 0; i < new_clusters.length; i++) {
              vm.results.clusters.push(new_clusters[i]);
            }
            vm.results.offset = results.data.offset;
          }
        )
      }

      function showCluster(entry) {
        var cluster_acc = entry.acc + '_c' + entry.cluster_number;
        window.open('/output/' + entry.acc + '/index.html#cluster-' + entry.cluster_number, '_new');
        //$state.go('show.cluster', {id: cluster_acc});
      };

      function getMibigUrl(accession) {
        if (!accession) {
          return '';
        }
        var acc = accession.split(/_/)[0];
        return "http://mibig.secondarymetabolites.org/repository/" + acc + "/index.html#cluster-1";
      };

      function addEntry(){
        vm.search_objects.push({category: {val: 'type', desc:'BGC type'}, term: ''});
      };

      function removeEntry(entry){
        var idx = vm.search_objects.indexOf(entry);
        if (idx > -1) {
          vm.search_objects.splice(idx, 1);
        }
      };

      function loadExample(entry){
        vm.search_objects = [
          {
            category: {val: 'type', desc: 'BGC type'},
            term: 'lantipeptide'
          },
          {
            category: {val: 'genus', desc: 'Genus'},
            term: 'Streptomyces'
          }
        ];
        vm.search_string = 'lantipeptide Streptomyces';
      };

      function resetSearch(){
        vm.search_done = false;
        vm.search_pending = false;
        vm.results = {};
      }

    }]);

})();
<|endoftext|>


<commit_before>'use strict';

import express from 'express';
import _       from 'lodash';
import crypto  from 'crypto';

import models                     from '../models';
import { verifyJWT, resolveUser } from '../middleware';
import { connections, EVENT_TYPES }            from '../utils/socketIO';

let User = models.User;

let router = express.Router();

// Route to check if a user is registered
router.get('/:phoneNumber/exists', verifyJWT, (req, res, next) => {
    let phoneNumber = req.params.phoneNumber.replace(/[+ ]/, '');
    let found = false;

    User.findOne({ where: { phoneNumber: phoneNumber } })
        .then(user => {
            if (user) {
                found = true;
            }

            res.status(200).json({ found: found, phoneNumber: phoneNumber });
        });
});

router.get('/generatePeerId', verifyJWT, resolveUser, (req, res, next) => {
    // PeerJS only allows alphanumeric characters in it's ID
    const phoneNumber = req.user.phoneNumber;
    const id = req.user.id;
    const peerJSId = `${phoneNumber}PEER${crypto.randomBytes(10).toString('hex')}`;

    const currentSocket = _.find(connections, socket => {
        return socket.user.id = id;
    });

    if (currentSocket) {
        currentSocket.emit(EVENT_TYPES.ALREADY_LOGGED_IN, {});
        currentSocket.disconnect(true);
    }

    req.user.update({ peerJSId })
    .then((results) => {
        res.status(200).json({ peerJSId });
    });
});

export default router;

<commit_msg>Fix accidental disconnecting of wrong socket<commit_after>'use strict';

import express from 'express';
import _       from 'lodash';
import crypto  from 'crypto';

import models                     from '../models';
import { verifyJWT, resolveUser } from '../middleware';
import { connections, EVENT_TYPES }            from '../utils/socketIO';
import {log} from '../utils/log'

let User = models.User;

let router = express.Router();

// Route to check if a user is registered
router.get('/:phoneNumber/exists', verifyJWT, (req, res, next) => {
    let phoneNumber = req.params.phoneNumber.replace(/[+ ]/, '');
    let found = false;

    User.findOne({ where: { phoneNumber: phoneNumber } })
        .then(user => {
            if (user) {
                found = true;
            }

            res.status(200).json({ found: found, phoneNumber: phoneNumber });
        });
});

router.get('/generatePeerId', verifyJWT, resolveUser, (req, res, next) => {
    // PeerJS only allows alphanumeric characters in it's ID
    const phoneNumber = req.user.phoneNumber;
    const id = req.user.id;
    const peerJSId = `${phoneNumber}PEER${crypto.randomBytes(10).toString('hex')}`;

    const currentSocket = _.find(connections, socket => {
        return socket.user.id === id;
    });

    if (currentSocket) {
        currentSocket.emit(EVENT_TYPES.ALREADY_LOGGED_IN, {});
    }

    req.user.update({ peerJSId })
    .then((results) => {
        res.status(200).json({ peerJSId });
    });
});

export default router;

<|endoftext|>


<commit_before>app.controller('HomeController', function ($scope, $location, $http, $interval, AuthService, ngProgress) {
    ngProgress.reset();
    ngProgress.start();
    AuthService.refresh();
    $scope.user = AuthService.getUser();
    $scope.items = {};
    $scope.resuls = {};

    $http.get("/api/service/queries")
        .success(function (data) {
            $scope.items = eval(data);
            ngProgress.complete();
        })
        .error(function (error) {
            console.log(error);
        });

    $scope.loginPath = function () {
        return "/login?path=" + $location.path();
    };

    $scope.$watch(function () {
        return AuthService.getUser();
    }, function () {
        $scope.user = AuthService.getUser();
    });

    $scope.isAuthenticated = AuthService.isAuthenticated();
    $scope.$watch(function () {
        return AuthService.isAuthenticated();
    }, function () {
        $scope.isAuthenticated = AuthService.isAuthenticated();
    });

    $scope.isAdmin = AuthService.isAdmin();
    $scope.$watch(function () {
        return AuthService.isAuthenticated();
    }, function () {
        $scope.isAdmin = AuthService.isAdmin();
    });

    $scope.launchRequest = function (index) {
        var item = $scope.items[index].request;
        ngProgress.reset();
        ngProgress.start();

        $http.post("/api/execute/query/", item)
            .success(function (data) {
                console.log(data);
                $location.path("/result/"+data.jobId);
            })
            .error(function (error) {
                console.log(error);
            });
    };

});<commit_msg>Repeat incremental call to get result.<commit_after>app.controller('HomeController', function ($scope, $location, $http, $interval, AuthService, ngProgress) {
    ngProgress.reset();
    ngProgress.start();
    AuthService.refresh();
    $scope.user = AuthService.getUser();
    $scope.items = {};
    $scope.resuls = {};

    $http.get("/api/service/queries")
        .success(function (data) {
            $scope.items = eval(data);
            ngProgress.complete();
        })
        .error(function (error) {
            console.log(error);
        });

    $scope.loginPath = function () {
        return "/login?path=" + $location.path();
    };

    $scope.$watch(function () {
        return AuthService.getUser();
    }, function () {
        $scope.user = AuthService.getUser();
    });

    $scope.isAuthenticated = AuthService.isAuthenticated();
    $scope.$watch(function () {
        return AuthService.isAuthenticated();
    }, function () {
        $scope.isAuthenticated = AuthService.isAuthenticated();
    });

    $scope.isAdmin = AuthService.isAdmin();
    $scope.$watch(function () {
        return AuthService.isAuthenticated();
    }, function () {
        $scope.isAdmin = AuthService.isAdmin();
    });

    $scope.launchRequest = function (index) {
        var item = $scope.items[index].request;
        ngProgress.reset();
        ngProgress.start();

        $location.path("/result/"+item.id);
    };
});<|endoftext|>


<commit_before>define(function (require) {
    'use strict';

    var Q = require('q');
    var Config = JSON.parse(require('text!config.json'));
    var _ = require('lodash');

    var READY_STATE_DONE = 4;
    var MAX_CURATE_SIZE = 100;

    var client;

    var Client = function (baseUrl) {
        this.baseUrl = baseUrl;
    };

    function mergeCTLResponses(oldCTL, newCTL) {
        return newCTL ? _.merge(newCTL, {
            objects: oldCTL.objects,
            response: {
                timeline: oldCTL.response.timeline
            }
        }, function (a, b) {
            return _.isArray(a) ? a.concat(b) : undefined;
        }) : oldCTL;
    }

    Client.getDefaultInstance = function () {
        if (!client) {
            client = new Client(Config.API_BASE);
        }

        return client;
    };

    Client.encodeQuery = function (query) {
        return Object.keys(query || {}).map(function (key) {
            return encodeURIComponent(_.string.underscored(key)) + '=' +
                encodeURIComponent(query[key]);
        }).join('&');
    };

    Client.normalizeCTLId = function (id) {
        return (_.string.startsWith(id, 'custom-')) ? id : 'custom-' + id;
    };

    Client.prototype.xhr = function (options) {
        var deferred = Q.defer();
        var xhr = new XMLHttpRequest();
        var params = '';

        xhr.withCredentials = !!options.withCredentials;

        if (options.params) {
            // Very simplistic, but should work for our limited use cases.
            params = '?' + Client.encodeQuery(options.params);
        }

        if (options.json) {
            options.headers = _.assign(options.headers || {}, {
                'Content-Type': 'application/json'
            });
            options.data = JSON.stringify(options.json);
        } else if (options.form) {
            options.headers = _.assign(options.headers || {}, {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            });
            options.data = Client.encodeQuery(options.form);
        }

        xhr.open(options.method, options.url + params, true);

        Object.keys(options.headers || {}).forEach(function (key) {
            xhr.setRequestHeader(key, options.headers[key]);
        });

        xhr.onreadystatechange = function (e) {
            if (xhr.readyState !== READY_STATE_DONE) {
                return;
            }

            if ([200, 304].indexOf(xhr.status) === -1) {
                var err = new Error('Server responded with status ' + xhr.status);
                err.status = xhr.status;
                err.xhr = xhr;

                deferred.reject(err);
            } else {
                deferred.resolve(e.target);
            }
        };

        xhr.send(options.data);

        return deferred.promise;
    };

    Client.prototype.request = function (url, method, options) {
        return this.xhr(_.extend({
            url: this.baseUrl + url,
            method: method || 'GET',
            withCredentials: true
        }, options)).then(function (xhr) {
            try {
                return JSON.parse(xhr.response);
            } catch (e) {
                console.warn('Unexpected non-JSON response: ', xhr.response);
                return xhr.response;
            }
        });
    };

    Client.prototype.login = function () {
        document.location.href = this.baseUrl + '/login?next=' +
            encodeURIComponent(document.location.href);
    };

    Client.prototype.logout = function () {
        return this.request('/logout', 'POST');
    };

    Client.prototype.getSession = function () {
        return this.request('/');
    };

    /**
     * Get a full user info response based on their user id.
     */
    Client.prototype.getUser = function (id, params) {
        /*jshint camelcase:false */
        return this.request('/1.1/users/show.json', 'GET', {
            params: _.extend({
                id: id
            }, params)
        });
    };

    Client.prototype.getCTLs = function (params) {
        return this.request('/1.1/beta/timelines/custom/list.json', 'GET', {
            params: params
        });
    };

    /**
     * Get a custom timeline, including *all* tweets in it.
     *
     * @callback progressCallback progressCb - A partial response, possibly not
     * containing all Tweets of the CTL.
     *
     * @param {string} id - CTL id
     * @param {object} params - URL parameters
     * @param {progressCallback} progressCb - Same as the resolved CTL, but
     * potentially partial
     *
     * @returns {object} Promise over the raw CTL response.
     */
    Client.prototype.getCTL = function (id, params, progressCb, _response) {
        return this.request('/1.1/beta/timelines/timeline.json', 'GET', {
            params: _.extend({
                id: Client.normalizeCTLId(id)
            }, params)
        }).then(function (response) {
            /*jshint camelcase:false */
            if (_.isFunction(progressCb)) {
                progressCb(response);
            }

            if (response.response.position.was_truncated) {
                return this.getCTL(
                    id,
                    _.extend({}, params, { max_position: response.response.position.min_position }),
                    progressCb,
                    mergeCTLResponses(response, _response)
                );
            } else {
                return mergeCTLResponses(response, _response);
            }
        }.bind(this));
    };

    /**
     * Creates a new CTL and (optionally) populates it with the given tweets in
     * order.
     *
     * @callback progressCallback progressCb - What should have gone through the
     * promise.
     *
     * @param {object} ctlParams - Object describing the new custom timeline.
     * @param {string} ctlParams.name - Name of the CTL.
     * @param {string} ctlParams.description - Description of the CTL.
     * @param {array=} tweetIds - List of Tweet IDs to add to the CTL.
     * @param {progressCallback} progressCb - Takes an object as parameter with
     * the keys {total, value}.
     *
     * @returns {object} Promise reporting the progress if tweetIds have been
     *                   specified.
     */
    Client.prototype.createCTL = function (ctlParams, tweetIds, progressCb) {
        var that = this;
        var createP = this.request(
            '/1.1/beta/timelines/custom/create.json',
            'POST', { form: {
                name: ctlParams.name,
                description: ctlParams.description
            } });
        tweetIds = tweetIds || [];

        if (!tweetIds.length) {
            return createP;
        }

        return createP.then(function (response) {
            var deferred = Q.defer();
            /*jshint camelcase:false */
            var ctlId = response.response.timeline_id;
            var counter = 0;
            var total = tweetIds.length;

            // These have to be executed sequentially and we want to resolve the
            // CTL response instead of the adding responses.
            console.log('reducing tweet ids:', tweetIds);
            tweetIds.reverse().reduce(function (prom, tweetId) {
                return prom.then(function () {
                    // Unfortunately, this doesn't bubble up at the moment and I
                    // can't really think of a pretty alternative to that.
                    deferred.notify(counter++);

                    if (_.isFunction(progressCb)) {
                        progressCb({
                            value: counter,
                            total: total
                        });
                    }
                }).then(that.addTweetToCTL.bind(that, ctlId, tweetId));
            }, Q()).then(deferred.resolve.bind(deferred, response),
                    deferred.reject.bind(deferred));

            // Make sure that we return just the response in the end.
            return deferred.promise;
        });
    };

    /**
     * Update the given properties on the CTL identified by ctlId.
     */
    Client.prototype.updateCTL = function (ctlId, props) {
        return this.request(
            '/1.1/beta/timelines/custom/update.json',
            'POST', {
                form: _.extend(props, {
                    id: Client.normalizeCTLId(ctlId)
                })
            }
        );
    };

    /**
     * Remove a CTL completely.
     *
     * @param ctlId {string} - ID of the CTL.
     *
     */
    Client.prototype.destroyCTL = function (ctlId) {
        return this.request(
            '/1.1/beta/timelines/custom/destroy.json',
            'POST', { form: {
                id: Client.normalizeCTLId(ctlId)
            } });
    };

    /**
     * Modify an existing CTL.
     *
     * An operation in `ops` has the following format:
     *
     * { op: OP, tweetId: TWEET_ID }
     *
     * whereby `OP` is either 'add' or 'remove' and `TWEET_ID` is the ID of the
     * Tweet.
     *
     * @param ctlId {string} - ID of the CTL.
     * @param ops {array} - Array of operations to apply to the CTL.
     *
     * @return {object} - promise over the response
     */
    Client.prototype.curateCTL = function (ctlId, ops) {
        ops = _.map(ops, function (op) {
            /*jshint camelcase:false */
            return { op: op.op, tweet_id: op.tweetId };
        });

        return this._batchCurateCTL(ctlId, ops);
    };

    Client.prototype._batchCurateCTL = function (ctlId, rawOps) {
        var ops = rawOps.splice(0, MAX_CURATE_SIZE);

        return this.request(
            '/1.1/beta/timelines/custom/curate.json',
            'POST', {
                json: {
                    id: Client.normalizeCTLId(ctlId),
                    changes: ops
                }
            }).then(function (result) {
                if (rawOps.length) {
                    return this._batchCurateCTL(ctlId, rawOps);
                }

                return result;
            }.bind(this));
    };

    /**
     * Overwrites the Tweets in an existing CTL by the given list of new Tweets.
     * This is one by removing all of the existing and adding the new ones
     * afterwards.
     *
     * @callback progressCallback progressCb - What should have gone through the
     * promise.
     *
     * @param {string} ctlId - ID of the CTL to replace.
     * @param {array=} tweetIds - List of Tweet IDs to add to the CTL.
     * @param {progressCallback} progressCb - Takes an object as parameter with
     * the keys {total, value}.
     *
     * @returns {object} Promise reporting the progress if tweetIds have been
     *                   specified.
     */
    Client.prototype.overwriteCTL = function (ctlId, tweetIds, progressCb) {
        return this.getCTL(ctlId).then(function (ctl) {
            progressCb({ value: 0, total: 1 });

            var removeOps = Object.keys(ctl.objects.tweets).map(function (key) {
                return {
                    tweetId: key,
                    op: 'remove'
                };
            });

            // Add them in the reverse order
            var addOps = tweetIds.reverse().map(function (id) {
                return {
                    tweetId: id,
                    op: 'add'
                };
            });

            return this.curateCTL(ctlId, removeOps.concat(addOps));
        }.bind(this));
    };

    Client.prototype.addTweetToCTL = function (ctlId, tweetId) {
        /*jshint camelcase:false */

        return this.request(
            '/1.1/beta/timelines/custom/add.json',
            'POST', { form: {
                id: ctlId,
                tweet_id: tweetId
            } });
    };

    return Client;
});
<commit_msg>Add a getConversation API method<commit_after>define(function (require) {
    'use strict';

    var Q = require('q');
    var Config = JSON.parse(require('text!config.json'));
    var _ = require('lodash');

    var READY_STATE_DONE = 4;
    var MAX_CURATE_SIZE = 100;

    var client;

    var Client = function (baseUrl) {
        this.baseUrl = baseUrl;
    };

    function mergeCTLResponses(oldCTL, newCTL) {
        return newCTL ? _.merge(newCTL, {
            objects: oldCTL.objects,
            response: {
                timeline: oldCTL.response.timeline
            }
        }, function (a, b) {
            return _.isArray(a) ? a.concat(b) : undefined;
        }) : oldCTL;
    }

    Client.getDefaultInstance = function () {
        if (!client) {
            client = new Client(Config.API_BASE);
        }

        return client;
    };

    Client.encodeQuery = function (query) {
        return Object.keys(query || {}).map(function (key) {
            return encodeURIComponent(_.string.underscored(key)) + '=' +
                encodeURIComponent(query[key]);
        }).join('&');
    };

    Client.normalizeCTLId = function (id) {
        return (_.string.startsWith(id, 'custom-')) ? id : 'custom-' + id;
    };

    Client.prototype.xhr = function (options) {
        var deferred = Q.defer();
        var xhr = new XMLHttpRequest();
        var params = '';

        xhr.withCredentials = !!options.withCredentials;

        if (options.params) {
            // Very simplistic, but should work for our limited use cases.
            params = '?' + Client.encodeQuery(options.params);
        }

        if (options.json) {
            options.headers = _.assign(options.headers || {}, {
                'Content-Type': 'application/json'
            });
            options.data = JSON.stringify(options.json);
        } else if (options.form) {
            options.headers = _.assign(options.headers || {}, {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            });
            options.data = Client.encodeQuery(options.form);
        }

        xhr.open(options.method, options.url + params, true);

        Object.keys(options.headers || {}).forEach(function (key) {
            xhr.setRequestHeader(key, options.headers[key]);
        });

        xhr.onreadystatechange = function (e) {
            if (xhr.readyState !== READY_STATE_DONE) {
                return;
            }

            if ([200, 304].indexOf(xhr.status) === -1) {
                var err = new Error('Server responded with status ' + xhr.status);
                err.status = xhr.status;
                err.xhr = xhr;

                deferred.reject(err);
            } else {
                deferred.resolve(e.target);
            }
        };

        xhr.send(options.data);

        return deferred.promise;
    };

    Client.prototype.request = function (url, method, options) {
        return this.xhr(_.extend({
            url: this.baseUrl + url,
            method: method || 'GET',
            withCredentials: true
        }, options)).then(function (xhr) {
            try {
                return JSON.parse(xhr.response);
            } catch (e) {
                console.warn('Unexpected non-JSON response: ', xhr.response);
                return xhr.response;
            }
        });
    };

    Client.prototype.login = function () {
        document.location.href = this.baseUrl + '/login?next=' +
            encodeURIComponent(document.location.href);
    };

    Client.prototype.logout = function () {
        return this.request('/logout', 'POST');
    };

    Client.prototype.getSession = function () {
        return this.request('/');
    };

    /**
     * Get a full user info response based on their user id.
     */
    Client.prototype.getUser = function (id, params) {
        /*jshint camelcase:false */
        return this.request('/1.1/users/show.json', 'GET', {
            params: _.extend({
                id: id
            }, params)
        });
    };

    Client.prototype.getCTLs = function (params) {
        return this.request('/1.1/beta/timelines/custom/list.json', 'GET', {
            params: params
        });
    };

    /**
     * Get a custom timeline, including *all* tweets in it.
     *
     * @callback progressCallback progressCb - A partial response, possibly not
     * containing all Tweets of the CTL.
     *
     * @param {string} id - CTL id
     * @param {object} params - URL parameters
     * @param {progressCallback} progressCb - Same as the resolved CTL, but
     * potentially partial
     *
     * @returns {object} Promise over the raw CTL response.
     */
    Client.prototype.getCTL = function (id, params, progressCb, _response) {
        return this.request('/1.1/beta/timelines/timeline.json', 'GET', {
            params: _.extend({
                id: Client.normalizeCTLId(id)
            }, params)
        }).then(function (response) {
            /*jshint camelcase:false */
            if (_.isFunction(progressCb)) {
                progressCb(response);
            }

            if (response.response.position.was_truncated) {
                return this.getCTL(
                    id,
                    _.extend({}, params, { max_position: response.response.position.min_position }),
                    progressCb,
                    mergeCTLResponses(response, _response)
                );
            } else {
                return mergeCTLResponses(response, _response);
            }
        }.bind(this));
    };

    /**
     * Creates a new CTL and (optionally) populates it with the given tweets in
     * order.
     *
     * @callback progressCallback progressCb - What should have gone through the
     * promise.
     *
     * @param {object} ctlParams - Object describing the new custom timeline.
     * @param {string} ctlParams.name - Name of the CTL.
     * @param {string} ctlParams.description - Description of the CTL.
     * @param {array=} tweetIds - List of Tweet IDs to add to the CTL.
     * @param {progressCallback} progressCb - Takes an object as parameter with
     * the keys {total, value}.
     *
     * @returns {object} Promise reporting the progress if tweetIds have been
     *                   specified.
     */
    Client.prototype.createCTL = function (ctlParams, tweetIds, progressCb) {
        var that = this;
        var createP = this.request(
            '/1.1/beta/timelines/custom/create.json',
            'POST', { form: {
                name: ctlParams.name,
                description: ctlParams.description
            } });
        tweetIds = tweetIds || [];

        if (!tweetIds.length) {
            return createP;
        }

        return createP.then(function (response) {
            var deferred = Q.defer();
            /*jshint camelcase:false */
            var ctlId = response.response.timeline_id;
            var counter = 0;
            var total = tweetIds.length;

            // These have to be executed sequentially and we want to resolve the
            // CTL response instead of the adding responses.
            console.log('reducing tweet ids:', tweetIds);
            tweetIds.reverse().reduce(function (prom, tweetId) {
                return prom.then(function () {
                    // Unfortunately, this doesn't bubble up at the moment and I
                    // can't really think of a pretty alternative to that.
                    deferred.notify(counter++);

                    if (_.isFunction(progressCb)) {
                        progressCb({
                            value: counter,
                            total: total
                        });
                    }
                }).then(that.addTweetToCTL.bind(that, ctlId, tweetId));
            }, Q()).then(deferred.resolve.bind(deferred, response),
                    deferred.reject.bind(deferred));

            // Make sure that we return just the response in the end.
            return deferred.promise;
        });
    };

    /**
     * Update the given properties on the CTL identified by ctlId.
     */
    Client.prototype.updateCTL = function (ctlId, props) {
        return this.request(
            '/1.1/beta/timelines/custom/update.json',
            'POST', {
                form: _.extend(props, {
                    id: Client.normalizeCTLId(ctlId)
                })
            }
        );
    };

    /**
     * Remove a CTL completely.
     *
     * @param ctlId {string} - ID of the CTL.
     *
     */
    Client.prototype.destroyCTL = function (ctlId) {
        return this.request(
            '/1.1/beta/timelines/custom/destroy.json',
            'POST', { form: {
                id: Client.normalizeCTLId(ctlId)
            } });
    };

    /**
     * Modify an existing CTL.
     *
     * An operation in `ops` has the following format:
     *
     * { op: OP, tweetId: TWEET_ID }
     *
     * whereby `OP` is either 'add' or 'remove' and `TWEET_ID` is the ID of the
     * Tweet.
     *
     * @param ctlId {string} - ID of the CTL.
     * @param ops {array} - Array of operations to apply to the CTL.
     *
     * @return {object} - promise over the response
     */
    Client.prototype.curateCTL = function (ctlId, ops) {
        ops = _.map(ops, function (op) {
            /*jshint camelcase:false */
            return { op: op.op, tweet_id: op.tweetId };
        });

        return this._batchCurateCTL(ctlId, ops);
    };

    Client.prototype._batchCurateCTL = function (ctlId, rawOps) {
        var ops = rawOps.splice(0, MAX_CURATE_SIZE);

        return this.request(
            '/1.1/beta/timelines/custom/curate.json',
            'POST', {
                json: {
                    id: Client.normalizeCTLId(ctlId),
                    changes: ops
                }
            }).then(function (result) {
                if (rawOps.length) {
                    return this._batchCurateCTL(ctlId, rawOps);
                }

                return result;
            }.bind(this));
    };

    /**
     * Overwrites the Tweets in an existing CTL by the given list of new Tweets.
     * This is one by removing all of the existing and adding the new ones
     * afterwards.
     *
     * @callback progressCallback progressCb - What should have gone through the
     * promise.
     *
     * @param {string} ctlId - ID of the CTL to replace.
     * @param {array=} tweetIds - List of Tweet IDs to add to the CTL.
     * @param {progressCallback} progressCb - Takes an object as parameter with
     * the keys {total, value}.
     *
     * @returns {object} Promise reporting the progress if tweetIds have been
     *                   specified.
     */
    Client.prototype.overwriteCTL = function (ctlId, tweetIds, progressCb) {
        return this.getCTL(ctlId).then(function (ctl) {
            progressCb({ value: 0, total: 1 });

            var removeOps = Object.keys(ctl.objects.tweets).map(function (key) {
                return {
                    tweetId: key,
                    op: 'remove'
                };
            });

            // Add them in the reverse order
            var addOps = tweetIds.reverse().map(function (id) {
                return {
                    tweetId: id,
                    op: 'add'
                };
            });

            return this.curateCTL(ctlId, removeOps.concat(addOps));
        }.bind(this));
    };

    Client.prototype.addTweetToCTL = function (ctlId, tweetId) {
        /*jshint camelcase:false */

        return this.request(
            '/1.1/beta/timelines/custom/add.json',
            'POST', { form: {
                id: ctlId,
                tweet_id: tweetId
            } });
    };

    /**
     * Get a conversation from a tweet id
     */
    Client.prototype.getConversation = function (tweetId, params) {
        /*jshint camelcase:false */
        return this.request('/1.1/conversation/show.json', 'GET', {
            params: _.extend({
                id: tweetId
            }, params)
        });
    };

    return Client;
});
<|endoftext|>


<commit_before>'use strict';
angular.module('confRegistrationWebApp', ['ngResource', 'ngCookies', 'ui.bootstrap'])
  .config(function ($routeProvider, $injector) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/admin-dashboard.html',
        controller: 'MainCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth')
        }
      })
      .when('/wizard/:conferenceId', {
        templateUrl: 'views/admin-wizard.html',
        controller: 'AdminWizardCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/register/:conferenceId/page/:pageId', {
        templateUrl: 'views/registration.html',
        controller: 'RegistrationCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          currentRegistration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId);
          }]
        }
      })
      .when('/adminData/:conferenceId', {
        templateUrl: 'views/adminData.html',
        controller: 'AdminDataCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registrations: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getAllForConference($route.current.params.conferenceId);
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/adminDetails/:conferenceId', {
        templateUrl: 'views/adminDetails.html',
        controller: 'AdminDetailsCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registrations: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getAllForConference($route.current.params.conferenceId);
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/register/:conferenceId', {
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          redirectToRegistration: ['$route', 'ConfCache', '$location', function ($route, ConfCache, $location) {
            var conferenceId = $route.current.params.conferenceId;
            ConfCache.get(conferenceId).then(function () {
              $location.replace().path('/register/' + conferenceId + '/page/');
            });
          }]
        }
      })
      .when('/reviewRegistration/:conferenceId', {
        templateUrl: 'views/reviewRegistration.html',
        controller: 'ReviewRegistrationCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId)
              .then(function (currentRegistration) {
                return currentRegistration;
              });
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/payment/:conferenceId', {
        templateUrl: 'views/payment.html',
        controller: 'paymentCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId)
              .then(function (currentRegistration) {
                return currentRegistration;
              });
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/permissions/:conferenceId', {
        templateUrl: 'views/admin-permissions.html',
        controller: 'AdminPermissionsCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/activatePermission/:permissionAuthCode', {
        template: '{{message}}',
        controller: 'ActiviatePermissionCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth')
        }
      })
      .when('/auth/:token', {
        resolve: {
          redirectToIntendedRoute: ['$location', '$cookies', '$route', '$rootScope', 'ProfileCache',
            function ($location, $cookies, $route, $rootScope, ProfileCache) {
              $cookies.crsAuthProviderType = '';
              $cookies.crsPreviousToken = $cookies.crsToken;
              $cookies.crsToken = $route.current.params.token;
              $rootScope.crsToken = $cookies.crsToken;
              ProfileCache.getCache(function (data) {
              $cookies.crsAuthProviderType = data.authProviderType;
              $location.replace().path($cookies.intendedRoute || '/');
              });
            }
          ]
        }
      })
      .otherwise({
        redirectTo: '/'
      });
  })
  .run(function ($rootScope, $cookies, $location) {
    $rootScope.$on('$locationChangeStart', function () {
      if (!/^\/auth\/.*/.test($location.url())) {
        $cookies.intendedRoute = $location.url();
      }
    });
  })
  .config(function ($httpProvider) {
    $httpProvider.interceptors.push('currentRegistrationInterceptor');
    $httpProvider.interceptors.push('httpUrlInterceptor');
    $httpProvider.interceptors.push('authorizationInterceptor');
    $httpProvider.interceptors.push('unauthorizedInterceptor');
    $httpProvider.interceptors.push('debouncePutsInterceptor');
    $httpProvider.interceptors.push('statusInterceptor');
  })
  .run(function ($rootScope, $location) {
    $rootScope.location = $location;
    $rootScope.$watch('location.url()', function (newVal) {
      $rootScope.adminDashboard = angular.equals(newVal, '/');

      $rootScope.subHeadStyle = {
        height: $rootScope.adminDashboard ? '100px' : '5px'
      };
    });
  })
  .config(function ($provide) {
    $provide.decorator('$exceptionHandler', ['$delegate', function ($delegate) {
      return function (exception, cause) {
        $delegate(exception, cause);
        bugsense.notify(exception, cause);
      };
    }]);
  });
<commit_msg>Only set previous token if current token has value and will change.<commit_after>'use strict';
angular.module('confRegistrationWebApp', ['ngResource', 'ngCookies', 'ui.bootstrap'])
  .config(function ($routeProvider, $injector) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/admin-dashboard.html',
        controller: 'MainCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth')
        }
      })
      .when('/wizard/:conferenceId', {
        templateUrl: 'views/admin-wizard.html',
        controller: 'AdminWizardCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/register/:conferenceId/page/:pageId', {
        templateUrl: 'views/registration.html',
        controller: 'RegistrationCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          currentRegistration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId);
          }]
        }
      })
      .when('/adminData/:conferenceId', {
        templateUrl: 'views/adminData.html',
        controller: 'AdminDataCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registrations: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getAllForConference($route.current.params.conferenceId);
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/adminDetails/:conferenceId', {
        templateUrl: 'views/adminDetails.html',
        controller: 'AdminDetailsCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registrations: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getAllForConference($route.current.params.conferenceId);
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/register/:conferenceId', {
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          redirectToRegistration: ['$route', 'ConfCache', '$location', function ($route, ConfCache, $location) {
            var conferenceId = $route.current.params.conferenceId;
            ConfCache.get(conferenceId).then(function () {
              $location.replace().path('/register/' + conferenceId + '/page/');
            });
          }]
        }
      })
      .when('/reviewRegistration/:conferenceId', {
        templateUrl: 'views/reviewRegistration.html',
        controller: 'ReviewRegistrationCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId)
              .then(function (currentRegistration) {
                return currentRegistration;
              });
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/payment/:conferenceId', {
        templateUrl: 'views/payment.html',
        controller: 'paymentCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId)
              .then(function (currentRegistration) {
                return currentRegistration;
              });
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/permissions/:conferenceId', {
        templateUrl: 'views/admin-permissions.html',
        controller: 'AdminPermissionsCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/activatePermission/:permissionAuthCode', {
        template: '{{message}}',
        controller: 'ActiviatePermissionCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth')
        }
      })
      .when('/auth/:token', {
        resolve: {
          redirectToIntendedRoute: ['$location', '$cookies', '$route', '$rootScope', 'ProfileCache',
            function ($location, $cookies, $route, $rootScope, ProfileCache) {
              $cookies.crsAuthProviderType = '';
              if($cookies.crsToken && ($cookies.crsToken != $route.current.params.token)) {
                $cookies.crsPreviousToken = $cookies.crsToken;
              }
              $cookies.crsToken = $route.current.params.token;
              $rootScope.crsToken = $cookies.crsToken;
              ProfileCache.getCache(function (data) {
              $cookies.crsAuthProviderType = data.authProviderType;
              $location.replace().path($cookies.intendedRoute || '/');
              });
            }
          ]
        }
      })
      .otherwise({
        redirectTo: '/'
      });
  })
  .run(function ($rootScope, $cookies, $location) {
    $rootScope.$on('$locationChangeStart', function () {
      if (!/^\/auth\/.*/.test($location.url())) {
        $cookies.intendedRoute = $location.url();
      }
    });
  })
  .config(function ($httpProvider) {
    $httpProvider.interceptors.push('currentRegistrationInterceptor');
    $httpProvider.interceptors.push('httpUrlInterceptor');
    $httpProvider.interceptors.push('authorizationInterceptor');
    $httpProvider.interceptors.push('unauthorizedInterceptor');
    $httpProvider.interceptors.push('debouncePutsInterceptor');
    $httpProvider.interceptors.push('statusInterceptor');
  })
  .run(function ($rootScope, $location) {
    $rootScope.location = $location;
    $rootScope.$watch('location.url()', function (newVal) {
      $rootScope.adminDashboard = angular.equals(newVal, '/');

      $rootScope.subHeadStyle = {
        height: $rootScope.adminDashboard ? '100px' : '5px'
      };
    });
  })
  .config(function ($provide) {
    $provide.decorator('$exceptionHandler', ['$delegate', function ($delegate) {
      return function (exception, cause) {
        $delegate(exception, cause);
        bugsense.notify(exception, cause);
      };
    }]);
  });
<|endoftext|>


<commit_before>/*
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/

(function(document) {
  'use strict';

  // Grab a reference to our auto-binding template
  // and give it some initial binding values
  // Learn more about auto-binding templates at http://goo.gl/Dx1u2g
  var app = document.querySelector('#app');

  app.displayInstalledToast = function() {
    // Check to make sure caching is actually enabled—it won't be in the dev environment.
    if (!document.querySelector('platinum-sw-cache').disabled) {
      document.querySelector('#caching-complete').show();
    }
  };

  // Listen for template bound event to know when bindings
  // have resolved and content has been stamped to the page
  app.addEventListener('dom-change', function() {
    console.log('Our app is ready to rock!');
  });

  // See https://github.com/Polymer/polymer/issues/1381
  window.addEventListener('WebComponentsReady', function() {
    // Ensure the drawer is hidden on desktop/tablet
//    var drawerPanel = document.querySelector('#paperDrawerPanel');
//    drawerPanel.forceNarrow = true;

    var toolbar = document.querySelector('#mainToolbar');
    toolbar.bottomJustify = 'around';

    var loading = document.getElementById('searchmodal');
    loading.noAutoFocus=true;
    loading.noCancelOnEscKey=true;
    loading.noCancelOnOutsideClick=true;
  });

  app.back2results = function(){
    page('/results');
  };

  app.itemSelected = function(){
    console.log('item has been selected, route to directions');
//    app.resultsScrollTop=document.getElementById('').scrollTop;
    app.resultsScrollTop=document.querySelector('.content').scrollTop;
    page('/map');
  };

  // Main area's paper-scroll-header-panel custom condensing transformation of
  // the appName in the middle-container and the bottom title in the bottom-container.
  // The appName is moved to top and shrunk on condensing. The bottom sub title
  // is shrunk to nothing on condensing.
  addEventListener('paper-header-transform', function(e) {
    var appName = document.querySelector('#mainToolbar .app-name');
    var middleContainer = document.querySelector('#mainToolbar .middle-container');
    var bottomContainer = document.querySelector('#mainToolbar .bottom-container');
    var detail = e.detail;
    var heightDiff = detail.height - detail.condensedHeight;
    var yRatio = Math.min(1, detail.y / heightDiff);
    var maxMiddleScale = 0.50;  // appName max size when condensed. The smaller the number the smaller the condensed size.
    var scaleMiddle = Math.max(maxMiddleScale, (heightDiff - detail.y) / (heightDiff / (1-maxMiddleScale))  + maxMiddleScale);
    var scaleBottom = 1 - yRatio;

    // Move/translate middleContainer
    Polymer.Base.transform('translate3d(0,' + yRatio * 100 + '%,0)', middleContainer);

    // Scale bottomContainer and bottom sub title to nothing and back
    Polymer.Base.transform('scale(' + scaleBottom + ') translateZ(0)', bottomContainer);

    // Scale middleContainer appName
    Polymer.Base.transform('scale(' + scaleMiddle + ') translateZ(0)', appName);
  });

  // Close drawer after menu item is selected if drawerPanel is narrow
  app.onDataRouteClick = function() {
    var drawerPanel = document.querySelector('#paperDrawerPanel');
    if (drawerPanel.narrow) {
      drawerPanel.closeDrawer();
    }
  };

  app.focussearch = function(){
    document.getElementById('searchquery').focus();
  };

  app.onSearchFocus = function(){
    console.log('search box focused!');
    page('/results');
  };

  app.startSearchModal = function(){
    console.log('started a catalog fetch');
    document.getElementById('searchmodal').open();

  };
  app.endSearchModal = function(){
    console.log('ended a catalog fetch');
    document.getElementById('searchmodal').close();
  };

  app.isTrue = function(val) {
    return !!(val);
  };

  app.resetHomeTimer = function(min) {
    if (app.timer) clearTimeout(app.timer);
    app.timer = setTimeout(function(){
      page('/');
      // Reload the page to get any changes (many updates coming)
      document.location.reload(true);
    }, min*60*1000);
  }

  document.onmousedown=app.disableclick;
  app.disableclick = function(event) {
    if(event.button == 2) {
      console.log('right click disabled!');
      return false;
    }
  }

})(document);
<commit_msg>cleanup<commit_after>/*
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/

(function(document) {
  'use strict';

  // Grab a reference to our auto-binding template
  // and give it some initial binding values
  // Learn more about auto-binding templates at http://goo.gl/Dx1u2g
  var app = document.querySelector('#app');

  // Listen for template bound event to know when bindings
  // have resolved and content has been stamped to the page
  app.addEventListener('dom-change', function() {
    console.log('Our app is ready to rock!');
  });

  // See https://github.com/Polymer/polymer/issues/1381
  window.addEventListener('WebComponentsReady', function() {
    // Ensure the drawer is hidden on desktop/tablet
//    var drawerPanel = document.querySelector('#paperDrawerPanel');
//    drawerPanel.forceNarrow = true;

    var toolbar = document.querySelector('#mainToolbar');
    toolbar.bottomJustify = 'around';

    var loading = document.getElementById('searchmodal');
    loading.noAutoFocus=true;
    loading.noCancelOnEscKey=true;
    loading.noCancelOnOutsideClick=true;
  });

  app.back2results = function(){
    page('/results');
  };

  app.itemSelected = function(){
    console.log('item has been selected, route to directions');
    app.resultsScrollTop=document.querySelector('.content').scrollTop;
    page('/map');
  };

  // Close drawer after menu item is selected if drawerPanel is narrow
  app.onDataRouteClick = function() {
    var drawerPanel = document.querySelector('#paperDrawerPanel');
    if (drawerPanel.narrow) {
      drawerPanel.closeDrawer();
    }
  };

  app.focussearch = function(){
    document.getElementById('searchquery').focus();
  };

  app.onSearchFocus = function(){
    console.log('search box focused!');
    page('/results');
  };

  app.startSearchModal = function(){
    console.log('started a catalog fetch');
    document.getElementById('searchmodal').open();

  };
  app.endSearchModal = function(){
    console.log('ended a catalog fetch');
    document.getElementById('searchmodal').close();
  };

  app.isTrue = function(val) {
    return !!(val);
  };

  app.resetHomeTimer = function(min) {
    if (app.timer) clearTimeout(app.timer);
    app.timer = setTimeout(function(){
      page('/');
      // Reload the page to get any changes (many updates coming)
      document.location.reload(true);
    }, min*60*1000);
  }

  document.onmousedown=app.disableclick;
  app.disableclick = function(event) {
    if(event.button == 2) {
      console.log('right click disabled!');
      return false;
    }
  }

})(document);
<|endoftext|>


<commit_before>
//empty array used to inject dependencies (external modules)
angular.module('blocJams', ['ui.router']);

angular.module('blocJams').config(function($stateProvider, $locationProvider){
//disable #! default in path
  $locationProvider.html5Mode({
    enabled: true,
    requireBase: false
  });

  $stateProvider.state('album', {
    url: '/album',
    controller: 'AlbumController',
    templateUrl: '/templates/album.html'
  });

  $stateProvider.state('collection', {
    url: '/collection',
    controller: 'CollectionController',
    templateUrl: '/templates/collection.html'
  });

  $stateProvider.state('landing', {
    url: '/',
    controller: 'LandingController',
    templateUrl: '/templates/landing.html'
  });

});

<commit_msg>added note to app.js<commit_after>//routes file
//empty array used to inject dependencies (external modules)
angular.module('blocJams', ['ui.router']);

angular.module('blocJams').config(function($stateProvider, $locationProvider){
//disable #! default in path
  $locationProvider.html5Mode({
    enabled: true,
    requireBase: false
  });

  $stateProvider.state('album', {
    url: '/album',
    controller: 'AlbumController',
    templateUrl: '/templates/album.html'
  });

  $stateProvider.state('collection', {
    url: '/collection',
    controller: 'CollectionController',
    templateUrl: '/templates/collection.html'
  });

  $stateProvider.state('landing', {
    url: '/',
    controller: 'LandingController',
    templateUrl: '/templates/landing.html'
  });

});

<|endoftext|>


<commit_before>/**
 * (C) 2013 Sazze, Inc.
 * MIT LICENCE
 *
 * Based on a gist by mbrevoort.
 * Available at: https://gist.github.com/mbrevoort/5848179
 *
 * Inspired by winston-logstash
 * Available at: https://github.com/jaakkos/winston-logstash
 */

// Really simple Winston Logstash UDP Logger

var dgram = require('dgram'),
    util = require('util'),
    os = require('os'),
    winston = require('winston'),
    common = require('winston/lib/winston/common'),
    cycle = require('cycle');

var LogstashUDP = exports.LogstashUDP = function(options) {
    winston.Transport.call(this, options);
    options = options || {};

    this.name = 'logstashUdp';
    this.level = options.level || 'info';
    this.localhost = options.localhost || os.hostname();
    this.host = options.host || options.udpType === 'udp6' ? '::1' : '127.0.0.1';
    this.port = options.port || 9999;
    this.application = options.appName || process.title;
    this.pid = options.pid || process.pid;
    this.trailingLineFeed = options.trailingLineFeed === true;
    this.trailingLineFeedChar = options.trailingLineFeedChar || os.EOL;
    this.udpType = options.udpType === 'udp6' ? 'udp6' : 'udp4';

    this.client = null;

    this.connect();
};

util.inherits(LogstashUDP, winston.Transport);

//
// Define a getter so that `winston.transports.LogstashUDP`
// is available and thus backwards compatible.
//
winston.transports.LogstashUDP = LogstashUDP;

LogstashUDP.prototype.connect = function() {
    this.client = dgram.createSocket(this.udpType);

    // Attach an error listener on the socket
    // It can also avoid top level exceptions like UDP DNS errors thrown by the socket
    this.client.on('error', function(err) {
        // in node versions <= 0.12, the error event is emitted even when a callback is passed to send()
        // we always pass a callback to send(), so it's safe to do nothing here
    });

    if (this.client.unref) {
        this.client.unref();
    }
};

LogstashUDP.prototype.log = function(level, msg, meta, callback) {
    var self = this,
        meta = winston.clone(cycle.decycle(meta) || {}),
        logEntry;

    callback = (callback || function () {});

    if (self.silent) {
        return callback(null, true);
    }

    meta.application = self.application;
    meta.serverName = self.localhost;
    meta.pid = self.pid;

    logEntry = common.log({
        level: level,
        message: msg,
        meta: meta,
        timestamp: self.timestamp,
        json: true
    });

    self.sendLog(logEntry, function (err) {
        self.emit('logged', !err);

        callback(err, !err);
    });

};

LogstashUDP.prototype.sendLog = function(message, callback) {
    var self = this;

    if (this.trailingLineFeed === true) {
        message = message.replace(/\s+$/, '') + this.trailingLineFeedChar;
    }

    var buf = new Buffer(message);

    callback = (callback || function () {});

    self.client.send(buf, 0, buf.length, self.port, self.host, callback);
};
<commit_msg>ensure order of operations when assigning the host to sent logs to<commit_after>/**
 * (C) 2013 Sazze, Inc.
 * MIT LICENCE
 *
 * Based on a gist by mbrevoort.
 * Available at: https://gist.github.com/mbrevoort/5848179
 *
 * Inspired by winston-logstash
 * Available at: https://github.com/jaakkos/winston-logstash
 */

// Really simple Winston Logstash UDP Logger

var dgram = require('dgram'),
    util = require('util'),
    os = require('os'),
    winston = require('winston'),
    common = require('winston/lib/winston/common'),
    cycle = require('cycle');

var LogstashUDP = exports.LogstashUDP = function(options) {
    winston.Transport.call(this, options);
    options = options || {};

    this.name = 'logstashUdp';
    this.level = options.level || 'info';
    this.localhost = options.localhost || os.hostname();
    this.host = options.host || (options.udpType === 'udp6' ? '::1' : '127.0.0.1');
    this.port = options.port || 9999;
    this.application = options.appName || process.title;
    this.pid = options.pid || process.pid;
    this.trailingLineFeed = options.trailingLineFeed === true;
    this.trailingLineFeedChar = options.trailingLineFeedChar || os.EOL;
    this.udpType = options.udpType === 'udp6' ? 'udp6' : 'udp4';

    this.client = null;

    this.connect();
};

util.inherits(LogstashUDP, winston.Transport);

//
// Define a getter so that `winston.transports.LogstashUDP`
// is available and thus backwards compatible.
//
winston.transports.LogstashUDP = LogstashUDP;

LogstashUDP.prototype.connect = function() {
    this.client = dgram.createSocket(this.udpType);

    // Attach an error listener on the socket
    // It can also avoid top level exceptions like UDP DNS errors thrown by the socket
    this.client.on('error', function(err) {
        // in node versions <= 0.12, the error event is emitted even when a callback is passed to send()
        // we always pass a callback to send(), so it's safe to do nothing here
    });

    if (this.client.unref) {
        this.client.unref();
    }
};

LogstashUDP.prototype.log = function(level, msg, meta, callback) {
    var self = this,
        meta = winston.clone(cycle.decycle(meta) || {}),
        logEntry;

    callback = (callback || function () {});

    if (self.silent) {
        return callback(null, true);
    }

    meta.application = self.application;
    meta.serverName = self.localhost;
    meta.pid = self.pid;

    logEntry = common.log({
        level: level,
        message: msg,
        meta: meta,
        timestamp: self.timestamp,
        json: true
    });

    self.sendLog(logEntry, function (err) {
        self.emit('logged', !err);

        callback(err, !err);
    });

};

LogstashUDP.prototype.sendLog = function(message, callback) {
    var self = this;

    if (this.trailingLineFeed === true) {
        message = message.replace(/\s+$/, '') + this.trailingLineFeedChar;
    }

    var buf = new Buffer(message);

    callback = (callback || function () {});

    self.client.send(buf, 0, buf.length, self.port, self.host, callback);
};
<|endoftext|>


<commit_before>define('model/login/loginModel', ['lib/common', 'api/login/loginApi'],
    function ($, loginApi) {
        function login(dataInfo, callback) {
            var dataInfo = dataInfo || {};
            $.xsr($.makeUrl(loginApi.login, dataInfo.post), function (res) {
                try {
                    callback && callback(res);
                } catch (e) {
                    //TODO handle the exception
                    throw e;
                }
            });
        };

        function signUp(dataInfo, callback) {
            var dataInfo = dataInfo || {};
            $.xsr($.makeUrl(loginApi.signUp, dataInfo.post), function (res) {
                try {
                    callback && callback(res);
                } catch (e) {
                    //TODO handle the exception
                    throw e;
                }
            });
        };
        return {
            login: login,   //
            signUp: signUp
         }
    }
);
<commit_msg>no message<commit_after>define('model/login/loginModel', ['lib/common', 'api/login/loginApi'],
    function ($, loginApi) {
        function login(dataInfo, callback) {
            var dataInfo = dataInfo || {};
            $.xsr($.makeUrl(loginApi.login, dataInfo.post), function (res) {
                try {
                    callback && callback(res);
                } catch (e) {
                    //TODO handle the exception
                    throw e;
                }
            });
        };

        function signUp(dataInfo, callback) {
            var dataInfo = dataInfo || {};
            $.xsr($.makeUrl(loginApi.signUp, dataInfo.post), function (res) {
                try {
                    callback && callback(res);
                } catch (e) {
                    //TODO handle the exception
                    throw e;
                }
            });
        };

        return {
            login: login,   //
            signUp: signUp
         }
    }
);
<|endoftext|>


<commit_before>/**
 * The main editor c;omponent
 */

import React, { Component } from 'react';
import {
  Editor,
  EditorState,
  getDefaultKeyBinding,
  KeyBindingUtil,
} from 'draft-js';
import createCompositeDecorator from '../utils/createCompositeDecorator';
import moveSelectionToEnd from '../utils/moveSelectionToEnd';
import moveToEndOfSelectedBlock from '../modifiers/moveToEndOfSelectedBlock';
import moveToStartOfSelectedBlock from '../modifiers/moveToStartOfSelectedBlock';
import { List } from 'immutable';

export default class PluginEditor extends Component {

  // TODO add flow types & propTypes - since it's a library and people might not use flow we want to have both

  constructor(props) {
    super(props);
    this.plugins = List(props.plugins)
      .filter((plugin) => plugin.pluginProps !== undefined)
      .map((plugin) => plugin.pluginProps)
      .toArray();
    const compositeDecorator = createCompositeDecorator(this.plugins, this.getEditorState, this.onChange);

    // TODO consider triggering an onChange here to make sure the editorState is in sync
    // with the outer Editor context
    const editorState = EditorState.set(this.props.editorState, { decorator: compositeDecorator });
    this.editorState = moveSelectionToEnd(editorState);
  }

  componentWillMount() {
    // Makes sure the editorState of the wrapping component is in sync with the
    // internal one, because we added the decorator in the constructor.
    if (this.props.onChange) {
      this.props.onChange(this.editorState);
    }
  }

  componentWillReceiveProps(props) {
    this.editorState = props.editorState;
  }

  // Cycle through the plugins, changing the editor state with what the plugins
  // changed (or didn't)
  onChange = (editorState) => {
    let newEditorState = editorState;
    this.plugins.forEach((plugin) => {
      if (plugin.onChange) {
        newEditorState = plugin.onChange(newEditorState);
      }
    });

    if (this.props.onChange) {
      this.props.onChange(newEditorState);
    }
  };

  onDownArrow = (keyboardEvent) => {
    // TODO allow to provide a custom onDownArrow

    this.plugins.map((plugin) => {
      if (plugin.onDownArrow) {
        plugin.onDownArrow(keyboardEvent);
      }

      return undefined;
    });
  };

  onUpArrow = (keyboardEvent) => {
    // TODO allow to provide a custom onUpArrow

    this.plugins.map((plugin) => {
      if (plugin.onUpArrow) {
        plugin.onUpArrow(keyboardEvent);
      }

      return undefined;
    });
  };

  onEscape = (keyboardEvent) => {
    // TODO allow to provide a custom onEscape

    this.plugins.map((plugin) => {
      if (plugin.onEscape) {
        plugin.onEscape(keyboardEvent);
      }

      return undefined;
    });
  };

  onTab = (keyboardEvent) => {
    // TODO allow to provide a custom onTab

    this.plugins.map((plugin) => {
      if (plugin.onTab) {
        plugin.onTab(keyboardEvent);
      }

      return undefined;
    });
  };

  getEditorState = () => this.editorState;

  handleKeyCommand = (command) => {
    if (this.props.handleKeyCommand) {
      const handled = this.props.handleKeyCommand(command);
      if (handled === true) {
        return handled;
      }
    }

    // TODO optimize to break after the first one
    let preventDefaultBehaviour = this.plugins
      .map((plugin) => {
        if (plugin.handleKeyCommand) {
          const handled = plugin.handleKeyCommand(command);
          if (handled === true) {
            return handled;
          }
        }

        return undefined;
      })
      .find((result) => result === true);

    if (command === 'plugin-editor-move-to-start') {
      moveToStartOfSelectedBlock(this.editorState, this.props.onChange);
      preventDefaultBehaviour = true;
    } else if (command === 'plugin-editor-move-to-end') {
      moveToEndOfSelectedBlock(this.editorState, this.props.onChange);
      preventDefaultBehaviour = true;
    }

    // TODO allow to provide a custom handleKeyCommand
    return preventDefaultBehaviour === true;
  };

  handleReturn = (keyboardEvent) => {
    // TODO optimize to break after the first one
    const preventDefaultBehaviour = this.plugins
      .map((plugin) => {
        if (plugin.handleReturn) {
          const handled = plugin.handleReturn(keyboardEvent);
          if (handled === true) {
            return handled;
          }
        }

        return undefined;
      })
      .find((result) => result === true);

    // TODO allow to provide a custom handleReturn
    return preventDefaultBehaviour === true;
  };

  keyBindingFn = (keyboardEvent) => {
    // TODO optimize to break after the first one
    let command = this.plugins
      .map((plugin) => {
        if (plugin.keyBindingFn) {
          const pluginCommand = plugin.keyBindingFn(keyboardEvent);
          if (pluginCommand) {
            return pluginCommand;
          }
        }

        return undefined;
      })
      .find((result) => result !== undefined);

    if (command === undefined) {
      if (keyboardEvent.keyCode === 37 && KeyBindingUtil.hasCommandModifier(keyboardEvent)) {
        command = 'plugin-editor-move-to-start';
      } else if (keyboardEvent.keyCode === 39 && KeyBindingUtil.hasCommandModifier(keyboardEvent)) {
        command = 'plugin-editor-move-to-end';
      }
    }

    // TODO allow to provide a custom handleKeyCommand

    return command !== undefined ? command : getDefaultKeyBinding(keyboardEvent);
  };

  blockRendererFn = (contentBlock) => {
    // TODO optimize to break after the first one
    if (this.props.blockRendererFn) {
      const result = this.props.blockRendererFn(contentBlock);
      if (result) {
        return result;
      }
    }

    return this.plugins
      .map((plugin) => {
        if (plugin.blockRendererFn) {
          const result = plugin.blockRendererFn(contentBlock, this.getEditorState, this.onChange);
          if (result) {
            return result;
          }
        }

        return undefined;
      })
      .find((result) => result !== undefined);
  };

  // Put the keyboard focus on the editor
  focus = () => {
    this.refs.editor.focus();
  };

  render() {
    let pluginProps = {};
    this.plugins.forEach((plugin) => {
      if (plugin.getEditorProps) {
        pluginProps = {
          ...pluginProps,
          ...plugin.getEditorProps(),
        };
      }
    });

    return (
      <Editor
        {...pluginProps}
        {...this.props}
        onChange={ this.onChange }
        editorState={ this.editorState }
        blockRendererFn={ this.blockRendererFn }
        handleKeyCommand={ this.handleKeyCommand }
        keyBindingFn={ this.keyBindingFn }
        onDownArrow={ this.onDownArrow }
        onTab={ this.onTab }
        onUpArrow={ this.onUpArrow }
        onEscape={ this.onEscape }
        handleReturn={ this.handleReturn }
        ref="editor"
      />
    );
  }
}
<commit_msg>fix behaviour for custom handleKeyCommand<commit_after>/**
 * The main editor c;omponent
 */

import React, { Component } from 'react';
import {
  Editor,
  EditorState,
  getDefaultKeyBinding,
  KeyBindingUtil,
} from 'draft-js';
import createCompositeDecorator from '../utils/createCompositeDecorator';
import moveSelectionToEnd from '../utils/moveSelectionToEnd';
import moveToEndOfSelectedBlock from '../modifiers/moveToEndOfSelectedBlock';
import moveToStartOfSelectedBlock from '../modifiers/moveToStartOfSelectedBlock';
import { List } from 'immutable';

export default class PluginEditor extends Component {

  // TODO add flow types & propTypes - since it's a library and people might not use flow we want to have both

  constructor(props) {
    super(props);
    this.plugins = List(props.plugins)
      .filter((plugin) => plugin.pluginProps !== undefined)
      .map((plugin) => plugin.pluginProps)
      .toArray();
    const compositeDecorator = createCompositeDecorator(this.plugins, this.getEditorState, this.onChange);

    // TODO consider triggering an onChange here to make sure the editorState is in sync
    // with the outer Editor context
    const editorState = EditorState.set(this.props.editorState, { decorator: compositeDecorator });
    this.editorState = moveSelectionToEnd(editorState);
  }

  componentWillMount() {
    // Makes sure the editorState of the wrapping component is in sync with the
    // internal one, because we added the decorator in the constructor.
    if (this.props.onChange) {
      this.props.onChange(this.editorState);
    }
  }

  componentWillReceiveProps(props) {
    this.editorState = props.editorState;
  }

  // Cycle through the plugins, changing the editor state with what the plugins
  // changed (or didn't)
  onChange = (editorState) => {
    let newEditorState = editorState;
    this.plugins.forEach((plugin) => {
      if (plugin.onChange) {
        newEditorState = plugin.onChange(newEditorState);
      }
    });

    if (this.props.onChange) {
      this.props.onChange(newEditorState);
    }
  };

  onDownArrow = (keyboardEvent) => {
    // TODO allow to provide a custom onDownArrow

    this.plugins.map((plugin) => {
      if (plugin.onDownArrow) {
        plugin.onDownArrow(keyboardEvent);
      }

      return undefined;
    });
  };

  onUpArrow = (keyboardEvent) => {
    // TODO allow to provide a custom onUpArrow

    this.plugins.map((plugin) => {
      if (plugin.onUpArrow) {
        plugin.onUpArrow(keyboardEvent);
      }

      return undefined;
    });
  };

  onEscape = (keyboardEvent) => {
    // TODO allow to provide a custom onEscape

    this.plugins.map((plugin) => {
      if (plugin.onEscape) {
        plugin.onEscape(keyboardEvent);
      }

      return undefined;
    });
  };

  onTab = (keyboardEvent) => {
    // TODO allow to provide a custom onTab

    this.plugins.map((plugin) => {
      if (plugin.onTab) {
        plugin.onTab(keyboardEvent);
      }

      return undefined;
    });
  };

  getEditorState = () => this.editorState;

  handleKeyCommand = (command) => {
    let preventDefaultBehaviour = false;
    if (this.props.handleKeyCommand) {
      const handled = this.props.handleKeyCommand(command);
      if (handled === true) {
        preventDefaultBehaviour = true;
      }
    }

    // TODO optimize to break after the first one
    preventDefaultBehaviour = this.plugins
      .map((plugin) => {
        if (plugin.handleKeyCommand) {
          const handled = plugin.handleKeyCommand(command);
          if (handled === true) {
            return handled;
          }
        }

        return undefined;
      })
      .find((result) => result === true);

    if (command === 'plugin-editor-move-to-start') {
      moveToStartOfSelectedBlock(this.editorState, this.props.onChange);
      preventDefaultBehaviour = true;
    } else if (command === 'plugin-editor-move-to-end') {
      moveToEndOfSelectedBlock(this.editorState, this.props.onChange);
      preventDefaultBehaviour = true;
    }

    return preventDefaultBehaviour === true;
  };

  handleReturn = (keyboardEvent) => {
    // TODO optimize to break after the first one
    const preventDefaultBehaviour = this.plugins
      .map((plugin) => {
        if (plugin.handleReturn) {
          const handled = plugin.handleReturn(keyboardEvent);
          if (handled === true) {
            return handled;
          }
        }

        return undefined;
      })
      .find((result) => result === true);

    // TODO allow to provide a custom handleReturn
    return preventDefaultBehaviour === true;
  };

  keyBindingFn = (keyboardEvent) => {
    // TODO optimize to break after the first one
    let command = this.plugins
      .map((plugin) => {
        if (plugin.keyBindingFn) {
          const pluginCommand = plugin.keyBindingFn(keyboardEvent);
          if (pluginCommand) {
            return pluginCommand;
          }
        }

        return undefined;
      })
      .find((result) => result !== undefined);

    if (command === undefined) {
      if (keyboardEvent.keyCode === 37 && KeyBindingUtil.hasCommandModifier(keyboardEvent)) {
        command = 'plugin-editor-move-to-start';
      } else if (keyboardEvent.keyCode === 39 && KeyBindingUtil.hasCommandModifier(keyboardEvent)) {
        command = 'plugin-editor-move-to-end';
      }
    }

    // TODO allow to provide a custom handleKeyCommand

    return command !== undefined ? command : getDefaultKeyBinding(keyboardEvent);
  };

  blockRendererFn = (contentBlock) => {
    // TODO optimize to break after the first one
    if (this.props.blockRendererFn) {
      const result = this.props.blockRendererFn(contentBlock);
      if (result) {
        return result;
      }
    }

    return this.plugins
      .map((plugin) => {
        if (plugin.blockRendererFn) {
          const result = plugin.blockRendererFn(contentBlock, this.getEditorState, this.onChange);
          if (result) {
            return result;
          }
        }

        return undefined;
      })
      .find((result) => result !== undefined);
  };

  // Put the keyboard focus on the editor
  focus = () => {
    this.refs.editor.focus();
  };

  render() {
    let pluginProps = {};
    this.plugins.forEach((plugin) => {
      if (plugin.getEditorProps) {
        pluginProps = {
          ...pluginProps,
          ...plugin.getEditorProps(),
        };
      }
    });

    return (
      <Editor
        {...pluginProps}
        {...this.props}
        onChange={ this.onChange }
        editorState={ this.editorState }
        blockRendererFn={ this.blockRendererFn }
        handleKeyCommand={ this.handleKeyCommand }
        keyBindingFn={ this.keyBindingFn }
        onDownArrow={ this.onDownArrow }
        onTab={ this.onTab }
        onUpArrow={ this.onUpArrow }
        onEscape={ this.onEscape }
        handleReturn={ this.handleReturn }
        ref="editor"
      />
    );
  }
}
<|endoftext|>


<commit_before>'use strict';

var app = angular.module('iutubeApp', [
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ngRoute',
    'ui.bootstrap'
  ]);

app.config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });

app.config(function($httpProvider) {
  //Enable cross domain calls
  $httpProvider.defaults.useXDomain = true;

  //Remove the header used to identify ajax call  that would prevent CORS from working
  delete $httpProvider.defaults.headers.common['X-Requested-With'];
});

app.run(function() {
  var tag = document.createElement('script');
  tag.src = "https://www.youtube.com/iframe_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});<commit_msg>fixing race condition on loading youtube API<commit_after>'use strict';

var app = angular.module('iutubeApp', [
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ngRoute',
    'ui.bootstrap'
  ]);

app.config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });

app.config(function($httpProvider) {
  //Enable cross domain calls
  $httpProvider.defaults.useXDomain = true;

  //Remove the header used to identify ajax call  that would prevent CORS from working
  delete $httpProvider.defaults.headers.common['X-Requested-With'];
});

app.run(function() {
    setTimeout(function(){
        var tag = document.createElement('script');
        tag.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }, 500);
});<|endoftext|>