<commit_before>import ProgressBar from './progress-bar';
import {
  errorFromDirectUploadMessage,
  FAILURE_CONNECTIVITY
} from './file-upload-error';
import { fire } from '@utils';

const INITIALIZE_EVENT = 'direct-upload:initialize';
const START_EVENT = 'direct-upload:start';
const PROGRESS_EVENT = 'direct-upload:progress';
const ERROR_EVENT = 'direct-upload:error';
const END_EVENT = 'direct-upload:end';

function addUploadEventListener(type, handler) {
  addEventListener(type, (event) => {
    // Internet Explorer and Edge will sometime replay Javascript events
    // that were dispatched just before a page navigation (!), but without
    // the event payload.
    //
    // Ignore these replayed events.
    const isEventValid = event && event.detail && event.detail.id != undefined;
    if (!isEventValid) return;

    handler(event);
  });
}

addUploadEventListener(INITIALIZE_EVENT, ({ target, detail: { id, file } }) => {
  ProgressBar.init(target, id, file);
});

addUploadEventListener(START_EVENT, ({ target, detail: { id } }) => {
  ProgressBar.start(id);
  // At the end of the upload, the form will be submitted again.
  // Avoid the confirm dialog to be presented again then.
  const button = target.form.querySelector('button.primary');
  if (button) {
    button.removeAttribute('data-confirm');
  }
});

addUploadEventListener(PROGRESS_EVENT, ({ detail: { id, progress } }) => {
  ProgressBar.progress(id, progress);
});

addUploadEventListener(ERROR_EVENT, (event) => {
  let id = event.detail.id;
  let errorMsg = event.detail.error;

  // Display an error message
  alert(
    `Nous sommes désolés, une erreur s’est produite lors de l’envoi du fichier.

    (${errorMsg})`
  );
  // Prevent ActiveStorage from displaying its own error message
  event.preventDefault();

  ProgressBar.error(id, errorMsg);

  let error = errorFromDirectUploadMessage(errorMsg);
  if (error.failureReason != FAILURE_CONNECTIVITY) {
    fire(document, 'sentry:capture-exception', error);
  }
});

addUploadEventListener(END_EVENT, ({ detail: { id } }) => {
  ProgressBar.end(id);
});
<commit_msg>javascript: ignore most common upload errors also in standard uploads<commit_after>import ProgressBar from './progress-bar';
import {
  errorFromDirectUploadMessage,
  ERROR_CODE_READ,
  FAILURE_CLIENT
} from './file-upload-error';
import { fire } from '@utils';

const INITIALIZE_EVENT = 'direct-upload:initialize';
const START_EVENT = 'direct-upload:start';
const PROGRESS_EVENT = 'direct-upload:progress';
const ERROR_EVENT = 'direct-upload:error';
const END_EVENT = 'direct-upload:end';

function addUploadEventListener(type, handler) {
  addEventListener(type, (event) => {
    // Internet Explorer and Edge will sometime replay Javascript events
    // that were dispatched just before a page navigation (!), but without
    // the event payload.
    //
    // Ignore these replayed events.
    const isEventValid = event && event.detail && event.detail.id != undefined;
    if (!isEventValid) return;

    handler(event);
  });
}

addUploadEventListener(INITIALIZE_EVENT, ({ target, detail: { id, file } }) => {
  ProgressBar.init(target, id, file);
});

addUploadEventListener(START_EVENT, ({ target, detail: { id } }) => {
  ProgressBar.start(id);
  // At the end of the upload, the form will be submitted again.
  // Avoid the confirm dialog to be presented again then.
  const button = target.form.querySelector('button.primary');
  if (button) {
    button.removeAttribute('data-confirm');
  }
});

addUploadEventListener(PROGRESS_EVENT, ({ detail: { id, progress } }) => {
  ProgressBar.progress(id, progress);
});

addUploadEventListener(ERROR_EVENT, (event) => {
  let id = event.detail.id;
  let errorMsg = event.detail.error;

  // Display an error message
  alert(
    `Nous sommes désolés, une erreur s’est produite lors de l’envoi du fichier.

    (${errorMsg})`
  );
  // Prevent ActiveStorage from displaying its own error message
  event.preventDefault();

  ProgressBar.error(id, errorMsg);

  // Report unexpected client errors to Sentry.
  // (But ignore usual client errors, or errors we can monitor better on the server side.)
  let error = errorFromDirectUploadMessage(errorMsg);
  if (error.failureReason == FAILURE_CLIENT && error.code != ERROR_CODE_READ) {
    fire(document, 'sentry:capture-exception', error);
  }
});

addUploadEventListener(END_EVENT, ({ detail: { id } }) => {
  ProgressBar.end(id);
});
<|endoftext|>


<commit_before>"use strict";

// @ngInject
let expandSearch = function() {

  return {
    restrict: 'E',
    scope: {
      options: '='
    },
    template: require('./expandSearch.html'),
    // @ngInject
    controller: function($scope, $element, $mdMedia, $timeout, $location, NpdcSearchService, npdcAppConfig) {

      $scope.$mdMedia = $mdMedia;
      $scope.isOpen = false;
      $scope.isFiltersOpen = false;
      $scope.query = { q: $location.search().q };
      $scope.filterCount = null;

      if ($scope.options.autocomplete) {
        $scope.options.autocomplete = Object.assign({}, $scope.options.autocomplete, $scope.query);
      }
      $scope.placeholder = $scope.options.placeholder || 'Search ' + npdcAppConfig.toolbarTitle;

      $scope.blockEvent = function($event) {
        $event.stopImmediatePropagation();
        return false;
      };

      $scope.open = function() {
        let input = $element[0].querySelector('.np-es-input input');
        if (input) {
          input.focus();
        }

        // Firefox workaround
        $timeout(() => {
          $scope.isOpen = true;
        }, 1);

        return false;
      };

      $scope.keyup = function($event) {
        if ($event.keyCode === 27) {
          $scope.close();
        }
        if ($event.keyCode === 13) {
          $scope.search($scope.query);
        }
      };

      $scope.close = function () {
        $scope.isOpen = false;
      };

      $scope.search = function(q) {
        let query = Object.assign({},
          $location.search(),
          q || $scope.query,
          $scope.options.autocomplete ? {q: $scope.options.autocomplete.q} : {});
        NpdcSearchService.search(query);
      };

      $scope.toggleFilters = function () {
        $scope.isFiltersOpen = !$scope.isFiltersOpen;
        // Wait for transition
        $timeout(() => {
          $scope.$broadcast('reCalcViewDimensions');
        }, 520);
      };

      $scope.$watch('query.q', (newVal, oldVal) => {
        if (newVal !== oldVal) {
          $scope.search({q: newVal});
        }
      });

      $scope.$on('filter-change', function (event, data) {
        $scope.filterCount = data.count || 0;
        let query = Object.assign({},
          data.q,
          $scope.options.autocomplete ? {q: $scope.options.autocomplete.q} : $scope.query);
        NpdcSearchService.search(query);
      });

    }
  };
};

module.exports = expandSearch;
<commit_msg>Quick fix to shut up angular when $scope.options is not defined<commit_after>"use strict";

// @ngInject
let expandSearch = function() {

  return {
    restrict: 'E',
    scope: {
      options: '='
    },
    template: require('./expandSearch.html'),
    // @ngInject
    controller: function($scope, $element, $mdMedia, $timeout, $location, NpdcSearchService, npdcAppConfig) {

      $scope.$mdMedia = $mdMedia;
      $scope.isOpen = false;
      $scope.isFiltersOpen = false;
      $scope.query = { q: $location.search().q };
      $scope.filterCount = null;

      if ($scope.options) {
        if ($scope.options.autocomplete) {
          $scope.options.autocomplete = Object.assign({}, $scope.options.autocomplete, $scope.query);
        }
        $scope.placeholder = $scope.options.placeholder || 'Search ' + npdcAppConfig.toolbarTitle;
      }

      $scope.blockEvent = function($event) {
        $event.stopImmediatePropagation();
        return false;
      };

      $scope.open = function() {
        let input = $element[0].querySelector('.np-es-input input');
        if (input) {
          input.focus();
        }

        // Firefox workaround
        $timeout(() => {
          $scope.isOpen = true;
        }, 1);

        return false;
      };

      $scope.keyup = function($event) {
        if ($event.keyCode === 27) {
          $scope.close();
        }
        if ($event.keyCode === 13) {
          $scope.search($scope.query);
        }
      };

      $scope.close = function () {
        $scope.isOpen = false;
      };

      $scope.search = function(q) {
        let query = Object.assign({},
          $location.search(),
          q || $scope.query,
          $scope.options.autocomplete ? {q: $scope.options.autocomplete.q} : {});
        NpdcSearchService.search(query);
      };

      $scope.toggleFilters = function () {
        $scope.isFiltersOpen = !$scope.isFiltersOpen;
        // Wait for transition
        $timeout(() => {
          $scope.$broadcast('reCalcViewDimensions');
        }, 520);
      };

      $scope.$watch('query.q', (newVal, oldVal) => {
        if (newVal !== oldVal) {
          $scope.search({q: newVal});
        }
      });

      $scope.$on('filter-change', function (event, data) {
        $scope.filterCount = data.count || 0;
        let query = Object.assign({},
          data.q,
          $scope.options.autocomplete ? {q: $scope.options.autocomplete.q} : $scope.query);
        NpdcSearchService.search(query);
      });

    }
  };
};

module.exports = expandSearch;
<|endoftext|>


<commit_before>/**
 * For the evalAssign view
 */
$(document).ready(function() {
    //trigger FB overrides
    evalAssignFacebox.init();
    $('a[rel=assignInstructorSelector]').assignSelector({type:0});
    $('a[rel=assignTaSelector]').assignSelector({type:1});
    $(':submit').bind('click', function() {
        //Validate group Selections
        var countChecked = $('form[id=eval-assign-form] input[@type=checkbox]:checked').get().length;
        if (countChecked == null || countChecked == 0) {
            $('#error').fadeIn(0);
            return false;
        } else {
            $('#error').fadeOut(0);
        }
        return true;
    });
});

(function($) {
    $.fn.assignSelector = function(opts) {
        var options = $.extend({}, $.fn.assignSelector.defaults, opts);
        init($(this), options);
    };
    /**
     * Public variables. Once init() has ran, do not reference directly to these, use variables.options instead.
     */
    $.fn.assignSelector.defaults = {
        type: 1, //Type is for type of category we are handling. ie: 0 = instructor, 1 = ta
        debug: typeof window.console !== "undefined"
    };
    /**
     * Private methods and variables
     *
     */

    var variables = {
        option:null,
        get:{
            typeOfBranch:function() {
                switch (variables.options.type) {
                    case 0: return "instructor";break;
                    case 1: return "ta";break;
                }
            },
            siteId:false,
            documentFB:null
        },
        set:{
            typeOfBranch:function(that) {
                var temp;
                if (that.attr('rel').search(/instructor/i) != -1)
                    temp = 0;
                else if (that.attr('rel').search(/tas/i) != -1)
                    temp = 1;
                variables.options.type = temp;
                log("Active catergory type is: " + variables.get.typeOfBranch());
            },
            siteId:function(that) {
                variables.get.siteId = that.parents('tr:eq(0)').find('input:eq(0)').val();
                return !variables.get.siteId ? false : true;  //Do not simplify this. Should return true if siteId is anything other than false.
            }
        },
        selectedPeople:0,
        deselectedPeopleIds: new Array(),
        initedafterRevealFacebox:0,
        that:null,
        deselectedLog:new Array(),
        thatRowNumber:0 ,
        evalGroupId:null,
        groupCheckBox:null,
        css: {
            enabled:{
                color: ""
            },
            disabled:{
                color: "#888"
            }
        }
    };

    function init(that, options) {
        //copy options to this class
        variables.options = options;
        $(document).bind('afterReveal.facebox', function() {
            variables.initedafterRevealFacebox++;
            log(variables.initedafterRevealFacebox);
                log("WARN: Lightbox loaded, attaching listerners now...");
                var _that = $('#facebox div.content:eq(0)');    //lightbox $document object
                variables.get.documentFB = _that ? _that : null;
                //Set the current evalGroupID
                var grpId = variables.get.documentFB.find("input[name=evalGroupId]").val();
                variables.evalGroupId = grpId == null ? '' : grpId.replace('/site/', '');
                //deselect boxes already deselected
                var field, regText = variables.evalGroupId + ".deselected" + (variables.options.type == 0 ? "Instructors" : "Assistants"),
                sRegExInput = new RegExp(regText);
                $('input[name=el-binding]').each(function() {
                    if ($(this).val().search(sRegExInput) != -1) {
                        field = $(this);
                    }
                });
                var deselected = field.val().replace("j#{selectedEvaluationUsersLocator." + regText + "}[", "").replace(/"/g,"").replace(/ /g,"").replace("]", "").split(",");
                if (deselected.length > 0) {
                    variables.get.documentFB.find('input[@type=checkbox]:checked').each(function() {
                        for (var i = 0; i < deselected.length; i++) {
                            if ( deselected[i] == $(this).attr('id')) {
                                this.checked = false;
                            }
                        }
                    });
                    handleCheckboxes(variables.get.documentFB.find('.selectTable tbody input[@type=checkbox]').not(':checked'), 1);
                }

                //check proper radiobox depending on selcetion option already saved in the DOM
                regText = variables.evalGroupId + (variables.options.type === 0 ? ".instructor" : ".assistant"),
                sRegExInput = new RegExp(regText);
                $('input[name=el-binding]').each(function() {
                    if ($(this).val().search(sRegExInput) != -1) {
                        field = $(this);
                    }
                });
                var selectionSaved = field.val().replace("j#{assignGroupSelectionSettings." + regText + "}", "");
                log("selectionSaved value: " + selectionSaved);
                if (selectionSaved.toString().length > 0) {
                    variables.get.documentFB.find('input[@type=radio]').each(function() {
                        if ( selectionSaved === $(this).val()) {
                            this.checked = true;
                        }

                    });
                }

                /**
                 *  Excecute this as soon as lightbox DON is loaded
                 */

                //set initial state of select all box
                if(variables.get.documentFB.find('.selectTable tbody input[@type=checkbox]').not(':checked').length === 0){
                   $('#selectorControl').each(function(){
                      this.checked = true;
                    });
                }
                $.facebox.setHeader($("#title"));
                //Activate Mass (De)Selector controls
                $("#selectorControl").bind('click', function(){
                    if (this.checked) {
                        $('.selectTable tbody input[@type=checkbox]').not(':checked').each(function(){
                            this.checked = true;
                        });
                    }else{
                        $('.selectTable tbody input[@type=checkbox]:checked').each(function(){
                          this.checked = false;
                        });
                    }
                });
                //bind individual checkbox to toggle main selector
                $(".selectTable tbody input[@type=checkbox]").bind('click', function(){
                    if (this.checked) {
                        if($('.selectTable tbody input[@type=checkbox]').not(':checked').length === 0){
                           $('#selectorControl').each(function(){
                              this.checked = true;
                            });
                        }
                    }else{
                        $('#selectorControl').each(function(){
                          this.checked = false;
                        });
                    }
                });

                $('#facebox input[id=save-item-action]').bind('click', function() {
                    log("Binding submit button value");
                    handleFormSubmit(this);

                    return false;
                });
                //Make list scrollable if hieght is more than 200px
                var tableHolder = variables.get.documentFB.find('.selectTable:eq(0)');
                tableHolder
                        .css({
                    'overflow': 'auto',
                    'height': tableHolder.height() > 200 ? '205px' : (tableHolder.height() + 10) + "px"
                }) ;
                log("Formatting table holder hieght. Set height to:" + tableHolder.height());
        });
        $(document).bind('afterClose.facebox', function() {
            log("Running afterClose.facebox; initialising variables.initedafterRevealFacebox.");
            variables.initedafterRevealFacebox = 0;
        });
        return that.each(function() {
            initControls($(this));
            initClassVars();
        });
    }

    function initClassVars() {
        variables.selectedPeople = 0;
        variables.deselectedPeopleIds = new Array();
        variables.thatRowNumber = 0;
    }

    function initControls(that) {
        that.hide();
        variables.groupCheckBox = that.parents('tr').find('input[@type=checkbox]');
        that.bind('click', function() {
                    var _url = that.attr('href');
                    variables.that = that;
                    variables.thatRowNumber = that.parents('tr').attr('rel');
                    variables.set.typeOfBranch(that);
                    log("Fetching URL: " + _url);
                    $.facebox({ajax: _url});
                    return false;
                });
        variables.groupCheckBox.bind('click', function() {
            if (this.checked) {
                that.fadeIn('fast');
            } else {
                that.fadeOut('fast');

            }
        });
        that.parents('tr.selectedGroup').find('input[@type=checkbox]').each(function(){
            //$(this).trigger("click");
            this.checked = true;
            that.fadeIn('fast');

        });

    }

    function handleCheckboxes(unChecked, where) {
        if (unChecked.length != 0) {
            if(where==2){//deselct everyone
                variables.deselectedPeopleIds = new Array();
            }else{
            unChecked.each(function() {
                var id = $(this).attr('id');
                variables.deselectedPeopleIds.push(id);
            });
            }
            var field;
            var regText = variables.evalGroupId + ".deselected" + (variables.options.type == 0 ? "Instructors" : "Assistants");
            var sRegExInput = new RegExp(regText);
            $('input[name=el-binding]').each(function() {
                if ($(this).val().search(sRegExInput) != -1) {
                    field = $(this);
                }
            });
            if (field != null) {
                field.val("j#{selectedEvaluationUsersLocator." + regText + "}[" + variables.deselectedPeopleIds.toString() + "]");
                log('Found - ' + unChecked.length + ' - deselected people and setting form value now. New val is:' + field.val());
                variables.deselectedPeopleIds = new Array();
                return true;
            } else {
                log("ERROR: Field param with part val:" + regText + " Not FOUND.");
            }

        }
        else {
            if (where == 1) {
                return false;
            }
            $(document).trigger('close.facebox');
        }
        return false;
    }

    function handleRadioButton(selection){
         if (variables.evalGroupId !== null){
            var field, regText = variables.evalGroupId + (variables.options.type === 0 ? ".instructor" : ".assistant"),
            sRegExInput = new RegExp(regText);
            $('input[name=el-binding]').each(function() {
                if ($(this).val().search(sRegExInput) != -1) {
                    field = $(this);
                }
            });
            if (field !== null) {
                field.val("j#{assignGroupSelectionSettings." + regText + "}" + selection );
                log('Selection setting is: ' + selection);
                return true;
            } else {
                log("ERROR: Field param with part val:" + regText + " Not FOUND.");
            }
         }
    }

    function handleFormSubmit(_that) {
        log("Running pre-SET checks");
        var that = $(_that), temp = variables.get.documentFB.find('.selectTable tbody input[@type=checkbox]').not(':checked'),
        tempChecked = variables.get.documentFB.find('.selectTable tbody input[@type=checkbox]:checked'),
        selectionChosen = variables.get.documentFB.find('input[@type=radio]:checked');
        variables.selectedPeople = tempChecked.length > 0 ? tempChecked.length : 0;
        if(temp.length>0){
            if (handleCheckboxes(temp, 0)) {
                //reset dom count on selected Instr/Ass
                var origionalSelected = variables.that.attr('class').replace("addItem total:", "");  //gets a String
                var text = variables.that.attr('title') + " (" + variables.selectedPeople + "/" + origionalSelected + ")";
                variables.that.text(text);
                $(document).trigger('close.facebox');
            }
        }else{
              if (handleCheckboxes(tempChecked, 2)) {
                //reset dom count on selected Instr/Ass
                var origionalSelected2 = variables.that.attr('class').replace("addItem total:", "");  //gets a String
                var text2 = variables.that.attr('title') + " (" + variables.selectedPeople + "/" + origionalSelected2 + ")";
                variables.that.text(text2);
                $(document).trigger('close.facebox');
            }
        }
        //save selection setting to DOM
        if (selectionChosen.length > 0){
            handleRadioButton(selectionChosen.val());
            handleListOrdering(tempChecked);
        }
        initClassVars();
        return true;

    }

    var handleListOrdering = function(selected){
        log("Handling ordering");
        var regText = variables.evalGroupId + ".ordering" + (variables.options.type === 0 ? "Instructors" : "Assistants"),
        sRegExInput = new RegExp(regText),
        selectedOrderedUserIds = [];
            $('input[name=el-binding]').each(function() {
                if ($(this).val().search(sRegExInput) != -1) {
                    field = $(this);
                }
            });
            if (field !== null) {
                // extract userIds from selected objects list
                for(var i=0; i < selected.length; i++){
                    selectedOrderedUserIds.push( $(selected[i]).attr("id") );
                }
                field.val("j#{selectedEvaluationUsersLocator." + regText + "}[" + selectedOrderedUserIds.toString() + "]");
                log('Found - ' + selected.length + ' - selected people and setting ordering form value now. New val is:' + field.val());
                return true;
            } else {
                log("ERROR: Field param with part val:" + regText + " Not FOUND.");
            }
    };

    // Debugging
    log = (($.fn.assignSelector.defaults.debug) && window.console) ? console.info : function(){return true;};

})($);
<commit_msg>EVALSYS-1036 Switch off debug in assign JS<commit_after>/**
 * For the evalAssign view
 */
$(document).ready(function() {
    //trigger FB overrides
    evalAssignFacebox.init();
    $('a[rel=assignInstructorSelector]').assignSelector({type:0});
    $('a[rel=assignTaSelector]').assignSelector({type:1});
    $(':submit').bind('click', function() {
        //Validate group Selections
        var countChecked = $('form[id=eval-assign-form] input[@type=checkbox]:checked').get().length;
        if (countChecked == null || countChecked == 0) {
            $('#error').fadeIn(0);
            return false;
        } else {
            $('#error').fadeOut(0);
        }
        return true;
    });
});

(function($) {
    $.fn.assignSelector = function(opts) {
        var options = $.extend({}, $.fn.assignSelector.defaults, opts);
        init($(this), options);
    };
    /**
     * Public variables. Once init() has ran, do not reference directly to these, use variables.options instead.
     */
    $.fn.assignSelector.defaults = {
        type: 1, //Type is for type of category we are handling. ie: 0 = instructor, 1 = ta
        debug: false
    };
    /**
     * Private methods and variables
     *
     */

    var variables = {
        option:null,
        get:{
            typeOfBranch:function() {
                switch (variables.options.type) {
                    case 0: return "instructor";break;
                    case 1: return "ta";break;
                }
            },
            siteId:false,
            documentFB:null
        },
        set:{
            typeOfBranch:function(that) {
                var temp;
                if (that.attr('rel').search(/instructor/i) != -1)
                    temp = 0;
                else if (that.attr('rel').search(/tas/i) != -1)
                    temp = 1;
                variables.options.type = temp;
                log("Active catergory type is: " + variables.get.typeOfBranch());
            },
            siteId:function(that) {
                variables.get.siteId = that.parents('tr:eq(0)').find('input:eq(0)').val();
                return !variables.get.siteId ? false : true;  //Do not simplify this. Should return true if siteId is anything other than false.
            }
        },
        selectedPeople:0,
        deselectedPeopleIds: new Array(),
        initedafterRevealFacebox:0,
        that:null,
        deselectedLog:new Array(),
        thatRowNumber:0 ,
        evalGroupId:null,
        groupCheckBox:null,
        css: {
            enabled:{
                color: ""
            },
            disabled:{
                color: "#888"
            }
        }
    };

    function init(that, options) {
        //copy options to this class
        variables.options = options;
        $(document).bind('afterReveal.facebox', function() {
            variables.initedafterRevealFacebox++;
            log(variables.initedafterRevealFacebox);
                log("WARN: Lightbox loaded, attaching listerners now...");
                var _that = $('#facebox div.content:eq(0)');    //lightbox $document object
                variables.get.documentFB = _that ? _that : null;
                //Set the current evalGroupID
                var grpId = variables.get.documentFB.find("input[name=evalGroupId]").val();
                variables.evalGroupId = grpId == null ? '' : grpId.replace('/site/', '');
                //deselect boxes already deselected
                var field, regText = variables.evalGroupId + ".deselected" + (variables.options.type == 0 ? "Instructors" : "Assistants"),
                sRegExInput = new RegExp(regText);
                $('input[name=el-binding]').each(function() {
                    if ($(this).val().search(sRegExInput) != -1) {
                        field = $(this);
                    }
                });
                var deselected = field.val().replace("j#{selectedEvaluationUsersLocator." + regText + "}[", "").replace(/"/g,"").replace(/ /g,"").replace("]", "").split(",");
                if (deselected.length > 0) {
                    variables.get.documentFB.find('input[@type=checkbox]:checked').each(function() {
                        for (var i = 0; i < deselected.length; i++) {
                            if ( deselected[i] == $(this).attr('id')) {
                                this.checked = false;
                            }
                        }
                    });
                    handleCheckboxes(variables.get.documentFB.find('.selectTable tbody input[@type=checkbox]').not(':checked'), 1);
                }

                //check proper radiobox depending on selcetion option already saved in the DOM
                regText = variables.evalGroupId + (variables.options.type === 0 ? ".instructor" : ".assistant"),
                sRegExInput = new RegExp(regText);
                $('input[name=el-binding]').each(function() {
                    if ($(this).val().search(sRegExInput) != -1) {
                        field = $(this);
                    }
                });
                var selectionSaved = field.val().replace("j#{assignGroupSelectionSettings." + regText + "}", "");
                log("selectionSaved value: " + selectionSaved);
                if (selectionSaved.toString().length > 0) {
                    variables.get.documentFB.find('input[@type=radio]').each(function() {
                        if ( selectionSaved === $(this).val()) {
                            this.checked = true;
                        }

                    });
                }

                /**
                 *  Excecute this as soon as lightbox DON is loaded
                 */

                //set initial state of select all box
                if(variables.get.documentFB.find('.selectTable tbody input[@type=checkbox]').not(':checked').length === 0){
                   $('#selectorControl').each(function(){
                      this.checked = true;
                    });
                }
                $.facebox.setHeader($("#title"));
                //Activate Mass (De)Selector controls
                $("#selectorControl").bind('click', function(){
                    if (this.checked) {
                        $('.selectTable tbody input[@type=checkbox]').not(':checked').each(function(){
                            this.checked = true;
                        });
                    }else{
                        $('.selectTable tbody input[@type=checkbox]:checked').each(function(){
                          this.checked = false;
                        });
                    }
                });
                //bind individual checkbox to toggle main selector
                $(".selectTable tbody input[@type=checkbox]").bind('click', function(){
                    if (this.checked) {
                        if($('.selectTable tbody input[@type=checkbox]').not(':checked').length === 0){
                           $('#selectorControl').each(function(){
                              this.checked = true;
                            });
                        }
                    }else{
                        $('#selectorControl').each(function(){
                          this.checked = false;
                        });
                    }
                });

                $('#facebox input[id=save-item-action]').bind('click', function() {
                    log("Binding submit button value");
                    handleFormSubmit(this);

                    return false;
                });
                //Make list scrollable if hieght is more than 200px
                var tableHolder = variables.get.documentFB.find('.selectTable:eq(0)');
                tableHolder
                        .css({
                    'overflow': 'auto',
                    'height': tableHolder.height() > 200 ? '205px' : (tableHolder.height() + 10) + "px"
                }) ;
                log("Formatting table holder hieght. Set height to:" + tableHolder.height());
        });
        $(document).bind('afterClose.facebox', function() {
            log("Running afterClose.facebox; initialising variables.initedafterRevealFacebox.");
            variables.initedafterRevealFacebox = 0;
        });
        return that.each(function() {
            initControls($(this));
            initClassVars();
        });
    }

    function initClassVars() {
        variables.selectedPeople = 0;
        variables.deselectedPeopleIds = new Array();
        variables.thatRowNumber = 0;
    }

    function initControls(that) {
        that.hide();
        variables.groupCheckBox = that.parents('tr').find('input[@type=checkbox]');
        that.bind('click', function() {
                    var _url = that.attr('href');
                    variables.that = that;
                    variables.thatRowNumber = that.parents('tr').attr('rel');
                    variables.set.typeOfBranch(that);
                    log("Fetching URL: " + _url);
                    $.facebox({ajax: _url});
                    return false;
                });
        variables.groupCheckBox.bind('click', function() {
            if (this.checked) {
                that.fadeIn('fast');
            } else {
                that.fadeOut('fast');

            }
        });
        that.parents('tr.selectedGroup').find('input[@type=checkbox]').each(function(){
            //$(this).trigger("click");
            this.checked = true;
            that.fadeIn('fast');

        });

    }

    function handleCheckboxes(unChecked, where) {
        if (unChecked.length != 0) {
            if(where==2){//deselct everyone
                variables.deselectedPeopleIds = new Array();
            }else{
            unChecked.each(function() {
                var id = $(this).attr('id');
                variables.deselectedPeopleIds.push(id);
            });
            }
            var field;
            var regText = variables.evalGroupId + ".deselected" + (variables.options.type == 0 ? "Instructors" : "Assistants");
            var sRegExInput = new RegExp(regText);
            $('input[name=el-binding]').each(function() {
                if ($(this).val().search(sRegExInput) != -1) {
                    field = $(this);
                }
            });
            if (field != null) {
                field.val("j#{selectedEvaluationUsersLocator." + regText + "}[" + variables.deselectedPeopleIds.toString() + "]");
                log('Found - ' + unChecked.length + ' - deselected people and setting form value now. New val is:' + field.val());
                variables.deselectedPeopleIds = new Array();
                return true;
            } else {
                log("ERROR: Field param with part val:" + regText + " Not FOUND.");
            }

        }
        else {
            if (where == 1) {
                return false;
            }
            $(document).trigger('close.facebox');
        }
        return false;
    }

    function handleRadioButton(selection){
         if (variables.evalGroupId !== null){
            var field, regText = variables.evalGroupId + (variables.options.type === 0 ? ".instructor" : ".assistant"),
            sRegExInput = new RegExp(regText);
            $('input[name=el-binding]').each(function() {
                if ($(this).val().search(sRegExInput) != -1) {
                    field = $(this);
                }
            });
            if (field !== null) {
                field.val("j#{assignGroupSelectionSettings." + regText + "}" + selection );
                log('Selection setting is: ' + selection);
                return true;
            } else {
                log("ERROR: Field param with part val:" + regText + " Not FOUND.");
            }
         }
    }

    function handleFormSubmit(_that) {
        log("Running pre-SET checks");
        var that = $(_that), temp = variables.get.documentFB.find('.selectTable tbody input[@type=checkbox]').not(':checked'),
        tempChecked = variables.get.documentFB.find('.selectTable tbody input[@type=checkbox]:checked'),
        selectionChosen = variables.get.documentFB.find('input[@type=radio]:checked');
        variables.selectedPeople = tempChecked.length > 0 ? tempChecked.length : 0;
        if(temp.length>0){
            if (handleCheckboxes(temp, 0)) {
                //reset dom count on selected Instr/Ass
                var origionalSelected = variables.that.attr('class').replace("addItem total:", "");  //gets a String
                var text = variables.that.attr('title') + " (" + variables.selectedPeople + "/" + origionalSelected + ")";
                variables.that.text(text);
                $(document).trigger('close.facebox');
            }
        }else{
              if (handleCheckboxes(tempChecked, 2)) {
                //reset dom count on selected Instr/Ass
                var origionalSelected2 = variables.that.attr('class').replace("addItem total:", "");  //gets a String
                var text2 = variables.that.attr('title') + " (" + variables.selectedPeople + "/" + origionalSelected2 + ")";
                variables.that.text(text2);
                $(document).trigger('close.facebox');
            }
        }
        //save selection setting to DOM
        if (selectionChosen.length > 0){
            handleRadioButton(selectionChosen.val());
            handleListOrdering(tempChecked);
        }
        initClassVars();
        return true;

    }

    var handleListOrdering = function(selected){
        log("Handling ordering");
        var regText = variables.evalGroupId + ".ordering" + (variables.options.type === 0 ? "Instructors" : "Assistants"),
        sRegExInput = new RegExp(regText),
        selectedOrderedUserIds = [];
            $('input[name=el-binding]').each(function() {
                if ($(this).val().search(sRegExInput) != -1) {
                    field = $(this);
                }
            });
            if (field !== null) {
                // extract userIds from selected objects list
                for(var i=0; i < selected.length; i++){
                    selectedOrderedUserIds.push( $(selected[i]).attr("id") );
                }
                field.val("j#{selectedEvaluationUsersLocator." + regText + "}[" + selectedOrderedUserIds.toString() + "]");
                log('Found - ' + selected.length + ' - selected people and setting ordering form value now. New val is:' + field.val());
                return true;
            } else {
                log("ERROR: Field param with part val:" + regText + " Not FOUND.");
            }
    };

    // Debugging
    log = (($.fn.assignSelector.defaults.debug) && window.console) ? console.info : function(){return true;};

})($);
<|endoftext|>


<commit_before>'use strict';

/*
 * Controllers for development topics management.
 * Pay attention to injection of dependencies (factories, entities and Angular objects).
 */
angular.module('appverseClientIncubatorApp')
  .controller('TopicsController',
      function ($scope,   $state,   topics,   utils) {
                // Add a 'topics' field in this abstract parent's scope, so that all
                // child state views can access it in their scopes. Please note: scope
                // inheritance is not due to nesting of states, but rather choosing to
                // nest the templates of those states. It's normal scope inheritance.
                $scope.topics = topics;

                $scope.goToRandom = function () {
                  var randId = utils.newRandomKey($scope.topics, "id", $state.params.topicId);
                  // $state.go() can be used as a high level convenience method
                  // for activating a state programmatically.
                  $state.go('topics.detail', { topicId: randId });
                };
  })
 .controller('TopicDetailsController',
      function (  $scope,   $stateParams,   utils) {
                    $scope.topic = utils.findById($scope.topics, $stateParams.topicId);
                })
 .controller('TopicDetailsItemController',
      function (  $scope,   $stateParams,   $state,   utils) {
                    $scope.item = utils.findById($scope.topic.items, $stateParams.itemId);

                    $scope.edit = function () {
                      // Here we show off go's ability to navigate to a relative state. Using '^' to go upwards
                      // and '.' to go down, you can navigate to any relative state (ancestor or descendant).
                      // Here we are going down to the child state 'edit' (full name of 'topics.detail.item.edit')
                      $state.go('.edit', $stateParams);
                    };
                  })
.controller('TopicDetailsItemEditController',
     function (  $scope,   $stateParams,   $state,   utils) {
                    $scope.item = utils.findById($scope.topic.items, $stateParams.itemId);
                    $scope.done = function () {
                      // Go back up. '^' means up one. '^.^' would be up twice, to the grandparent.
                      $state.go('^', $stateParams);
                    };
                  })

.controller('translationController', ['$scope', '$translate', 'tmhDynamicLocale',
     function ( $scope, $translate, tmhDynamicLocale ) {

                    $scope.now = new Date();
                    $scope.name = 'Alicia';
                    $scope.age = '25';

                    $scope.setLocale = function(locale) {
                        $translate.uses(locale);
                        tmhDynamicLocale.set(locale.toLowerCase());
                    };
                  }]);
<commit_msg>- Added cacheController - Formatted to comply with JSHint<commit_after>'use strict';

/*
 * Controllers for development topics management.
 * Pay attention to injection of dependencies (factories, entities and Angular objects).
 */
angular.module('appverseClientIncubatorApp')
    .controller('TopicsController',
        function ($scope, $state, topics, utils) {
            // Add a 'topics' field in this abstract parent's scope, so that all
            // child state views can access it in their scopes. Please note: scope
            // inheritance is not due to nesting of states, but rather choosing to
            // nest the templates of those states. It's normal scope inheritance.
            $scope.topics = topics;

            $scope.goToRandom = function () {
                var randId = utils.newRandomKey($scope.topics, 'id', $state.params.topicId);
                // $state.go() can be used as a high level convenience method
                // for activating a state programmatically.
                $state.go('topics.detail', {
                    topicId: randId
                });
            };
        })
    .controller('TopicDetailsController',
        function ($scope, $stateParams, utils) {
            $scope.topic = utils.findById($scope.topics, $stateParams.topicId);
        })
    .controller('TopicDetailsItemController',
        function ($scope, $stateParams, $state, utils) {
            $scope.item = utils.findById($scope.topic.items, $stateParams.itemId);

            $scope.edit = function () {
                // Here we show off go's ability to navigate to a relative state. Using '^' to go upwards
                // and '.' to go down, you can navigate to any relative state (ancestor or descendant).
                // Here we are going down to the child state 'edit' (full name of 'topics.detail.item.edit')
                $state.go('.edit', $stateParams);
            };
        })
    .controller('TopicDetailsItemEditController',
        function ($scope, $stateParams, $state, utils) {
            $scope.item = utils.findById($scope.topic.items, $stateParams.itemId);
            $scope.done = function () {
                // Go back up. '^' means up one. '^.^' would be up twice, to the grandparent.
                $state.go('^', $stateParams);
            };
        })
    .controller('cacheController',
        function () {
            console.log('cacheController loading');
        })
    .controller('translationController', ['$scope', '$translate', 'tmhDynamicLocale',
        function ($scope, $translate, tmhDynamicLocale) {

            $scope.now = new Date();
            $scope.name = 'Alicia';
            $scope.age = '25';

            $scope.setLocale = function (locale) {
                $translate.uses(locale);
                tmhDynamicLocale.set(locale.toLowerCase());
            };
        }]);
<|endoftext|>


<commit_before>app.controller('MainController', function($rootScope, $scope, itemTypesService, flashService, FlashMessage) {

	$rootScope.$on("$routeChangeStart", function() {
		$rootScope.loading = true;
	});

	$rootScope.$on("$routeChangeSuccess", function() {
		$rootScope.loading = false;
	});

	$scope.logout = function() {
		window.location.href = '?logout';
	};

	$scope.loadFlashes = function() {
		flashService.get().then(function(FlashMessages){
			$scope.flashes = FlashMessages.getFlashMessages();
		});
	};

	$scope.loadItemTypes = function() {
		itemTypesService.get().then(function(ItemTypes){
			$scope.itemTypes = ItemTypes.getItemTypes();
		});
	};

	$scope.addFlashMessage = function(message, type){
		var flashes = [];
		flashes.push(FlashMessage.build({message:message, type:type}));
		$scope.flashes = flashes;
	};

	var scrollItems = [];

	for (var i = 1; i <= 100; i++) {
		scrollItems.push("Item " + i);
	}

	$scope.scrollItems = scrollItems;

	$scope.loadItemTypes();
	$scope.loadFlashes();
});<commit_msg>- clear flashes after timeout<commit_after>app.controller('MainController', function($rootScope, $scope, $timeout, itemTypesService, flashService, FlashMessage) {

	$rootScope.$on("$routeChangeStart", function() {
		$rootScope.loading = true;
	});

	$rootScope.$on("$routeChangeSuccess", function() {
		$rootScope.loading = false;
	});

	$scope.logout = function() {
		window.location.href = '?logout';
	};

	$scope.loadFlashes = function() {
		flashService.get()
			.then(function(FlashMessages){
				$scope.flashes = FlashMessages.getFlashMessages();
			})
			.then(function(){
				$timeout(function(){
					$scope.flashes = {};
				}, 3000);
			});
	};

	$scope.loadItemTypes = function() {
		itemTypesService.get().then(function(ItemTypes){
			$scope.itemTypes = ItemTypes.getItemTypes();
		});
	};

	$scope.addFlashMessage = function(message, type){
		var flashes = [];
		flashes.push(FlashMessage.build({message:message, type:type}));
		$scope.flashes = flashes;
	};

	var scrollItems = [];

	for (var i = 1; i <= 100; i++) {
		scrollItems.push("Item " + i);
	}

	$scope.scrollItems = scrollItems;

	$scope.loadItemTypes();
	$scope.loadFlashes();
});<|endoftext|>


<commit_before>/**
 * ==========================
 * Base Libs Warmup & Hacks
 * ==========================
 * lib activation:
 * 1. +Swag (Handlebars Helpers)
 * 2. +Handlebars to Backbone.Marionette
 *
 * component opt-ins: (use in component initialize func)
 * 3. +Action Tag listener mechanisms.
 * 4. +UI Locking support to view regions (without Application scope total lockdown atm...)
 * 5. +Pagination ability to Backbone.Collection
 *
 * @author Tim.Liu
 * @create 2013.09.11
 */
;(function(window, Swag, Backbone, Handlebars){

	//1 Hook up additional Handlebars helpers.
	Swag.registerHelpers();

	//2 Override to use Handlebars templating engine with Backbone.Marionette
	Backbone.Marionette.TemplateCache.prototype.compileTemplate = function(rawTemplate) {
	  return Handlebars.compile(rawTemplate);
	};

/**
 * 3 Action Tag listener hookups +actions{}
 * Usage:
 * 		1. add action tags to html template -> e.g

 * 		2. implement the action method name in UI definition body's actions{} object.
 * 		functions under actions{} are bind to 'this' scope (the view object).
 * 		functions under actions{} are called with a single param ($action) which is a jQuery object referencing the action tag.
 */
 	_.extend(Backbone.Marionette.View.prototype, {

 		enableActionTags: function(uiName){ //the uiName is just there to output meaningful dev msg if some actions haven't been implemented.
 			this.events = this.events || {};
 			//add general action tag clicking event and listener
 			_.extend(this.events, {
 				'click [action]': '_doAction'
 			});
 			this._doAction = function(e){
				e.stopPropagation(); //Important::This is to prevent confusing the parent view's action tag listeners.
				var $el = $(e.currentTarget);
				var action = $el.attr('action') || 'UNKNOWN';
				var doer = this._actions[action];
				if(doer) {
					doer($el);
				}else throw new Error('DEV::' + (uiName || 'UI Component') + '::You have not yet implemented this action - [' + action + ']');
			};
			this.actions = this.actions || {};
			//bind all action listeners funcs to this producing _actions
			//Warning:: By creating a new object to hold all the binded listeners is to avoid the 'Can NOT rebind' problem with _.bind()
			//This is extremely important, since all 'this.func' in an initialize function refer to the prototype.func, if this.actions gets assigned
			//to be the binded version, other view instances of the same prototype can NOT bind the actions to themselves.
			_.each(['actions'], function(funcGroup){
				this['_' + funcGroup] = {};
				_.each(this[funcGroup], function(func, name){
					this['_' + funcGroup][name] = _.bind(func, this);
				}, this);
			}, this);
 		}

 	});

/**
 * 4 UI Locks support
 * Add a _uilocks map for each of the UI view on screen, for managing UI action locks for its regions
 * Also it will add in a _all region for locking the whole UI
 * Usage:
 * 		1. lockUI/unlockUI([region], [caller])
 * 		2. isUILocked([region])
 */
	_.extend(Backbone.Marionette.View.prototype, {
		//only for layouts
		enableUILocks: function(){
			if(this.regions){
				this._uilocks = _.reduce(this.regions, function(memo, val, key, list){
					memo[key] = false;
					return memo;
				}, {_all: false});
			}
		},

		//region, caller are optional
		lockUI: function(region, caller){
			region = this._checkRegion(region);

			caller = caller || '_default_';
			if(!this._uilocks[region]){ //not locked, lock it with caller signature!
				this._uilocks[region] = caller;
				return true;
			}
			if(this._uilocks[region] === caller) //locked by caller already, bypass.
				return true;
			//else throw error...since it is already locked, by something else tho...
			throw new Error('DEV::View UI Locks::This region ' + region + ' is already locked by ' + this._uilocks[region]);
		},

		//region, caller are optional
		unlockUI: function(region, caller){
			region = this._checkRegion(region);

			caller = caller || '_default_';
			if(!this._uilocks[region]) return true; //not locked, bypass.
			if(this._uilocks[region] === caller){ //locked by caller, release it.
				this._uilocks[region] = false;
				return true;
			}
			//else throw error...
			throw new Error('DEV::View UI Locks::This region ' + region + ' is locked by ' + this._uilocks[region] + ', you can NOT unlock it with ' + caller);
		},

		isUILocked: function(region){
			region = this._checkRegion(region);

			return this._uilocks[region];
		},

		//=====Internal Workers=====
		_checkRegion: function(region){
			if(!region)
				region = '_all';
			else
				if(!this.regions[region])
					throw new Error('DEV::View UI Locks::This region does NOT exist - ' + region);
			return region;
		}
		//=====Internal Workers=====

	});

/*
	5 Pagination - extend the Backbone.Collection to let it have this ability
		(Warning: To make the code simpler, we put a special parse() in data-units.js for collections to save
					the fetched result without feeding all of them to the model factory. (only in mode:client)
					This way, we don't have to make another 'window' collection for updating the UI.
		)
		+Config: {
			mode: client/server - non 'server' value means 'client' mode.
			cache: false(default)/true (completely swap the content of this collection or incrementally feed it)
			pageSize: (default: 25) - 0 means showing all
			params: { optionally control the server params used. //Hard coded atm...
				offset: 'page',
				size: 'per_page'
			}
		}
		+Properties: { should be Read-Only, can only be changed from calling the functions below.
			currentPage:
			totalRecords: in cached server mode, this can be null
		}
		+Func: {
			load: instead of calling fetch directly, we use load(options) to do some preprocess.
				+options: apart from the normal options to be passed to fetch() we add
						page: number or nothing -> load specific page or page 1

			nextPage: load currentPage + 1;
			prevPage: only works if 'cache' is set to false;
		}
		+Events
			1. pagination:updatePageNumbers - fired upon 'sync' after 'reset';
			2. pagination:updatePageNumbers:clientMode - fired upon 'sync' after 'add' and 'destroy' after 'remove', only in non-cached client mode.
			3. pagination:pageChanged - fired upon each time the collection change to hold another page of data.
		Note that: at any given time, you can still use fetch(), using load() will always enforce a paginated fetch()
*/
	_.extend(Backbone.Collection.prototype, {

		//To opt-in the pagination with any Backbone.Collection
		//Invoke this function in your collection definition's initialize()
		//Warning:: your parse() method must be overridden to provide support to the load() method below, see collection's parse() method override in - special/registry/data-units.js
		//You don't have to do anything if your collection is created by the DataUnits special registry module.
		enablePagination: function(config){
			this.pagination = _.extend({
				mode: 'client',
				cache: false, //this means the collection is not used to cache previously loaded records. However, we do save the fetched result in client mode. see - data-units.js
				pageSize: 10,
			}, this.pagination, config);

			//we need to +/- related records from _cachedResponse array as well.
			function signalClientModePageNumberUpdate(collection){
				collection.totalRecords = collection._cachedResponse.length;
				collection.trigger('pagination:updatePageNumbers:clientMode');
			}
			var eWhiteList = {
				'sync': true,
				'destroy': true
			};
			this.on('all', function(event, target){
				if(!eWhiteList[event]) return;
				if(this.pagination.cache) return;
				if(this === target){
					//Note that this === target means the 'sync' detected is after 'reset'. This is true for both client and server mode.
					this.trigger('pagination:updatePageNumbers');
					//1. we are only interested in sync after add and destroy after remove.
					return;
				}
				if(this.pagination.mode !== 'client') return;
				//2. we only need to do this for non-cached client mode, since in other modes, the page numbers are either not needed or updated by server's replay about total records.
				switch(event){
					case 'sync':
						this._cachedResponse.push(target.attributes);
						signalClientModePageNumberUpdate(this);
						break;
					case 'destroy':
						console.log('-', target.id);
						for (var i = this._cachedResponse.length - 1; i >= 0; i--) {
							if(this._cachedResponse[i][target.idAttribute] === target.id){
								this._cachedResponse.splice(i, 1);
								break;
							}
						};
						signalClientModePageNumberUpdate(this);
						break;
					default:
						break;
				}

			});
		},

		//A version of fetch() with pagination config applied. Always use load if possible.
		load: function(page, options){
			if(_.isObject(page)){
				options = page || {};
			}
			options = options || {};

			if(this.pagination){
				page = (_.isNumber(page) && page) || 1;
				//Note that we don't skip fetch when (this.currentPage === page), coz the page would be the same during a 'UI module' swap/navigate, like in the Admin context.

				this.currentPage = page;
				if(this.pagination.mode === 'client'){
					if(!this._cachedResponse || options.reset){
						//go fetch the records again.
						this.fetch(options);
					}else {
						//go to page
						this.set(this._cachedResponse.slice((this.currentPage-1) * this.pagination.pageSize, this.currentPage * this.pagination.pageSize), {remove: !this.pagination.cache});
						this.trigger('pagination:pageChanged');
					}
				}else {
					//server mode
					options.data = _.extend(options.data || {}, {
						page: this.currentPage,
						per_page: this.pagination.pageSize,
					});
					var that = this;
					_.extend(options, {
						remove: !this.pagination.cache,
						success: function(){
							that.trigger('pagination:pageChanged');
						}
					});
					this.fetch(options);
				}
			}else {
				this.fetch(options); //ignore pagination. normal fetch();
			}
		}
	});

})(window, Swag, Backbone, Handlebars);<commit_msg>Refined action listener invoke mechanism.<commit_after>/**
 * ==========================
 * Base Libs Warmup & Hacks
 * ==========================
 * lib activation:
 * 1. +Swag (Handlebars Helpers)
 * 2. +Handlebars to Backbone.Marionette
 *
 * component opt-ins: (use in component initialize func)
 * 3. +Action Tag listener mechanisms.
 * 4. +UI Locking support to view regions (without Application scope total lockdown atm...)
 * 5. +Pagination ability to Backbone.Collection
 *
 * @author Tim.Liu
 * @create 2013.09.11
 */
;(function(window, Swag, Backbone, Handlebars){

	//1 Hook up additional Handlebars helpers.
	Swag.registerHelpers();

	//2 Override to use Handlebars templating engine with Backbone.Marionette
	Backbone.Marionette.TemplateCache.prototype.compileTemplate = function(rawTemplate) {
	  return Handlebars.compile(rawTemplate);
	};

/**
 * 3 Action Tag listener hookups +actions{}
 * Usage:
 * 		1. add action tags to html template -> e.g

 * 		2. implement the action method name in UI definition body's actions{} object.
 * 		functions under actions{} are invoked with 'this' as scope (the view object).
 * 		functions under actions{} are called with a single param ($action) which is a jQuery object referencing the action tag.
 *
 * Note:
 * We removed _.bind() altogether from the enableActionTags() function and use Function.apply(scope, args) instead for listener invocation to avoid actions{} methods binding problem.
 * Functions under actions will only be bound ONCE to the first instance of the view definition, since _.bind() can not rebind functions that were already bound, other instances of
 * the view prototype will have all the action listeners bound to the wrong view object. This holds true to all nested functions, if you assign the bound version of the function back to itself
 * e.g. this.nest.func = _.bind(this.nest.func, this); - Do NOT do this in initialize()/constructor()!! Use Function.apply() for invocation instead!!!
 */
 	_.extend(Backbone.Marionette.View.prototype, {

 		enableActionTags: function(uiName){ //the uiName is just there to output meaningful dev msg if some actions haven't been implemented.
 			this.events = this.events || {};
 			//add general action tag clicking event and listener
 			_.extend(this.events, {
 				'click [action]': '_doAction'
 			});
 		},

		_doAction: function(e){
			e.stopPropagation(); //Important::This is to prevent confusing the parent view's action tag listeners.
			var $el = $(e.currentTarget);
			var action = $el.attr('action') || 'UNKNOWN';
			var doer = this.actions[action];
			if(doer) {
				doer.apply(this, [$el]); //use 'this' view object as scope when applying the action listeners.
			}else throw new Error('DEV::' + (uiName || 'UI Component') + '::You have not yet implemented this action - [' + action + ']');
		},
 	});

/**
 * 4 UI Locks support
 * Add a _uilocks map for each of the UI view on screen, for managing UI action locks for its regions
 * Also it will add in a _all region for locking the whole UI
 * Usage:
 * 		1. lockUI/unlockUI([region], [caller])
 * 		2. isUILocked([region])
 */
	_.extend(Backbone.Marionette.View.prototype, {
		//only for layouts
		enableUILocks: function(){
			if(this.regions){
				this._uilocks = _.reduce(this.regions, function(memo, val, key, list){
					memo[key] = false;
					return memo;
				}, {_all: false});
			}
		},

		//region, caller are optional
		lockUI: function(region, caller){
			region = this._checkRegion(region);

			caller = caller || '_default_';
			if(!this._uilocks[region]){ //not locked, lock it with caller signature!
				this._uilocks[region] = caller;
				return true;
			}
			if(this._uilocks[region] === caller) //locked by caller already, bypass.
				return true;
			//else throw error...since it is already locked, by something else tho...
			throw new Error('DEV::View UI Locks::This region ' + region + ' is already locked by ' + this._uilocks[region]);
		},

		//region, caller are optional
		unlockUI: function(region, caller){
			region = this._checkRegion(region);

			caller = caller || '_default_';
			if(!this._uilocks[region]) return true; //not locked, bypass.
			if(this._uilocks[region] === caller){ //locked by caller, release it.
				this._uilocks[region] = false;
				return true;
			}
			//else throw error...
			throw new Error('DEV::View UI Locks::This region ' + region + ' is locked by ' + this._uilocks[region] + ', you can NOT unlock it with ' + caller);
		},

		isUILocked: function(region){
			region = this._checkRegion(region);

			return this._uilocks[region];
		},

		//=====Internal Workers=====
		_checkRegion: function(region){
			if(!region)
				region = '_all';
			else
				if(!this.regions[region])
					throw new Error('DEV::View UI Locks::This region does NOT exist - ' + region);
			return region;
		}
		//=====Internal Workers=====

	});

/*
	5 Pagination - extend the Backbone.Collection to let it have this ability
		(Warning: To make the code simpler, we put a special parse() in data-units.js for collections to save
					the fetched result without feeding all of them to the model factory. (only in mode:client)
					This way, we don't have to make another 'window' collection for updating the UI.
		)
		+Config: {
			mode: client/server - non 'server' value means 'client' mode.
			cache: false(default)/true (completely swap the content of this collection or incrementally feed it)
			pageSize: (default: 25) - 0 means showing all
			params: { optionally control the server params used. //Hard coded atm...
				offset: 'page',
				size: 'per_page'
			}
		}
		+Properties: { should be Read-Only, can only be changed from calling the functions below.
			currentPage:
			totalRecords: in cached server mode, this can be null
		}
		+Func: {
			load: instead of calling fetch directly, we use load(options) to do some preprocess.
				+options: apart from the normal options to be passed to fetch() we add
						page: number or nothing -> load specific page or page 1

			nextPage: load currentPage + 1;
			prevPage: only works if 'cache' is set to false;
		}
		+Events
			1. pagination:updatePageNumbers - fired upon 'sync' after 'reset';
			2. pagination:updatePageNumbers:clientMode - fired upon 'sync' after 'add' and 'destroy' after 'remove', only in non-cached client mode.
			3. pagination:pageChanged - fired upon each time the collection change to hold another page of data.
		Note that: at any given time, you can still use fetch(), using load() will always enforce a paginated fetch()
*/
	_.extend(Backbone.Collection.prototype, {

		//To opt-in the pagination with any Backbone.Collection
		//Invoke this function in your collection definition's initialize()
		//Warning:: your parse() method must be overridden to provide support to the load() method below, see collection's parse() method override in - special/registry/data-units.js
		//You don't have to do anything if your collection is created by the DataUnits special registry module.
		enablePagination: function(config){
			this.pagination = _.extend({
				mode: 'client',
				cache: false, //this means the collection is not used to cache previously loaded records. However, we do save the fetched result in client mode. see - data-units.js
				pageSize: 10,
			}, this.pagination, config);

			//we need to +/- related records from _cachedResponse array as well.
			function signalClientModePageNumberUpdate(collection){
				collection.totalRecords = collection._cachedResponse.length;
				collection.trigger('pagination:updatePageNumbers:clientMode');
			}
			var eWhiteList = {
				'sync': true,
				'destroy': true
			};
			this.on('all', function(event, target){
				if(!eWhiteList[event]) return;
				if(this.pagination.cache) return;
				if(this === target){
					//Note that this === target means the 'sync' detected is after 'reset'. This is true for both client and server mode.
					this.trigger('pagination:updatePageNumbers');
					//1. we are only interested in sync after add and destroy after remove.
					return;
				}
				if(this.pagination.mode !== 'client') return;
				//2. we only need to do this for non-cached client mode, since in other modes, the page numbers are either not needed or updated by server's replay about total records.
				switch(event){
					case 'sync':
						this._cachedResponse.push(target.attributes);
						signalClientModePageNumberUpdate(this);
						break;
					case 'destroy':
						console.log('-', target.id);
						for (var i = this._cachedResponse.length - 1; i >= 0; i--) {
							if(this._cachedResponse[i][target.idAttribute] === target.id){
								this._cachedResponse.splice(i, 1);
								break;
							}
						};
						signalClientModePageNumberUpdate(this);
						break;
					default:
						break;
				}

			});
		},

		//A version of fetch() with pagination config applied. Always use load if possible.
		load: function(page, options){
			if(_.isObject(page)){
				options = page || {};
			}
			options = options || {};

			if(this.pagination){
				page = (_.isNumber(page) && page) || 1;
				//Note that we don't skip fetch when (this.currentPage === page), coz the page would be the same during a 'UI module' swap/navigate, like in the Admin context.

				this.currentPage = page;
				if(this.pagination.mode === 'client'){
					if(!this._cachedResponse || options.reset){
						//go fetch the records again.
						this.fetch(options);
					}else {
						//go to page
						this.set(this._cachedResponse.slice((this.currentPage-1) * this.pagination.pageSize, this.currentPage * this.pagination.pageSize), {remove: !this.pagination.cache});
						this.trigger('pagination:pageChanged');
					}
				}else {
					//server mode
					options.data = _.extend(options.data || {}, {
						page: this.currentPage,
						per_page: this.pagination.pageSize,
					});
					var that = this;
					_.extend(options, {
						remove: !this.pagination.cache,
						success: function(){
							that.trigger('pagination:pageChanged');
						}
					});
					this.fetch(options);
				}
			}else {
				this.fetch(options); //ignore pagination. normal fetch();
			}
		}
	});

})(window, Swag, Backbone, Handlebars);<|endoftext|>


<commit_before>'use strict';

angular.module('confRegistrationWebApp')
  .service('validateRegistrant', function validateRegistrant() {

    this.validate = function(conference, registrant) {
      var invalidBlocks = [];
      conference = angular.copy(conference);

      //remove blocks not applicable to registrant type
      angular.forEach(conference.registrationPages, function(page) {
        var pageIndex = _.findIndex(conference.registrationPages, { 'id': page.id });
        angular.forEach(angular.copy(page.blocks), function (block) {
          if (_.contains(block.registrantTypes, registrant.registrantTypeId)) {
            _.remove(conference.registrationPages[pageIndex].blocks, function (b) {
              return b.id === block.id;
            });
          }
        });
      });

      angular.forEach(_.flatten(conference.registrationPages, 'blocks'), function(block){
        if (!block.required) { return; }

        var answer = _.find(registrant.answers, { 'blockId': block.id });
        if (angular.isUndefined(answer)) {
          invalidBlocks.push(block.id);
          return;
        }
        answer = answer.value;

        switch (block.type) {
          case 'nameQuestion':
            if(angular.isUndefined(answer.firstName) || angular.isUndefined(answer.lastName)){
              invalidBlocks.push(block.id);
              return;
            }

            if (_.isEmpty(answer.firstName) || _.isEmpty(answer.lastName)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'numberQuestion':
            if(angular.isUndefined(answer)){
              invalidBlocks.push(block.id);
              return;
            }

            if (!_.isNumber(answer)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'phoneQuestion':
            if(angular.isUndefined(answer)){
              invalidBlocks.push(block.id);
              return;
            }
            if (_.isNull(answer.match(/^(\D*\d\D*){10,15}$/g))) { //Contains 10-15 digits
              invalidBlocks.push(block.id);
              return;
            }
            break;
          default:
            if(angular.isUndefined(answer)){
              invalidBlocks.push(block.id);
              return;
            }

            if (_.isEmpty(answer)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
        }
      });

      return invalidBlocks;
    };
  });
<commit_msg>Check if answer is null before matching<commit_after>'use strict';

angular.module('confRegistrationWebApp')
  .service('validateRegistrant', function validateRegistrant() {

    this.validate = function(conference, registrant) {
      var invalidBlocks = [];
      conference = angular.copy(conference);

      //remove blocks not applicable to registrant type
      angular.forEach(conference.registrationPages, function(page) {
        var pageIndex = _.findIndex(conference.registrationPages, { 'id': page.id });
        angular.forEach(angular.copy(page.blocks), function (block) {
          if (_.contains(block.registrantTypes, registrant.registrantTypeId)) {
            _.remove(conference.registrationPages[pageIndex].blocks, function (b) {
              return b.id === block.id;
            });
          }
        });
      });

      angular.forEach(_.flatten(conference.registrationPages, 'blocks'), function(block){
        if (!block.required) { return; }

        var answer = _.find(registrant.answers, { 'blockId': block.id });
        if (angular.isUndefined(answer)) {
          invalidBlocks.push(block.id);
          return;
        }
        answer = answer.value;

        switch (block.type) {
          case 'nameQuestion':
            if(angular.isUndefined(answer.firstName) || angular.isUndefined(answer.lastName)){
              invalidBlocks.push(block.id);
              return;
            }

            if (_.isEmpty(answer.firstName) || _.isEmpty(answer.lastName)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'numberQuestion':
            if(angular.isUndefined(answer)){
              invalidBlocks.push(block.id);
              return;
            }

            if (!_.isNumber(answer)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
          case 'phoneQuestion':
            if(angular.isUndefined(answer) || _.isNull(answer)){
              invalidBlocks.push(block.id);
              return;
            }
            if (_.isNull(answer.match(/^(\D*\d\D*){10,15}$/g))) { //Contains 10-15 digits
              invalidBlocks.push(block.id);
              return;
            }
            break;
          default:
            if(angular.isUndefined(answer)){
              invalidBlocks.push(block.id);
              return;
            }

            if (_.isEmpty(answer)) {
              invalidBlocks.push(block.id);
              return;
            }
            break;
        }
      });

      return invalidBlocks;
    };
  });
<|endoftext|>


<commit_before>'use strict';

/**
 * @module controllers
 */

/**
 * Provides default route action to deal with angularJS single page application.
 *
 * @class searchController
 */

const path = require('path');
const async = require('async');
const querystring = require('querystring');

const errors = process.require('app/server/httpErrors.js');
const openVeoAPI = require('@openveo/api');
const OpenVeoClient = require('@openveo/rest-nodejs-client').OpenVeoClient;
const configurationDirectoryPath = path.join(openVeoAPI.fileSystem.getConfDir(), 'portal');

const webservicesConf = require(path.join(configurationDirectoryPath, 'webservicesConf.json'));
const conf = require(path.join(configurationDirectoryPath, 'conf.json'));

const OPENVEO_CERT = webservicesConf.certificate;
const OPENVEO_URL = webservicesConf.path;
const CLIENT_ID = webservicesConf.clientID;
const CLIENT_SECRET = webservicesConf.secretID;

const openVeoClient = new OpenVeoClient(OPENVEO_URL, CLIENT_ID, CLIENT_SECRET, OPENVEO_CERT);

const videoCache = process.require('/app/server/serverCache/VideoCache');
const filterCache = process.require('/app/server/serverCache/FilterCache');
const VIDEO_PUBLISH_STATES = 12;

/**
 * Handles default action to display main HTML.
 *
 * If no other action were performed display the main template.
 * Main template loads libraries JavaScript files, Bootstrap CSS file and CSS file from the configured theme.
 *
 * @method defaultAction
 * @static
 */
module.exports.searchAction = (request, response, next) => {
  const body = request.body || {};
  const orderedProperties = ['views', 'date'];
  let params;
  let paginate;

  // Parse Filters
  try {
    params = openVeoAPI.util.shallowValidateObject(body.filter, {
      query: {type: 'string'},
      dateStart: {type: 'string'},
      dateEnd: {type: 'string'},
      categories: {type: 'array<string>'},
      sortBy: {type: 'string', in: orderedProperties, default: 'date'},
      sortOrder: {type: 'string', in: ['asc', 'desc'], default: 'desc'}
    });
  } catch (error) {
    return response.status(500).send({
      error: {
        message: error.message
      }
    });
  }

  // Add public group filter
  params['groups'] = conf.publicFilter;

  // Add visibility group filter
  if (request.isAuthenticated()) {

    // Add user filter
    if (request.user['groups'].length)
      params['groups'] = params['groups'].concat(request.user['groups']);
  }

  // Add published states
  params['states'] = VIDEO_PUBLISH_STATES;

  // Add properties
  Object.keys(body.filter).forEach((key) => {
    // if filter key is allready set thanks to shallowValidateObject
    if (!params[key] && params[key] !== '') {
      params[`properties[${key}]`] = body.filter[key];
    }
  });

  // Parse pagination
  try {
    paginate = openVeoAPI.util.shallowValidateObject(body.pagination, {
      limit: {type: 'number', gt: 0, default: 9},
      page: {type: 'number', gt: 0, default: 1}
    });
  } catch (error) {
    return response.status(500).send({
      error: {
        message: error.message
      }
    });
  }

  // Add pagination
  Object.keys(paginate).forEach((key) => {
    params[key] = paginate[key];
  });

  const query = querystring.stringify(params);

  // Get the list of videos
  openVeoClient.get(`/publish/videos?${query}`).then((result) => {
    result.pagination.page--;
    response.send(result);
  }).catch((error) => {
    process.logger.error(error.message, {error, method: 'searchAction'});
    return next(errors.SEARCH_ERROR);
  });
};

module.exports.getSearchFiltersAction = (request, response, next) => {
  const filters = [];
  const series = [];
  const filtersId = conf.exposedFilter;
  const categoriesId = conf.categoriesFilter;
  if (categoriesId && categoriesId != '')
    series.push((callback) => {
      filterCache.getCategories(categoriesId, (error, categories) => {
        if (categories) {
          filters.push(categories);
        }
        callback();
      });
    });

  for (let i = 0; i < filtersId.length; i++) {
    series.push((callback) => {
      filterCache.getFilter(filtersId[i], (error, filter) => {
        if (filter) {
          filters.push(filter);
        }
        callback();
      });
    });
  }

  async.series(series, () => {

    response.send(filters);
  });
};

module.exports.getCategoriesAction = (request, response, next) => {
  filterCache.getCategories(conf.categoriesFilter, (error, categories) => {
    if (error) {
      next(error);
      return;
    } else {
      response.send(categories);
    }
  });
};

module.exports.getVideoAction = (request, response, next) => {
  videoCache.getVideo(request.params.id, (error, res) => {
    if (error) {
      next(error);
      return;
    }

    const isInPublic = openVeoAPI.util.intersectArray(res.entity.metadata.groups, conf.publicFilter);
    const isInPrivate = openVeoAPI.util.intersectArray(res.entity.metadata.groups, conf.privateFilter);

    // return entity if entity is public
    if (isInPublic.length)
      response.send(res);

    // if video is private
    else if (isInPrivate.length) {

      // if user is not authentified, send need authent
      if (!request.isAuthenticated())
        response.send({needAuth: true});

      // if user is authentified
      else {
        const isAllowed = openVeoAPI.util.intersectArray(isInPrivate, request.user.groups);

        // if is allowed return authent else return error
        if (isAllowed.length) response.send(res);
        else next(errors.GET_VIDEO_NOT_ALLOWED);
      }

      // if no group corresponding to an entity
    } else {
      next(errors.GET_VIDEO_NOT_ALLOWED);
    }

  });
};
<commit_msg>Don't show boolean filter in portal (for the moment)<commit_after>'use strict';

/**
 * @module controllers
 */

/**
 * Provides default route action to deal with angularJS single page application.
 *
 * @class searchController
 */

const path = require('path');
const async = require('async');
const querystring = require('querystring');

const errors = process.require('app/server/httpErrors.js');
const openVeoAPI = require('@openveo/api');
const OpenVeoClient = require('@openveo/rest-nodejs-client').OpenVeoClient;
const configurationDirectoryPath = path.join(openVeoAPI.fileSystem.getConfDir(), 'portal');

const webservicesConf = require(path.join(configurationDirectoryPath, 'webservicesConf.json'));
const conf = require(path.join(configurationDirectoryPath, 'conf.json'));

const OPENVEO_CERT = webservicesConf.certificate;
const OPENVEO_URL = webservicesConf.path;
const CLIENT_ID = webservicesConf.clientID;
const CLIENT_SECRET = webservicesConf.secretID;

const openVeoClient = new OpenVeoClient(OPENVEO_URL, CLIENT_ID, CLIENT_SECRET, OPENVEO_CERT);

const videoCache = process.require('/app/server/serverCache/VideoCache');
const filterCache = process.require('/app/server/serverCache/FilterCache');
const VIDEO_PUBLISH_STATES = 12;

/**
 * Handles default action to display main HTML.
 *
 * If no other action were performed display the main template.
 * Main template loads libraries JavaScript files, Bootstrap CSS file and CSS file from the configured theme.
 *
 * @method defaultAction
 * @static
 */
module.exports.searchAction = (request, response, next) => {
  const body = request.body || {};
  const orderedProperties = ['views', 'date'];
  let params;
  let paginate;

  // Parse Filters
  try {
    params = openVeoAPI.util.shallowValidateObject(body.filter, {
      query: {type: 'string'},
      dateStart: {type: 'string'},
      dateEnd: {type: 'string'},
      categories: {type: 'array<string>'},
      sortBy: {type: 'string', in: orderedProperties, default: 'date'},
      sortOrder: {type: 'string', in: ['asc', 'desc'], default: 'desc'}
    });
  } catch (error) {
    return response.status(500).send({
      error: {
        message: error.message
      }
    });
  }

  // Add public group filter
  params['groups'] = conf.publicFilter;

  // Add visibility group filter
  if (request.isAuthenticated()) {

    // Add user filter
    if (request.user['groups'].length)
      params['groups'] = params['groups'].concat(request.user['groups']);
  }

  // Add published states
  params['states'] = VIDEO_PUBLISH_STATES;

  // Add properties
  Object.keys(body.filter).forEach((key) => {
    // if filter key is allready set thanks to shallowValidateObject
    if (!params[key] && params[key] !== '') {
      params[`properties[${key}]`] = body.filter[key];
    }
  });

  // Parse pagination
  try {
    paginate = openVeoAPI.util.shallowValidateObject(body.pagination, {
      limit: {type: 'number', gt: 0, default: 9},
      page: {type: 'number', gt: 0, default: 1}
    });
  } catch (error) {
    return response.status(500).send({
      error: {
        message: error.message
      }
    });
  }

  // Add pagination
  Object.keys(paginate).forEach((key) => {
    params[key] = paginate[key];
  });

  const query = querystring.stringify(params);

  // Get the list of videos
  openVeoClient.get(`/publish/videos?${query}`).then((result) => {
    result.pagination.page--;
    response.send(result);
  }).catch((error) => {
    process.logger.error(error.message, {error, method: 'searchAction'});
    return next(errors.SEARCH_ERROR);
  });
};

module.exports.getSearchFiltersAction = (request, response, next) => {
  const filters = [];
  const series = [];
  const filtersId = conf.exposedFilter;
  const categoriesId = conf.categoriesFilter;
  if (categoriesId && categoriesId != '')
    series.push((callback) => {
      filterCache.getCategories(categoriesId, (error, categories) => {
        if (categories) {
          filters.push(categories);
        }
        callback();
      });
    });

  for (let i = 0; i < filtersId.length; i++) {
    series.push((callback) => {
      filterCache.getFilter(filtersId[i], (error, filter) => {
        if (filter && filter.type !== 'boolean') {
          filters.push(filter);
        }
        callback();
      });
    });
  }

  async.series(series, () => {

    response.send(filters);
  });
};

module.exports.getCategoriesAction = (request, response, next) => {
  filterCache.getCategories(conf.categoriesFilter, (error, categories) => {
    if (error) {
      next(error);
      return;
    } else {
      response.send(categories);
    }
  });
};

module.exports.getVideoAction = (request, response, next) => {
  videoCache.getVideo(request.params.id, (error, res) => {
    if (error) {
      next(error);
      return;
    }

    const isInPublic = openVeoAPI.util.intersectArray(res.entity.metadata.groups, conf.publicFilter);
    const isInPrivate = openVeoAPI.util.intersectArray(res.entity.metadata.groups, conf.privateFilter);

    // return entity if entity is public
    if (isInPublic.length)
      response.send(res);

    // if video is private
    else if (isInPrivate.length) {

      // if user is not authentified, send need authent
      if (!request.isAuthenticated())
        response.send({needAuth: true});

      // if user is authentified
      else {
        const isAllowed = openVeoAPI.util.intersectArray(isInPrivate, request.user.groups);

        // if is allowed return authent else return error
        if (isAllowed.length) response.send(res);
        else next(errors.GET_VIDEO_NOT_ALLOWED);
      }

      // if no group corresponding to an entity
    } else {
      next(errors.GET_VIDEO_NOT_ALLOWED);
    }

  });
};
<|endoftext|>


<commit_before>/*
 * Copyright 2012 The Toolkitchen Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function() {
  var thisFile = 'pointerevents.js';
  var source = '', base = '';
  var s$ = document.querySelectorAll('script[src]');
  Array.prototype.forEach.call(s$, function(s) {
    var src = s.getAttribute('src');
    if (src.slice(-thisFile.length) == thisFile) {
      source = s;
      base = src.slice(0, -thisFile.length);
    }
  });
  var require = function(inSrc) {
    document.write('<script src="' + base + inSrc + '"></script>');
  };
  [
    'initialize.js',
    'pointermap.js',
    'dispatcher.js',
    'platform-events.js',
    'flick.js',
    'finalize.js'
  ].forEach(require);
})();
<commit_msg>Allow for loading from inside a web component<commit_after>/*
 * Copyright 2012 The Toolkitchen Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function() {
  var thisFile = 'pointerevents.js';
  var libLocation = '';
  /*
   * if we are loaded inside a component, we need to know the relative path from
   * that location, not the document
   */
  var baseUrlFromNode = function(inNode) {
    var n = inNode, p;
    while ((p = n.parentNode)) {
      n = p;
    }
    return (n && (n.URL || n.name)) || '';
  };
  var appendScriptPath = function(inBasePath, inRelPath) {
    // include last slash as well
    var ls = inBasePath.lastIndexOf('/') + 1;
    return inBasePath.slice(0, ls) + inRelPath;
  };
  var require = function(inSrc) {
    document.write('<script src="' + libLocation + inSrc + '"></script>');
  };
  var s$ = document.querySelectorAll('script[src]');
  Array.prototype.forEach.call(s$, function(s) {
    var src = s.getAttribute('src');
    if (src.slice(-thisFile.length) == thisFile) {
      var source = baseUrlFromNode(s);
      var base = src.slice(0, -thisFile.length);
      libLocation = appendScriptPath(source, base);
    }
  });
  [
    'initialize.js',
    'pointermap.js',
    'dispatcher.js',
    'platform-events.js',
    'flick.js',
    'finalize.js'
  ].forEach(require);
})();
<|endoftext|>


<commit_before>$(function() {
	$('#omega_naobundle_observations_espece').typeahead({ source: noms });
})<commit_msg>modifs<commit_after>$(function() {
	$('#omega_naobundle_observations_espece').typeahead({ source: noms });
});<|endoftext|>


<commit_before>
$(function () {
    $('[data-toggle="popover"]').popover();
})

$(".sidebar-toggle").click(function(e) {
    e.preventDefault();
    $("#wrapper").toggleClass("active");
});

function addCardButtonHandler() {
    // ADD CARD
    $('a[href="#addCard"]').unbind('click');
    $('a[href="#addCard"]').click(function(e) {
	var addCardButton = $(this);
	var card = addCardButton.closest('.card');
	$('#id_card').val(card.prop('id')).change();
	addCardFormHandler(card.find('img.non_idolized').prop('src'),
			   card.find('img.idolized').prop('src'));

	$('#addCardModal form.add').unbind('submit');
	$('#addCardModal form.add').submit(function(e) {
	    e.preventDefault();
	    $(this).ajaxSubmit({
		success: function(data) {
		    addCardButton.before(data + '|');
		    $('#addCardModal').modal('hide');
		    editCardFormHandler();
		    $('[data-toggle="popover"]').popover();
		},
		error: function() {
		    $('#addCardModal').modal('hide');
		    alert('Opps! Something bad happened. Try again.');
		}
	    });
	});
    });
}

function youtubeRatio() {
    var showYoutubeIframe = function(embed_video) {
	if (embed_video.length > 0) {
	    embed_video.html('
Watch all the stories

');
	    var width = embed_video.width();
	    if (!width) {
		width = 200;
	    }
	    embed_video.find('iframe').height(width * (450 / 800));
	}
    };
    $('.more.collapse').on('show.bs.collapse', function() { showYoutubeIframe($(this).find('.embed_video')) });
    $('.already_collapsed').each(function() {
	console.log($(this));
	showYoutubeIframe($(this).find('.embed_video'));
    });
}

function center_images() {
    $('.card_images').each(function() {
	if ($(this).closest('.panel-body').children('.row').length > 0) {
	    var height = $(this).closest('.panel-body').height();
	    $(this).css('margin-top', (height / 2) - ($(this).find('.idolized').height() / 2));
	}
    });
}

function load_more_function() {
    var button = $("#load_more");
    var oldButtonContent = button.html();
    button.html('
Loading...
');
    var next_page = button.attr('data-next-page');
    $.get('/ajax/cards/' + location.search + (location.search == '' ? '?' : '&') + 'page=' + next_page, function(data) {
	button.replaceWith(data);
	pagination();
	addCardButtonHandler();
	editCardFormHandler();
	statistics_buttons();
	youtubeRatio();
	center_images();

	// Reload disqus comments count
	window.DISQUSWIDGETS = undefined;
	$.getScript("http://schoolidol.disqus.com/count.js");

	$('[data-toggle="popover"]').popover();
    });
}

function pagination() {
    var button = $("#load_more");
    $(window).scroll(
	function () {
	    if (button.length > 0
		&& button.find('.loader').length == 0
		&& ($(window).scrollTop() + $(window).height())
		>= ($(document).height() - button.height())) {
		load_more_function();
	    }
	});
}

function statistics_buttons() {
    $('.btn.minimum_statistics').unbind('click');
    $('.btn.minimum_statistics').click(function() {
	card = $(this).closest('.card')
	card.find('.statistics_minimum').show()
	card.find('.statistics_non_idolized_maximum').hide()
	card.find('.statistics_idolized_maximum').hide()
	card.find('.hp_non_idolized').show()
	card.find('.hp_idolized').hide()
    })
    $('.btn.non_idolized_statistics').unbind('click');
    $('.btn.non_idolized_statistics').click(function() {
	card = $(this).closest('.card')
	card.find('.statistics_minimum').hide()
	card.find('.statistics_non_idolized_maximum').show()
	card.find('.statistics_idolized_maximum').hide()
	card.find('.hp_non_idolized').show()
	card.find('.hp_idolized').hide()
    })
    $('.btn.idolized_statistics').unbind('click');
    $('.btn.idolized_statistics').click(function() {
	card = $(this).closest('.card')
	card.find('.statistics_minimum').hide()
	card.find('.statistics_non_idolized_maximum').hide()
	card.find('.statistics_idolized_maximum').show()
	card.find('.hp_non_idolized').hide()
	card.find('.hp_idolized').show()
    })
}

addCardButtonHandler();
$(document).ready(function() {
    addCardButtonHandler();
    statistics_buttons();
    center_images();
    pagination();
    youtubeRatio();
});
<commit_msg>web: Fix js youtube ratio<commit_after>
$(function () {
    $('[data-toggle="popover"]').popover();
})

$(".sidebar-toggle").click(function(e) {
    e.preventDefault();
    $("#wrapper").toggleClass("active");
});

function addCardButtonHandler() {
    // ADD CARD
    $('a[href="#addCard"]').unbind('click');
    $('a[href="#addCard"]').click(function(e) {
	var addCardButton = $(this);
	var card = addCardButton.closest('.card');
	$('#id_card').val(card.prop('id')).change();
	addCardFormHandler(card.find('img.non_idolized').prop('src'),
			   card.find('img.idolized').prop('src'));

	$('#addCardModal form.add').unbind('submit');
	$('#addCardModal form.add').submit(function(e) {
	    e.preventDefault();
	    $(this).ajaxSubmit({
		success: function(data) {
		    addCardButton.before(data + '|');
		    $('#addCardModal').modal('hide');
		    editCardFormHandler();
		    $('[data-toggle="popover"]').popover();
		},
		error: function() {
		    $('#addCardModal').modal('hide');
		    alert('Opps! Something bad happened. Try again.');
		}
	    });
	});
    });
}

function youtubeRatio() {
    var showYoutubeIframe = function(embed_video) {
	if (embed_video.length > 0) {
	    embed_video.html('
Watch all the stories

');
	    var width = embed_video.parent().width();
	    embed_video.find('iframe').height(width * (450 / 800));
	}
    };
    $('.more.collapse').on('show.bs.collapse', function() { showYoutubeIframe($(this).find('.embed_video')) });
    $('.already_collapsed').each(function() {
	console.log($(this));
	showYoutubeIframe($(this).find('.embed_video'));
    });
}

function center_images() {
    $('.card_images').each(function() {
	if ($(this).closest('.panel-body').children('.row').length > 0) {
	    var height = $(this).closest('.panel-body').height();
	    $(this).css('margin-top', (height / 2) - ($(this).find('.idolized').height() / 2));
	}
    });
}

function load_more_function() {
    var button = $("#load_more");
    var oldButtonContent = button.html();
    button.html('
Loading...
');
    var next_page = button.attr('data-next-page');
    $.get('/ajax/cards/' + location.search + (location.search == '' ? '?' : '&') + 'page=' + next_page, function(data) {
	button.replaceWith(data);
	pagination();
	addCardButtonHandler();
	editCardFormHandler();
	statistics_buttons();
	youtubeRatio();
	center_images();

	// Reload disqus comments count
	window.DISQUSWIDGETS = undefined;
	$.getScript("http://schoolidol.disqus.com/count.js");

	$('[data-toggle="popover"]').popover();
    });
}

function pagination() {
    var button = $("#load_more");
    $(window).scroll(
	function () {
	    if (button.length > 0
		&& button.find('.loader').length == 0
		&& ($(window).scrollTop() + $(window).height())
		>= ($(document).height() - button.height())) {
		load_more_function();
	    }
	});
}

function statistics_buttons() {
    $('.btn.minimum_statistics').unbind('click');
    $('.btn.minimum_statistics').click(function() {
	card = $(this).closest('.card')
	card.find('.statistics_minimum').show()
	card.find('.statistics_non_idolized_maximum').hide()
	card.find('.statistics_idolized_maximum').hide()
	card.find('.hp_non_idolized').show()
	card.find('.hp_idolized').hide()
    })
    $('.btn.non_idolized_statistics').unbind('click');
    $('.btn.non_idolized_statistics').click(function() {
	card = $(this).closest('.card')
	card.find('.statistics_minimum').hide()
	card.find('.statistics_non_idolized_maximum').show()
	card.find('.statistics_idolized_maximum').hide()
	card.find('.hp_non_idolized').show()
	card.find('.hp_idolized').hide()
    })
    $('.btn.idolized_statistics').unbind('click');
    $('.btn.idolized_statistics').click(function() {
	card = $(this).closest('.card')
	card.find('.statistics_minimum').hide()
	card.find('.statistics_non_idolized_maximum').hide()
	card.find('.statistics_idolized_maximum').show()
	card.find('.hp_non_idolized').hide()
	card.find('.hp_idolized').show()
    })
}

addCardButtonHandler();
$(document).ready(function() {
    addCardButtonHandler();
    statistics_buttons();
    center_images();
    pagination();
    youtubeRatio();
});
<|endoftext|>