<commit_before>/**
 * @file Guide component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import TriggerPop from '../_TriggerPop';
import AnchorButton from '../AnchorButton';

import Position from '../_statics/Position';
import MsgType from '../_statics/MsgType';

import Util from '../_vendors/Util';
import PopManagement from '../_vendors/PopManagement';

class Guide extends Component {

    static Position = Position;
    static Type = MsgType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    /**
     * public
     */
    resetPosition = () => {
        this.refs.guide && this.refs.guide.resetPosition();
    };

    getIconCls = () => {
        switch (this.props.type) {
            case MsgType.SUCCESS:
                return 'fas fa-check-circle';
            case MsgType.WARNING:
                return 'fas fa-exclamation-triangle';
            case MsgType.ERROR:
                return 'fas fa-times-circle';
            default:
                return 'fas fa-info-circle';
        }
    };

    renderHandler = (...args) => {

        PopManagement.push(this);

        const {onRender} = this.props;
        onRender && onRender(...args);

    };

    destroyHandler = (...args) => {

        PopManagement.pop(this);

        const {onDestroy} = this.props;
        onDestroy && onDestroy(...args);

    };

    render() {

        const {

                className, contentClassName, type, iconVisible, iconCls, closeButtonVisible, closeButtonValue,
                children, onRequestClose,

                ...restProps

            } = this.props,

            guideClassName = classNames('guide', {
                'icon-hidden': !iconVisible,
                [className]: className
            }),

            guideContentClassName = classNames('guide-content', {
                'theme-default': type === MsgType.DEFAULT,
                [`theme-${type}`]: type !== MsgType.DEFAULT,
                [contentClassName]: contentClassName
            });

        return (
            <TriggerPop {...restProps}
                        ref="guide"
                        className={guideClassName}
                        contentClassName={guideContentClassName}
                        onRender={this.renderHandler}
                        onDestroy={this.destroyHandler}>

                {
                    !iconVisible || type === MsgType.DEFAULT ?
                        null
                        :

                }

                    {children}

                    {
                        closeButtonVisible ?
                            <AnchorButton className="guide-close-Button"
                                          value={closeButtonValue}
                                          onClick={onRequestClose}/>
                            :
                            null
                    }

            </TriggerPop>
        );
    }

}

Guide.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the content element.
     */
    contentClassName: PropTypes.string,

    modalClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The type of notification.
     */
    type: PropTypes.oneOf(Util.enumerateValue(MsgType)),

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The guide alignment.
     */
    position: PropTypes.oneOf(Util.enumerateValue(Position)),

    iconVisible: PropTypes.bool,
    iconCls: PropTypes.string,

    /**
     * If true,guide will have animation effects.
     */
    isAnimated: PropTypes.bool,

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    isBlurClose: PropTypes.bool,
    isEscClose: PropTypes.bool,
    shouldPreventContainerScroll: PropTypes.bool,
    isTriggerPositionFixed: PropTypes.bool,
    resetPositionWait: PropTypes.number,
    showModal: PropTypes.bool,

    closeButtonVisible: PropTypes.bool,
    closeButtonValue: PropTypes.string,

    /**
     * The function of guide render.
     */
    onRender: PropTypes.func,

    /**
     * The function of guide rendered.
     */
    onRendered: PropTypes.func,

    /**
     * The function of guide destroy.
     */
    onDestroy: PropTypes.func,

    /**
     * The function of guide destroyed.
     */
    onDestroyed: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be closed.
     */
    onRequestClose: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func

};

Guide.defaultProps = {

    type: MsgType.INFO,
    visible: false,
    hasTriangle: true,
    position: Position.BOTTOM,
    isAnimated: true,
    iconVisible: true,

    isBlurClose: true,
    isEscClose: true,
    shouldPreventContainerScroll: true,
    isTriggerPositionFixed: false,
    resetPositionWait: 250,
    showModal: false,

    closeButtonVisible: true,
    closeButtonValue: 'Close'

};

export default Guide;
<commit_msg>update Guide<commit_after>/**
 * @file Guide component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import TriggerPop from '../_TriggerPop';
import AnchorButton from '../AnchorButton';

import Position from '../_statics/Position';
import MsgType from '../_statics/MsgType';

import Util from '../_vendors/Util';
import PopManagement from '../_vendors/PopManagement';

class Guide extends Component {

    static Position = Position;
    static Type = MsgType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    /**
     * public
     */
    resetPosition = () => {
        this.refs.guide && this.refs.guide.resetPosition();
    };

    getIconCls = () => {
        switch (this.props.type) {
            case MsgType.SUCCESS:
                return 'fas fa-check-circle';
            case MsgType.WARNING:
                return 'fas fa-exclamation-triangle';
            case MsgType.ERROR:
                return 'fas fa-times-circle';
            default:
                return 'fas fa-info-circle';
        }
    };

    renderHandler = (...args) => {

        PopManagement.push(this);

        const {onRender} = this.props;
        onRender && onRender(...args);

    };

    destroyHandler = (...args) => {

        PopManagement.pop(this);

        const {onDestroy} = this.props;
        onDestroy && onDestroy(...args);

    };

    componentWillUnmount() {
        PopManagement.pop(this);
    }

    render() {

        const {

                className, contentClassName, type, iconVisible, iconCls, closeButtonVisible, closeButtonValue,
                children, onRequestClose,

                ...restProps

            } = this.props,

            guideClassName = classNames('guide', {
                'icon-hidden': !iconVisible,
                [className]: className
            }),

            guideContentClassName = classNames('guide-content', {
                'theme-default': type === MsgType.DEFAULT,
                [`theme-${type}`]: type !== MsgType.DEFAULT,
                [contentClassName]: contentClassName
            });

        return (
            <TriggerPop {...restProps}
                        ref="guide"
                        className={guideClassName}
                        contentClassName={guideContentClassName}
                        onRender={this.renderHandler}
                        onDestroy={this.destroyHandler}>

                {
                    !iconVisible || type === MsgType.DEFAULT ?
                        null
                        :

                }

                    {children}

                    {
                        closeButtonVisible ?
                            <AnchorButton className="guide-close-Button"
                                          value={closeButtonValue}
                                          onClick={onRequestClose}/>
                            :
                            null
                    }

            </TriggerPop>
        );
    }

}

Guide.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The CSS class name of the content element.
     */
    contentClassName: PropTypes.string,

    modalClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The type of notification.
     */
    type: PropTypes.oneOf(Util.enumerateValue(MsgType)),

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The guide alignment.
     */
    position: PropTypes.oneOf(Util.enumerateValue(Position)),

    iconVisible: PropTypes.bool,
    iconCls: PropTypes.string,

    /**
     * If true,guide will have animation effects.
     */
    isAnimated: PropTypes.bool,

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    isBlurClose: PropTypes.bool,
    isEscClose: PropTypes.bool,
    shouldPreventContainerScroll: PropTypes.bool,
    isTriggerPositionFixed: PropTypes.bool,
    resetPositionWait: PropTypes.number,
    showModal: PropTypes.bool,

    closeButtonVisible: PropTypes.bool,
    closeButtonValue: PropTypes.string,

    /**
     * The function of guide render.
     */
    onRender: PropTypes.func,

    /**
     * The function of guide rendered.
     */
    onRendered: PropTypes.func,

    /**
     * The function of guide destroy.
     */
    onDestroy: PropTypes.func,

    /**
     * The function of guide destroyed.
     */
    onDestroyed: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be closed.
     */
    onRequestClose: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func

};

Guide.defaultProps = {

    type: MsgType.INFO,
    visible: false,
    hasTriangle: true,
    position: Position.BOTTOM,
    isAnimated: true,
    iconVisible: true,

    isBlurClose: true,
    isEscClose: true,
    shouldPreventContainerScroll: true,
    isTriggerPositionFixed: false,
    resetPositionWait: 250,
    showModal: false,

    closeButtonVisible: true,
    closeButtonValue: 'Close'

};

export default Guide;
<|endoftext|>


<commit_before>////////////////////////////////////
// Controller for event dashboard //
////////////////////////////////////

'use strict';

pay.controller('AdminEvent', [
    '$scope',
    '$timeout',
    '$routeParams',
    '$http',
    'ParsePrices',
    'PayAuth',
    'Event',
    'Account',
    'EventTickets',
    'FormValidator',
    'Error',
    function ($scope, $timeout, $routeParams, $http, ParsePrices, PayAuth, Event, Account, EventTickets, FormValidator, Error) {
        if (!PayAuth.needUser()) { return; }

        var eventId = $routeParams.eventId;

        var BoundAccount = Account.bind({
            id: eventId
        });

        $scope.foundUsers = {};
        $scope.vendors = [];
        $scope.admins = [];

        // jQuery autocomplete
        $('#searchVendorUser, #searchAdminUser').autocomplete({
            serviceUrl: '/api/etu/search/',
            minChars: 3,
            maxHeight: 400,
            zIndex: 9999,
            // callback function:
            onSelect: function (suggestion) {
                if (this.id === 'searchVendorUser') {
                    $scope.vendorToAdd = suggestion.value;
                } else {
                    $scope.adminToAdd = suggestion.value;
                }
            },
            onSearchError: function (v, e) {
                if (e.responseText) {
                    Error('Erreur', JSON.parse(e.responseText).error);
                }
            },
            transformResult: function (response) {
                var fullNames = JSON.parse(response).map(function (v) {
                    $scope.foundUsers[v.fullName] = v.id;
                    return v.fullName;
                });
                return {
                    suggestions: fullNames
                };
            }
        });

        // Activate the datepicker, and ng-validate when the date changes
        $('.date').datetimepicker().on('dp.change', function () {
            var $self = $(this).children().first();
            $timeout(function () {
                if (!$self.data().$ngModelController) {
                    return;
                }
                $self.data().$ngModelController.$setViewValue($self.val());
            }, 0);
        });

        // Updates the input text with the input file name
        $('input[type=file]').on('change', function (e) {
            if (this.files.length === 1) {
                $(this).parent().parent().next().val(this.files[0].name);
            }
        });

        /**
         * Checks whether the given string is a positive integer or not
         * @param  {string}  str The integer as a string
         * @return {Boolean}     True if the given string is an integer
         */
        function isInteger (str) {
            var n = ~~Number(str);
            return String(n) === str && n >= 0;
        }

        if (!isInteger(eventId)) {
            location.hash = '#/admin/';
            Error('Erreur', 6);
            return;
        }

        Event.get({
            id: eventId,
        }, function (e) {
            if (!e.hasOwnProperty('id')) {
                location.hash = '#/admin/';
                Error('Erreur', 0);
            }
            $scope.currentEvent = e;

            // Parse the date
            var b = moment($scope.currentEvent.date, moment.ISO_8601);
            var now = moment();
            var diff = moment({
                years: b.year() - now.year(),
                months: b.month() - now.month(),
                date: b.date() - now.date(),
                hours: b.hours() - now.hours(),
                minutes: 0,
                seconds: 0,
                milliseconds: 0
            });
            var formatted = diff.months() + ' mois, ' +
                            diff.date() + ' jours et ' +
                            diff.hours() + ' heure(s)';

            $scope.currentEvent.date = b.format('DD/MM/YYYY HH:mm');
            $('.date').data('DateTimePicker').date($scope.currentEvent.date);
            $scope.remainingTime = formatted;

            // Parse the prices
            ParsePrices.fromEvent(e);
        }, function (res) {
            location.hash = '#/admin/';

            if (res.data && res.data.status) {
                return Error('Erreur', res.data.error);
            }
            Error('Erreur', 6);
        });

        EventTickets.query({
            id: eventId
        }, function (tickets) {
            $scope.tickets = tickets;

            // Tickets with etu price
            $scope.ticketsEtu = tickets.filter(function (ticket) {
                return ticket.student && !ticket.contributor
            });

            // Tickets with bde member price
            $scope.ticketsContrib = tickets.filter(function (ticket) {
                return ticket.student && ticket.contributor
            });

            // Tickets with external price
            $scope.ticketsExt = tickets.filter(function (ticket) {
                return !ticket.student && !ticket.contributor
            });

            // Tickets not paid, in cash
            $scope.ticketsNotPaid = tickets.filter(function (ticket) {
                return !ticket.paid
            });

            // Amount of paid tickets
            $scope.paidTickets = tickets.length - $scope.ticketsNotPaid.length;
        });

        Account.query({
            id: eventId
        }, function (accounts) {
            accounts.forEach(function (account) {
                var nameSplitted = account[0].split(' ');
                nameSplitted.push(account[1]);
                if (account[2] === 1) {
                    $scope.admins.push(nameSplitted);
                } else {
                    $scope.vendors.push(nameSplitted);
                }
            });
        });

        /**
         * Edits the event parameters
         * @param {object} e The click event
         */
        this.editParameters = function (e) {
            e.preventDefault();
            $('#modalEdit').modal();
        };

        /**
         * Edits the event
         * @param {object} e The click event
         */
        this.editEvent = function (e) {
            var fileDisabled = eventForm.file.files.length === 0;
            if (fileDisabled) {
                if (!FormValidator(eventForm, 'file')) {
                    return;
                }
            } else {
                if (!FormValidator(eventForm, 'file', true)) {
                    return;
                }
            }

            if (!fileDisabled) {
                var file = eventForm.file.files[0];

                // Image -> string
                var reader = new FileReader();
                reader.onload = callback;
                reader.readAsDataURL(file);
            } else {
                callback();
            }

            function callback (e) {
                if (!fileDisabled) {
                    var result = e.currentTarget.result;
                    $scope.currentEvent.image = result;
                }

                $scope.currentEvent.date = moment($scope.currentEvent.date, 'DD/MM/YYYY HH:mm').toDate();

                $scope.currentEvent.$save(function (res) {
                    $scope.currentEvent = this;
                    var dateDiff = new Date($scope.currentEvent.date) - new Date();
                    $scope.currentEvent.date = moment(new Date($scope.currentEvent.date)).format('DD/MM/YYYY HH:mm');
                    $('.date').data('DateTimePicker').date($scope.currentEvent.date);
                    $scope.remainingTime = moment(new Date(dateDiff)).format('D [jour(s) et] H [heure(s)]');
                    $('#modalEdit').modal('hide');
                }, function (res) {
                    Error('Erreur', res.data.error);
                });
            }
        };

        /**
         * Shows the modal to prevent from miss clicks
         * @param {string} e The click event
         */
        this.confirmDeleteEvent = function (e) {
            e.preventDefault();
            $('#modalConfirm').modal();
        };

        /**
         * Deletes the event
         * @param {object} e The click event
         */
        this.deleteEvent = function (e) {
            e.preventDefault();
            $scope.currentEvent.$remove({
                id: $scope.currentEvent.id
            }).then(function (res) {
                if (res.status === 200) {
                    $('#modalConfirm').modal('hide').on('hidden.bs.modal', function () {
                        location.hash = '#/admin/';
                    });
                }
            });
        };

        /**
         * Shows the modal to changes the event prices
         * @param {object} e The click event
         */
        this.showChangePrices = function (e) {
            e.preventDefault();
            $('#modalPrices').modal();
        };

        /**
         * Changes the event prices
         * @param {object} e The click event
         */
        this.changePrices = function (e) {
            e.preventDefault();
            ParsePrices.toEvent($scope.currentEvent, $scope.newPrices);
        };

        /**
         * Adds a vendor to the event
         * @param {object} e The submit event
         */
        this.addVendor = function (e) {
            e.preventDefault();
            var username = $scope.foundUsers[$scope.vendorToAdd];
            var displayName = $scope.vendorToAdd;

            var newAccount = new BoundAccount({
                username: username,
                displayName: displayName,
                event_id: $scope.currentEvent.id,
                right_id: 2 // Vendor right
            });

            newAccount.$save(function () {
                var splitted = displayName.split(' ');
                var firstName = splitted.shift();
                var lastName = splitted.join(' ');

                $scope.vendorToAdd = '';
                $scope.vendors.push([firstName, lastName, newAccount.id]);
            }, function (res) {
                Error('Erreur', res.data.error);
            });
        };

        /**
         * Adds an admin to the event
         * @param {object} e The submit event
         */
        this.addAdmin = function (e) {
            e.preventDefault();
            var username = $scope.foundUsers[$scope.adminToAdd];
            var displayName = $scope.adminToAdd;
            var newAccount = new BoundAccount({
                username: username,
                displayName: displayName,
                event_id: $scope.currentEvent.id,
                right_id: 1 // Admin right
            });

            newAccount.$save(function () {
                var splitted = displayName.split(' ');
                var firstName = splitted.shift();
                var lastName = splitted.join(' ');

                $scope.adminToAdd = '';
                $scope.admins.push([firstName, lastName, newAccount.id]);
            }, function (res) {
                Error('Erreur', res.data.error);
            });
        };

        /**
         * Removes an account (admin or vendor)
         * @param  {object} e         The submit event
         * @param  {number} accountId The account id
         */
        this.removeAccount = function (e, accountId) {
            e.preventDefault();
            $http.delete('/api/accounts/' + accountId).then(function () {
                if (e.currentTarget.dataset.hasOwnProperty('vendor')) {
                    $scope.vendors.splice(e.currentTarget.dataset.index, 1);
                } else {
                    $scope.admins.splice(e.currentTarget.dataset.index, 1);
                }
            }, function () {
                Error('Erreur', 0);
            });
        };
    }
]);
<commit_msg>Hide modal when the prices have been changed<commit_after>////////////////////////////////////
// Controller for event dashboard //
////////////////////////////////////

'use strict';

pay.controller('AdminEvent', [
    '$scope',
    '$timeout',
    '$routeParams',
    '$http',
    'ParsePrices',
    'PayAuth',
    'Event',
    'Account',
    'EventTickets',
    'FormValidator',
    'Error',
    function ($scope, $timeout, $routeParams, $http, ParsePrices, PayAuth, Event, Account, EventTickets, FormValidator, Error) {
        if (!PayAuth.needUser()) { return; }

        var eventId = $routeParams.eventId;

        var BoundAccount = Account.bind({
            id: eventId
        });

        $scope.foundUsers = {};
        $scope.vendors = [];
        $scope.admins = [];

        // jQuery autocomplete
        $('#searchVendorUser, #searchAdminUser').autocomplete({
            serviceUrl: '/api/etu/search/',
            minChars: 3,
            maxHeight: 400,
            zIndex: 9999,
            // callback function:
            onSelect: function (suggestion) {
                if (this.id === 'searchVendorUser') {
                    $scope.vendorToAdd = suggestion.value;
                } else {
                    $scope.adminToAdd = suggestion.value;
                }
            },
            onSearchError: function (v, e) {
                if (e.responseText) {
                    Error('Erreur', JSON.parse(e.responseText).error);
                }
            },
            transformResult: function (response) {
                var fullNames = JSON.parse(response).map(function (v) {
                    $scope.foundUsers[v.fullName] = v.id;
                    return v.fullName;
                });
                return {
                    suggestions: fullNames
                };
            }
        });

        // Activate the datepicker, and ng-validate when the date changes
        $('.date').datetimepicker().on('dp.change', function () {
            var $self = $(this).children().first();
            $timeout(function () {
                if (!$self.data().$ngModelController) {
                    return;
                }
                $self.data().$ngModelController.$setViewValue($self.val());
            }, 0);
        });

        // Updates the input text with the input file name
        $('input[type=file]').on('change', function (e) {
            if (this.files.length === 1) {
                $(this).parent().parent().next().val(this.files[0].name);
            }
        });

        /**
         * Checks whether the given string is a positive integer or not
         * @param  {string}  str The integer as a string
         * @return {Boolean}     True if the given string is an integer
         */
        function isInteger (str) {
            var n = ~~Number(str);
            return String(n) === str && n >= 0;
        }

        if (!isInteger(eventId)) {
            location.hash = '#/admin/';
            Error('Erreur', 6);
            return;
        }

        Event.get({
            id: eventId,
        }, function (e) {
            if (!e.hasOwnProperty('id')) {
                location.hash = '#/admin/';
                Error('Erreur', 0);
            }
            $scope.currentEvent = e;

            // Parse the date
            var b = moment($scope.currentEvent.date, moment.ISO_8601);
            var now = moment();
            var diff = moment({
                years: b.year() - now.year(),
                months: b.month() - now.month(),
                date: b.date() - now.date(),
                hours: b.hours() - now.hours(),
                minutes: 0,
                seconds: 0,
                milliseconds: 0
            });
            var formatted = diff.months() + ' mois, ' +
                            diff.date() + ' jours et ' +
                            diff.hours() + ' heure(s)';

            $scope.currentEvent.date = b.format('DD/MM/YYYY HH:mm');
            $('.date').data('DateTimePicker').date($scope.currentEvent.date);
            $scope.remainingTime = formatted;

            // Parse the prices
            ParsePrices.fromEvent(e);
        }, function (res) {
            location.hash = '#/admin/';

            if (res.data && res.data.status) {
                return Error('Erreur', res.data.error);
            }
            Error('Erreur', 6);
        });

        EventTickets.query({
            id: eventId
        }, function (tickets) {
            $scope.tickets = tickets;

            // Tickets with etu price
            $scope.ticketsEtu = tickets.filter(function (ticket) {
                return ticket.student && !ticket.contributor
            });

            // Tickets with bde member price
            $scope.ticketsContrib = tickets.filter(function (ticket) {
                return ticket.student && ticket.contributor
            });

            // Tickets with external price
            $scope.ticketsExt = tickets.filter(function (ticket) {
                return !ticket.student && !ticket.contributor
            });

            // Tickets not paid, in cash
            $scope.ticketsNotPaid = tickets.filter(function (ticket) {
                return !ticket.paid
            });

            // Amount of paid tickets
            $scope.paidTickets = tickets.length - $scope.ticketsNotPaid.length;
        });

        Account.query({
            id: eventId
        }, function (accounts) {
            accounts.forEach(function (account) {
                var nameSplitted = account[0].split(' ');
                nameSplitted.push(account[1]);
                if (account[2] === 1) {
                    $scope.admins.push(nameSplitted);
                } else {
                    $scope.vendors.push(nameSplitted);
                }
            });
        });

        /**
         * Edits the event parameters
         * @param {object} e The click event
         */
        this.editParameters = function (e) {
            e.preventDefault();
            $('#modalEdit').modal();
        };

        /**
         * Edits the event
         * @param {object} e The click event
         */
        this.editEvent = function (e) {
            var fileDisabled = eventForm.file.files.length === 0;
            if (fileDisabled) {
                if (!FormValidator(eventForm, 'file')) {
                    return;
                }
            } else {
                if (!FormValidator(eventForm, 'file', true)) {
                    return;
                }
            }

            if (!fileDisabled) {
                var file = eventForm.file.files[0];

                // Image -> string
                var reader = new FileReader();
                reader.onload = callback;
                reader.readAsDataURL(file);
            } else {
                callback();
            }

            function callback (e) {
                if (!fileDisabled) {
                    var result = e.currentTarget.result;
                    $scope.currentEvent.image = result;
                }

                $scope.currentEvent.date = moment($scope.currentEvent.date, 'DD/MM/YYYY HH:mm').toDate();

                $scope.currentEvent.$save(function (res) {
                    $scope.currentEvent = this;
                    var dateDiff = new Date($scope.currentEvent.date) - new Date();
                    $scope.currentEvent.date = moment(new Date($scope.currentEvent.date)).format('DD/MM/YYYY HH:mm');
                    $('.date').data('DateTimePicker').date($scope.currentEvent.date);
                    $scope.remainingTime = moment(new Date(dateDiff)).format('D [jour(s) et] H [heure(s)]');
                    $('#modalEdit').modal('hide');
                }, function (res) {
                    Error('Erreur', res.data.error);
                });
            }
        };

        /**
         * Shows the modal to prevent from miss clicks
         * @param {string} e The click event
         */
        this.confirmDeleteEvent = function (e) {
            e.preventDefault();
            $('#modalConfirm').modal();
        };

        /**
         * Deletes the event
         * @param {object} e The click event
         */
        this.deleteEvent = function (e) {
            e.preventDefault();
            $scope.currentEvent.$remove({
                id: $scope.currentEvent.id
            }).then(function (res) {
                if (res.status === 200) {
                    $('#modalConfirm').modal('hide').on('hidden.bs.modal', function () {
                        location.hash = '#/admin/';
                    });
                }
            });
        };

        /**
         * Shows the modal to changes the event prices
         * @param {object} e The click event
         */
        this.showChangePrices = function (e) {
            e.preventDefault();
            $('#modalPrices').modal();
        };

        /**
         * Changes the event prices
         * @param {object} e The click event
         */
        this.changePrices = function (e) {
            e.preventDefault();
            ParsePrices.toEvent($scope.currentEvent, $scope.newPrices);
            $('#modalPrices').modal('hide');
        };

        /**
         * Adds a vendor to the event
         * @param {object} e The submit event
         */
        this.addVendor = function (e) {
            e.preventDefault();
            var username = $scope.foundUsers[$scope.vendorToAdd];
            var displayName = $scope.vendorToAdd;

            var newAccount = new BoundAccount({
                username: username,
                displayName: displayName,
                event_id: $scope.currentEvent.id,
                right_id: 2 // Vendor right
            });

            newAccount.$save(function () {
                var splitted = displayName.split(' ');
                var firstName = splitted.shift();
                var lastName = splitted.join(' ');

                $scope.vendorToAdd = '';
                $scope.vendors.push([firstName, lastName, newAccount.id]);
            }, function (res) {
                Error('Erreur', res.data.error);
            });
        };

        /**
         * Adds an admin to the event
         * @param {object} e The submit event
         */
        this.addAdmin = function (e) {
            e.preventDefault();
            var username = $scope.foundUsers[$scope.adminToAdd];
            var displayName = $scope.adminToAdd;
            var newAccount = new BoundAccount({
                username: username,
                displayName: displayName,
                event_id: $scope.currentEvent.id,
                right_id: 1 // Admin right
            });

            newAccount.$save(function () {
                var splitted = displayName.split(' ');
                var firstName = splitted.shift();
                var lastName = splitted.join(' ');

                $scope.adminToAdd = '';
                $scope.admins.push([firstName, lastName, newAccount.id]);
            }, function (res) {
                Error('Erreur', res.data.error);
            });
        };

        /**
         * Removes an account (admin or vendor)
         * @param  {object} e         The submit event
         * @param  {number} accountId The account id
         */
        this.removeAccount = function (e, accountId) {
            e.preventDefault();
            $http.delete('/api/accounts/' + accountId).then(function () {
                if (e.currentTarget.dataset.hasOwnProperty('vendor')) {
                    $scope.vendors.splice(e.currentTarget.dataset.index, 1);
                } else {
                    $scope.admins.splice(e.currentTarget.dataset.index, 1);
                }
            }, function () {
                Error('Erreur', 0);
            });
        };
    }
]);
<|endoftext|>


<commit_before>/* @flow */
import { findAll } from 'highlight-words-core'
import PropTypes from 'prop-types'
import React from 'react'

Highlighter.propTypes = {
  activeClassName: PropTypes.string,
  activeIndex: PropTypes.number,
  activeStyle: PropTypes.object,
  autoEscape: PropTypes.bool,
  className: PropTypes.string,
  highlightClassName: PropTypes.string,
  highlightStyle: PropTypes.object,
  highlightTag: PropTypes.oneOfType([
    PropTypes.node,
    PropTypes.func,
    PropTypes.string
  ]),
  sanitize: PropTypes.func,
  searchWords: PropTypes.arrayOf(PropTypes.string).isRequired,
  textToHighlight: PropTypes.string.isRequired,
  unhighlightClassName: PropTypes.string,
  unhighlightStyle: PropTypes.object
}

/**
 * Highlights all occurrences of search terms (searchText) within a string (textToHighlight).
 * This function returns an array of strings and s (wrapping highlighted words).
 */
export default function Highlighter ({
  activeClassName = '',
  activeIndex = -1,
  activeStyle,
  autoEscape,
  caseSensitive = false,
  className,
  highlightClassName = '',
  highlightStyle = {},
  highlightTag = 'mark',
  sanitize,
  searchWords,
  textToHighlight,
  unhighlightClassName = '',
  unhighlightStyle
}) {
  const chunks = findAll({
    autoEscape,
    caseSensitive,
    sanitize,
    searchWords,
    textToHighlight
  })
  const HighlightTag = highlightTag
  let highlightCount = -1
  let highlightClassNames = ''
  let highlightStyles

  return (

      {chunks.map((chunk, index) => {
        const text = textToHighlight.substr(chunk.start, chunk.end - chunk.start)

        if (chunk.highlight) {
          highlightCount++

          const isActive = highlightCount === +activeIndex

          highlightClassNames = `${highlightClassName} ${isActive ? activeClassName : ''}`
          highlightStyles = isActive === true && activeStyle != null
            ? Object.assign({}, highlightStyle, activeStyle)
            : highlightStyle

          return (
            <HighlightTag
              className={highlightClassNames}
              key={index}
              style={highlightStyles}
            >
              {text}
            </HighlightTag>
          )
        } else {
          return (

              {text}

          )
        }
      })}

  )
}
<commit_msg>Added findChunks prop<commit_after>/* @flow */
import { findAll } from 'highlight-words-core'
import PropTypes from 'prop-types'
import React from 'react'

Highlighter.propTypes = {
  activeClassName: PropTypes.string,
  activeIndex: PropTypes.number,
  activeStyle: PropTypes.object,
  autoEscape: PropTypes.bool,
  className: PropTypes.string,
  findChunks: PropTypes.func,
  highlightClassName: PropTypes.string,
  highlightStyle: PropTypes.object,
  highlightTag: PropTypes.oneOfType([
    PropTypes.node,
    PropTypes.func,
    PropTypes.string
  ]),
  sanitize: PropTypes.func,
  searchWords: PropTypes.arrayOf(PropTypes.string).isRequired,
  textToHighlight: PropTypes.string.isRequired,
  unhighlightClassName: PropTypes.string,
  unhighlightStyle: PropTypes.object
}

/**
 * Highlights all occurrences of search terms (searchText) within a string (textToHighlight).
 * This function returns an array of strings and s (wrapping highlighted words).
 */
export default function Highlighter ({
  activeClassName = '',
  activeIndex = -1,
  activeStyle,
  autoEscape,
  caseSensitive = false,
  className,
  findChunks,
  highlightClassName = '',
  highlightStyle = {},
  highlightTag = 'mark',
  sanitize,
  searchWords,
  textToHighlight,
  unhighlightClassName = '',
  unhighlightStyle
}) {
  const chunks = findAll({
    autoEscape,
    caseSensitive,
    findChunks,
    sanitize,
    searchWords,
    textToHighlight
  })
  const HighlightTag = highlightTag
  let highlightCount = -1
  let highlightClassNames = ''
  let highlightStyles

  return (

      {chunks.map((chunk, index) => {
        const text = textToHighlight.substr(chunk.start, chunk.end - chunk.start)

        if (chunk.highlight) {
          highlightCount++

          const isActive = highlightCount === +activeIndex

          highlightClassNames = `${highlightClassName} ${isActive ? activeClassName : ''}`
          highlightStyles = isActive === true && activeStyle != null
            ? Object.assign({}, highlightStyle, activeStyle)
            : highlightStyle

          return (
            <HighlightTag
              className={highlightClassNames}
              key={index}
              style={highlightStyles}
            >
              {text}
            </HighlightTag>
          )
        } else {
          return (

              {text}

          )
        }
      })}

  )
}
<|endoftext|>


<commit_before>/**
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// requires: top
// requires: plugins
// requires: undefined

Ace2Editor.registry = { nextId: 1 };

function Ace2Editor() {
  var thisFunctionsName = "Ace2Editor";
  var ace2 = Ace2Editor;

  var editor = {};
  var info = { editor: editor, id: (ace2.registry.nextId++) };
  var loaded = false;

  var actionsPendingInit = [];
  function pendingInit(func, optDoNow) {
    return function() {
      var that = this;
      var args = arguments;
      function action() {
	func.apply(that, args);
      }
      if (optDoNow) {
	optDoNow.apply(that, args);
      }
      if (loaded) {
	action();
      }
      else {
	actionsPendingInit.push(action);
      }
    };
  }
  function doActionsPendingInit() {
    for(var i=0;i<actionsPendingInit.length;i++) {
      actionsPendingInit[i]();
    }
    actionsPendingInit = [];
  }

  ace2.registry[info.id] = info;

  editor.importText = pendingInit(function(newCode, undoable) {
    info.ace_importText(newCode, undoable); });
  editor.importAText = pendingInit(function(newCode, apoolJsonObj, undoable) {
    info.ace_importAText(newCode, apoolJsonObj, undoable); });
  editor.exportText = function() {
    if (! loaded) return "(awaiting init)\n";
    return info.ace_exportText();
  };
  editor.getFrame = function() { return info.frame || null; };
  editor.focus = pendingInit(function() { info.ace_focus(); });
  editor.adjustSize = pendingInit(function() {
    var frameParent = info.frame.parentNode;
    var parentHeight = frameParent.clientHeight;
    // deal with case where iframe is hidden, no clientHeight
    info.frame.style.height = (parentHeight ? parentHeight+"px" :
			       frameParent.style.height);
    info.ace_editorChangedSize();
  });
  editor.setEditable = pendingInit(function(newVal) { info.ace_setEditable(newVal); });
  editor.getFormattedCode = function() { return info.ace_getFormattedCode(); };
  editor.setOnKeyPress = pendingInit(function (handler) { info.ace_setOnKeyPress(handler); });
  editor.setOnKeyDown = pendingInit(function (handler) { info.ace_setOnKeyDown(handler); });
  editor.setNotifyDirty = pendingInit(function (handler) { info.ace_setNotifyDirty(handler); });

  editor.setProperty = pendingInit(function(key, value) { info.ace_setProperty(key, value); });
  editor.getDebugProperty = function(prop) { return info.ace_getDebugProperty(prop); };

  editor.setBaseText = pendingInit(function(txt) { info.ace_setBaseText(txt); });
  editor.setBaseAttributedText = pendingInit(function(atxt, apoolJsonObj) {
    info.ace_setBaseAttributedText(atxt, apoolJsonObj); });
  editor.applyChangesToBase = pendingInit(function (changes, optAuthor,apoolJsonObj) {
    info.ace_applyChangesToBase(changes, optAuthor, apoolJsonObj); });
  // prepareUserChangeset:
  // Returns null if no new changes or ACE not ready.  Otherwise, bundles up all user changes
  // to the latest base text into a Changeset, which is returned (as a string if encodeAsString).
  // If this method returns a truthy value, then applyPreparedChangesetToBase can be called
  // at some later point to consider these changes part of the base, after which prepareUserChangeset
  // must be called again before applyPreparedChangesetToBase.  Multiple consecutive calls
  // to prepareUserChangeset will return an updated changeset that takes into account the
  // latest user changes, and modify the changeset to be applied by applyPreparedChangesetToBase
  // accordingly.
  editor.prepareUserChangeset = function() {
    if (! loaded) return null;
    return info.ace_prepareUserChangeset();
  };
  editor.applyPreparedChangesetToBase = pendingInit(
    function() { info.ace_applyPreparedChangesetToBase(); });
  editor.setUserChangeNotificationCallback = pendingInit(function(callback) {
    info.ace_setUserChangeNotificationCallback(callback);
  });
  editor.setAuthorInfo = pendingInit(function(author, authorInfo) {
    info.ace_setAuthorInfo(author, authorInfo);
  });
  editor.setAuthorSelectionRange = pendingInit(function(author, start, end) {
    info.ace_setAuthorSelectionRange(author, start, end);
  });

  editor.getUnhandledErrors = function() {
    if (! loaded) return [];
    // returns array of {error: <browser Error object>, time: +new Date()}
    return info.ace_getUnhandledErrors();
  };
  editor.execCommand = pendingInit(function(cmd, arg1) {
    info.ace_execCommand(cmd, arg1);
  });

  // calls to these functions ($$INCLUDE_...)  are replaced when this file is processed
  // and compressed, putting the compressed code from the named file directly into the
  // source here.

  var $$INCLUDE_CSS = function(fileName) {
    return '<link rel="stylesheet" type="text/css" href="'+fileName+'"/>';
  };
  var $$INCLUDE_JS = function(fileName) {
    return '\x3cscript type="text/javascript" src="'+fileName+'">\x3c/script>';
  };
  var $$INCLUDE_JS_DEV = $$INCLUDE_JS;
  var $$INCLUDE_CSS_DEV = $$INCLUDE_CSS;

  var $$INCLUDE_CSS_Q = function(fileName) {
    return '\'<link rel="stylesheet" type="text/css" href="'+fileName+'"/>\'';
  };
  var $$INCLUDE_JS_Q = function(fileName) {
    return '\'\\x3cscript type="text/javascript" src="'+fileName+'">\\x3c/script>\'';
  };
  var $$INCLUDE_JS_Q_DEV = $$INCLUDE_JS_Q;
  var $$INCLUDE_CSS_Q_DEV = $$INCLUDE_CSS_Q;

  editor.destroy = pendingInit(function() {
    info.ace_dispose();
    info.frame.parentNode.removeChild(info.frame);
    delete ace2.registry[info.id];
    info = null; // prevent IE 6 closure memory leaks
  });

  editor.init = function(containerId, initialCode, doneFunc) {

    editor.importText(initialCode);

    info.onEditorReady = function() {
      loaded = true;
      doActionsPendingInit();
      doneFunc();
    };

    (function() {
      var doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '+
	'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';

      var iframeHTML = ["'"+doctype+"'"];

      plugins.callHook(
        "aceInitInnerdocbodyHead", {iframeHTML:iframeHTML});

      // these lines must conform to a specific format because they are passed by the build script:
      iframeHTML.push($$INCLUDE_CSS_Q("editor.css syntax.css inner.css"));
      //iframeHTML.push(INCLUDE_JS_Q_DEV("ace2_common_dev.js"));
      //iframeHTML.push(INCLUDE_JS_Q_DEV("profiler.js"));
      iframeHTML.push($$INCLUDE_JS_Q("ace2_common.js skiplist.js virtual_lines.js easysync2.js cssmanager.js colorutils.js undomodule.js contentcollector.js changesettracker.js linestylefilter.js domline.js"));
      iframeHTML.push($$INCLUDE_JS_Q("ace2_inner.js"));
      iframeHTML.push('\'\\n\\n\'');
      iframeHTML.push('\' \'');

      var outerScript = 'editorId = "'+info.id+'"; editorInfo = parent.'+
	thisFunctionsName+'.registry[editorId]; '+
	'window.onload = function() '+
	'{ window.onload = null; setTimeout'+
	'(function() '+
	'{ var iframe = document.createElement("IFRAME"); '+
	'iframe.scrolling = "no"; var outerdocbody = document.getElementById("outerdocbody"); '+
	'iframe.frameBorder = 0; iframe.allowTransparency = true; '+ // for IE
	'outerdocbody.insertBefore(iframe, outerdocbody.firstChild); '+
	'iframe.ace_outerWin = window; '+
	'readyFunc = function() { editorInfo.onEditorReady(); readyFunc = null; editorInfo = null; }; '+
	'var doc = iframe.contentWindow.document; doc.open(); doc.write('+
	iframeHTML.join('+')+'); doc.close(); '+
	'}, 0); }';

      var outerHTML = [doctype, '',
	$$INCLUDE_CSS("editor.css"),
	// bizarrely, in FF2, a file with no "external" dependencies won't finish loading properly
	// (throbs busy while typing)
	'<link rel="stylesheet" type="text/css" href="data:text/css,"/>',
	'\x3cscript>', outerScript, '\x3c/script>',
	'

x

'];

      var outerFrame = document.createElement("IFRAME");
      outerFrame.frameBorder = 0; // for IE
      info.frame = outerFrame;
      document.getElementById(containerId).appendChild(outerFrame);

      var editorDocument = outerFrame.contentWindow.document;

      editorDocument.open();
      editorDocument.write(outerHTML.join(''));
      editorDocument.close();

      editor.adjustSize();
    })();
  };

  return editor;
}
<commit_msg>Fix IE lacking Array#map. Closes #70<commit_after>/**
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// requires: top
// requires: plugins
// requires: undefined

Ace2Editor.registry = { nextId: 1 };

function Ace2Editor() {
  var thisFunctionsName = "Ace2Editor";
  var ace2 = Ace2Editor;

  var editor = {};
  var info = { editor: editor, id: (ace2.registry.nextId++) };
  var loaded = false;

  var actionsPendingInit = [];
  function pendingInit(func, optDoNow) {
    return function() {
      var that = this;
      var args = arguments;
      function action() {
	func.apply(that, args);
      }
      if (optDoNow) {
	optDoNow.apply(that, args);
      }
      if (loaded) {
	action();
      }
      else {
	actionsPendingInit.push(action);
      }
    };
  }
  function doActionsPendingInit() {
    for(var i=0;i<actionsPendingInit.length;i++) {
      actionsPendingInit[i]();
    }
    actionsPendingInit = [];
  }

  ace2.registry[info.id] = info;

  editor.importText = pendingInit(function(newCode, undoable) {
    info.ace_importText(newCode, undoable); });
  editor.importAText = pendingInit(function(newCode, apoolJsonObj, undoable) {
    info.ace_importAText(newCode, apoolJsonObj, undoable); });
  editor.exportText = function() {
    if (! loaded) return "(awaiting init)\n";
    return info.ace_exportText();
  };
  editor.getFrame = function() { return info.frame || null; };
  editor.focus = pendingInit(function() { info.ace_focus(); });
  editor.adjustSize = pendingInit(function() {
    var frameParent = info.frame.parentNode;
    var parentHeight = frameParent.clientHeight;
    // deal with case where iframe is hidden, no clientHeight
    info.frame.style.height = (parentHeight ? parentHeight+"px" :
			       frameParent.style.height);
    info.ace_editorChangedSize();
  });
  editor.setEditable = pendingInit(function(newVal) { info.ace_setEditable(newVal); });
  editor.getFormattedCode = function() { return info.ace_getFormattedCode(); };
  editor.setOnKeyPress = pendingInit(function (handler) { info.ace_setOnKeyPress(handler); });
  editor.setOnKeyDown = pendingInit(function (handler) { info.ace_setOnKeyDown(handler); });
  editor.setNotifyDirty = pendingInit(function (handler) { info.ace_setNotifyDirty(handler); });

  editor.setProperty = pendingInit(function(key, value) { info.ace_setProperty(key, value); });
  editor.getDebugProperty = function(prop) { return info.ace_getDebugProperty(prop); };

  editor.setBaseText = pendingInit(function(txt) { info.ace_setBaseText(txt); });
  editor.setBaseAttributedText = pendingInit(function(atxt, apoolJsonObj) {
    info.ace_setBaseAttributedText(atxt, apoolJsonObj); });
  editor.applyChangesToBase = pendingInit(function (changes, optAuthor,apoolJsonObj) {
    info.ace_applyChangesToBase(changes, optAuthor, apoolJsonObj); });
  // prepareUserChangeset:
  // Returns null if no new changes or ACE not ready.  Otherwise, bundles up all user changes
  // to the latest base text into a Changeset, which is returned (as a string if encodeAsString).
  // If this method returns a truthy value, then applyPreparedChangesetToBase can be called
  // at some later point to consider these changes part of the base, after which prepareUserChangeset
  // must be called again before applyPreparedChangesetToBase.  Multiple consecutive calls
  // to prepareUserChangeset will return an updated changeset that takes into account the
  // latest user changes, and modify the changeset to be applied by applyPreparedChangesetToBase
  // accordingly.
  editor.prepareUserChangeset = function() {
    if (! loaded) return null;
    return info.ace_prepareUserChangeset();
  };
  editor.applyPreparedChangesetToBase = pendingInit(
    function() { info.ace_applyPreparedChangesetToBase(); });
  editor.setUserChangeNotificationCallback = pendingInit(function(callback) {
    info.ace_setUserChangeNotificationCallback(callback);
  });
  editor.setAuthorInfo = pendingInit(function(author, authorInfo) {
    info.ace_setAuthorInfo(author, authorInfo);
  });
  editor.setAuthorSelectionRange = pendingInit(function(author, start, end) {
    info.ace_setAuthorSelectionRange(author, start, end);
  });

  editor.getUnhandledErrors = function() {
    if (! loaded) return [];
    // returns array of {error: <browser Error object>, time: +new Date()}
    return info.ace_getUnhandledErrors();
  };
  editor.execCommand = pendingInit(function(cmd, arg1) {
    info.ace_execCommand(cmd, arg1);
  });

  // calls to these functions ($$INCLUDE_...)  are replaced when this file is processed
  // and compressed, putting the compressed code from the named file directly into the
  // source here.

  var $$INCLUDE_CSS = function(fileName) {
    return '<link rel="stylesheet" type="text/css" href="'+fileName+'"/>';
  };
  var $$INCLUDE_JS = function(fileName) {
    return '\x3cscript type="text/javascript" src="'+fileName+'">\x3c/script>';
  };
  var $$INCLUDE_JS_DEV = $$INCLUDE_JS;
  var $$INCLUDE_CSS_DEV = $$INCLUDE_CSS;

  var $$INCLUDE_CSS_Q = function(fileName) {
    return '\'<link rel="stylesheet" type="text/css" href="'+fileName+'"/>\'';
  };
  var $$INCLUDE_JS_Q = function(fileName) {
    return '\'\\x3cscript type="text/javascript" src="'+fileName+'">\\x3c/script>\'';
  };
  var $$INCLUDE_JS_Q_DEV = $$INCLUDE_JS_Q;
  var $$INCLUDE_CSS_Q_DEV = $$INCLUDE_CSS_Q;

  editor.destroy = pendingInit(function() {
    info.ace_dispose();
    info.frame.parentNode.removeChild(info.frame);
    delete ace2.registry[info.id];
    info = null; // prevent IE 6 closure memory leaks
  });

  editor.init = function(containerId, initialCode, doneFunc) {

    editor.importText(initialCode);

    info.onEditorReady = function() {
      loaded = true;
      doActionsPendingInit();
      doneFunc();
    };

    (function() {
      var doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '+
	'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';

      var iframeHTML = ["'"+doctype+"'"];

      plugins.callHook(
        "aceInitInnerdocbodyHead", {iframeHTML:iframeHTML});

      // these lines must conform to a specific format because they are passed by the build script:
      iframeHTML.push($$INCLUDE_CSS_Q("editor.css syntax.css inner.css"));
      //iframeHTML.push(INCLUDE_JS_Q_DEV("ace2_common_dev.js"));
      //iframeHTML.push(INCLUDE_JS_Q_DEV("profiler.js"));
      iframeHTML.push($$INCLUDE_JS_Q("ace2_common.js skiplist.js virtual_lines.js easysync2.js cssmanager.js colorutils.js undomodule.js contentcollector.js changesettracker.js linestylefilter.js domline.js"));
      iframeHTML.push($$INCLUDE_JS_Q("ace2_inner.js"));
      iframeHTML.push('\'\\n\\n\'');
      iframeHTML.push('\' \'');

      var outerScript = 'editorId = "'+info.id+'"; editorInfo = parent.'+
	thisFunctionsName+'.registry[editorId]; '+
	'window.onload = function() '+
	'{ window.onload = null; setTimeout'+
	'(function() '+
	'{ var iframe = document.createElement("IFRAME"); '+
	'iframe.scrolling = "no"; var outerdocbody = document.getElementById("outerdocbody"); '+
	'iframe.frameBorder = 0; iframe.allowTransparency = true; '+ // for IE
	'outerdocbody.insertBefore(iframe, outerdocbody.firstChild); '+
	'iframe.ace_outerWin = window; '+
	'readyFunc = function() { editorInfo.onEditorReady(); readyFunc = null; editorInfo = null; }; '+
	'var doc = iframe.contentWindow.document; doc.open(); doc.write('+
	iframeHTML.join('+')+'); doc.close(); '+
	'}, 0); }';

      var outerHTML = [doctype, '',
	$$INCLUDE_CSS("editor.css"),
	// bizarrely, in FF2, a file with no "external" dependencies won't finish loading properly
	// (throbs busy while typing)
	'<link rel="stylesheet" type="text/css" href="data:text/css,"/>',
	'\x3cscript>', outerScript, '\x3c/script>',
	'

x

'];

      if (!Array.prototype.map) Array.prototype.map = function(fun) { //needed for IE
        if (typeof fun != "function") throw new TypeError();
        var len = this.length;
        var res = new Array(len);
        var thisp = arguments[1];
        for (var i = 0; i < len; i++) {
          if (i in this) res[i] = fun.call(thisp, this[i], i, this);
        }
        return res;
      };

      var outerFrame = document.createElement("IFRAME");
      outerFrame.frameBorder = 0; // for IE
      info.frame = outerFrame;
      document.getElementById(containerId).appendChild(outerFrame);

      var editorDocument = outerFrame.contentWindow.document;

      editorDocument.open();
      editorDocument.write(outerHTML.join(''));
      editorDocument.close();

      editor.adjustSize();
    })();
  };

  return editor;
}
<|endoftext|>


<commit_before>"use strict";

var Class = require("nodeclass").Class,
    Nodeclass = Class,
    Collection = require("./Collection.class.js"),
    _ = require("underscore");

var ModelCollection = new Class("ModelCollection", {

    Extends: Collection,

    /**
     * @type {Object}
     * @private
     */
    __listeners: {
        models: [],
        change: [],
        delete: []
    },

    /**
     * @param {String} className
     * @param {Object} descriptor
     * @return {Function}
     */
    $define: function (className, descriptor) {

        descriptor.Extends = ModelCollection;

        return new Nodeclass(className, descriptor);

    },

    /**
     * @param {Class} ModelClass
     * @param {array|Models} models
     *
     * @constructor
     */
    init: function (ModelClass, models) {

        this.Super(ModelClass);

        if (models !== undefined) {
            this.push(models);
        }

    },

    /**
     * @param {number} index
     * @param {Model} model
     * @return {ModelCollection}
     */
    set: function (index, model) {

        var models = this.Super._getElements();

        if (models[index]) {
            this._removeModelListeners(models[index]);
        }
        this._addModelListeners(model);

        this.Super.set(index, model);

        return this.Instance;
    },

    /**
     * @param {Number|Model} modelOrIndex
     * @return {Model}
     */
    remove: function (modelOrIndex) {

        var removeIndex;

        // if given param is an index
        if (typeof modelOrIndex === "number") {
            removeIndex = modelOrIndex;
        } else {
            // if given param is a Model
            _(this.Super._getElements()).find(function findModelIndex(model, index) {
                if (modelOrIndex === model) {
                    removeIndex = index
                    return true;
                }
            });
        }

        return this.Super.remove(removeIndex)

    },

    /**
     * @return {Model}
     */
    pop: function () {
        var poppedModel = this.Super.pop();

        this._removeModelListeners(poppedModel);

        return poppedModel;
    },

    /**
     * @return {Model}
     */
    shift: function () {
        var shiftedModel = this.Super.shift();

        this._removeModelListeners(shiftedModel);

        return shiftedModel;
    },

    /**
     * @param {Model} models
     * @return {ModelCollection}
     */
    push: function (models) {
        var self = this;

        if (_(models).isArray() === false) {
            models = [models];
        }

        _(models).each(function addChangeListener(model) {
            //model.on("change", self.__createChangeListener(model));
            self._addModelListeners(model);
        });

        this.Super.push(models);

        return this.Instance;
    },

    /**
     * @param {Model} models
     * @return {ModelCollection}
     */
    unshift: function (models) {
        var self = this;

        if (_(models).isArray() === false) {
            models = [models];
        }

        _(models).each(function addChangeListener(model) {
            self._addModelListeners(model);
        });

        this.Super.unshift(models);

        return this.Instance;
    },

    /**
     * @param {string} modelAttribute
     * @param {boolean} descending (optional)
     * @return {ModelCollection}
     */
    sortBy: function (modelAttribute, descending) {
        var elements = this.Super._getElements();

        if (elements[0].get(modelAttribute) === undefined) {
            throw new Error(
                "(alamid) Unable to sort by " + modelAttribute + "." +
                "Models do not have an attribute called " + modelAttribute + "."
            );
        }

        elements = _(elements).sortBy(function sortModelBy(model, index) {
            return model.get(modelAttribute);
        });

        if (descending === true) {
            elements.reverse();
        }

        this.Super._setElements(elements);

        this.Super.emit("sort");

        return this.Instance;
    },

    /**
     * Prepares all Collection-Models for Garbage-Collector
     */
    dispose: function () {

        var models = this.Super._getElements(),
            self = this;

        this.Super.removeAllListeners();
        _(models).each(function removeAllAddedListeners(model) {
            self._removeModelListeners(model);
        });

        this.Super._setElements(null);
    },

    /**
     * @param {Model} model
     * @return {Function}
     * @private
     */
    __createChangeListener: function (model) {
        var self = this;

        function changeListener() {
            self.Super.emit("change", model);
        }

        this.__changeListenersModels.push(model);
        this.__changeListeners.push(changeListener);

        return changeListener;
    },

    /**
     * @param {Model} model
     * @return {Function}
     * @private
     */
    _createChangeListener: function (model) {

        var self = this;

        function onChange() {
            self.Super.emit("change", model);
        }

        return onChange;

    },

    /**
     * @param {Model} model
     * @return {Function}
     * @private
     */
    _createDeleteListener: function (model) {

        var self = this;

        function onDelete(err) {
            var models;

            if(!err) {

                models = self.Super._getElements();

                _(models).find(function findModelInCollection(collectionModel, index) {

                    if (collectionModel === model) {
                        self.Super.remove(index);
                        //@TODO https://github.com/peerigon/alamid/issues/109
                        model.removeListener("delete", onDelete);
                        return true;
                    }

                });

            }

        }

        return onDelete;

    },

    /**
     * @param {Model} model
     * @private
     */
    _addModelListeners: function (model) {

        var onChange = this._createChangeListener(model),
            onDelte = this._createDeleteListener(model);

        model.on("change", onChange);
        model.on("delete", onDelte);

        this.__listeners.models.push(model);
        this.__listeners.change.push(onChange);
        this.__listeners.delete.push(onDelte);

    },

    /**
     * @param {model}
     * @private
     */
    _removeModelListeners: function (model) {

        var listenerModelIndex,
            listenerModels = this.__listeners.models;

        _(listenerModels).find(function findModelIndex(listenerModel, index) {
            if (listenerModel === model) {
                listenerModelIndex = index;
                return true;
            }
        });

        model.removeListener("change", this.__listeners.change[listenerModelIndex]);
        model.removeListener("delete", this.__listeners.change[listenerModelIndex]);

    }

});

module.exports = ModelCollection;<commit_msg>- tidy<commit_after>"use strict";

var Class = require("nodeclass").Class,
    Nodeclass = Class,
    Collection = require("./Collection.class.js"),
    _ = require("underscore");

var ModelCollection = new Class("ModelCollection", {

    Extends: Collection,

    /**
     * @type {Object}
     * @private
     */
    __listeners: {
        models: [],
        change: [],
        delete: []
    },

    /**
     * @param {String} className
     * @param {Object} descriptor
     * @return {Function}
     */
    $define: function (className, descriptor) {

        descriptor.Extends = ModelCollection;

        return new Nodeclass(className, descriptor);

    },

    /**
     * @param {Class} ModelClass
     * @param {array|Models} models
     *
     * @constructor
     */
    init: function (ModelClass, models) {

        this.Super(ModelClass);

        if (models !== undefined) {
            this.push(models);
        }

    },

    /**
     * @param {number} index
     * @param {Model} model
     * @return {ModelCollection}
     */
    set: function (index, model) {

        var models = this.Super._getElements();

        if (models[index]) {
            this._removeModelListeners(models[index]);
        }
        this._addModelListeners(model);

        this.Super.set(index, model);

        return this.Instance;
    },

    /**
     * @param {Number|Model} modelOrIndex
     * @return {Model}
     */
    remove: function (modelOrIndex) {

        var removeIndex;

        // if given param is an index
        if (typeof modelOrIndex === "number") {
            removeIndex = modelOrIndex;
        } else {
            // if given param is a Model
            _(this.Super._getElements()).find(function findModelIndex(model, index) {
                if (modelOrIndex === model) {
                    removeIndex = index
                    return true;
                }
            });
        }

        return this.Super.remove(removeIndex)

    },

    /**
     * @return {Model}
     */
    pop: function () {
        var poppedModel = this.Super.pop();

        this._removeModelListeners(poppedModel);

        return poppedModel;
    },

    /**
     * @return {Model}
     */
    shift: function () {
        var shiftedModel = this.Super.shift();

        this._removeModelListeners(shiftedModel);

        return shiftedModel;
    },

    /**
     * @param {Model} models
     * @return {ModelCollection}
     */
    push: function (models) {
        var self = this;

        if (_(models).isArray() === false) {
            models = [models];
        }

        _(models).each(function addChangeListener(model) {
            //model.on("change", self.__createChangeListener(model));
            self._addModelListeners(model);
        });

        this.Super.push(models);

        return this.Instance;
    },

    /**
     * @param {Model} models
     * @return {ModelCollection}
     */
    unshift: function (models) {
        var self = this;

        if (_(models).isArray() === false) {
            models = [models];
        }

        _(models).each(function addChangeListener(model) {
            self._addModelListeners(model);
        });

        this.Super.unshift(models);

        return this.Instance;
    },

    /**
     * @param {string} modelAttribute
     * @param {boolean} descending (optional)
     * @return {ModelCollection}
     */
    sortBy: function (modelAttribute, descending) {
        var elements = this.Super._getElements();

        if (elements[0].get(modelAttribute) === undefined) {
            throw new Error(
                "(alamid) Unable to sort by " + modelAttribute + "." +
                "Models do not have an attribute called " + modelAttribute + "."
            );
        }

        elements = _(elements).sortBy(function sortModelBy(model, index) {
            return model.get(modelAttribute);
        });

        if (descending === true) {
            elements.reverse();
        }

        this.Super._setElements(elements);

        this.Super.emit("sort");

        return this.Instance;
    },

    /**
     * Prepares all Collection-Models for Garbage-Collector
     */
    dispose: function () {

        var models = this.Super._getElements(),
            self = this;

        this.Super.removeAllListeners();
        _(models).each(function removeAllAddedListeners(model) {
            self._removeModelListeners(model);
        });

        this.Super._setElements(null);
    },

    /**
     * @param {Model} model
     * @return {Function}
     * @private
     */
    __createChangeListener: function (model) {
        var self = this;

        function changeListener() {
            self.Super.emit("change", model);
        }

        this.__changeListenersModels.push(model);
        this.__changeListeners.push(changeListener);

        return changeListener;
    },

    /**
     * @param {Model} model
     * @return {Function}
     * @private
     */
    _createChangeListener: function (model) {

        var self = this;

        function onChange() {
            self.Super.emit("change", model);
        }

        return onChange;

    },

    /**
     * @param {Model} model
     * @return {Function}
     * @private
     */
    _createDeleteListener: function (model) {

        var self = this;

        function onDelete(err) {
            if(!err) {
                _(self.Super._getElements()).find(function findModelInCollection(collectionModel, index) {

                    if (collectionModel === model) {
                        self.Super.remove(index);
                        //@TODO https://github.com/peerigon/alamid/issues/109
                        model.removeListener("delete", onDelete);
                        return true;
                    }

                });
            }
        }

        return onDelete;

    },

    /**
     * @param {Model} model
     * @private
     */
    _addModelListeners: function (model) {

        var onChange = this._createChangeListener(model),
            onDelte = this._createDeleteListener(model);

        model.on("change", onChange);
        model.on("delete", onDelte);

        this.__listeners.models.push(model);
        this.__listeners.change.push(onChange);
        this.__listeners.delete.push(onDelte);

    },

    /**
     * @param {model}
     * @private
     */
    _removeModelListeners: function (model) {

        var listenerModelIndex,
            listenerModels = this.__listeners.models;

        _(listenerModels).find(function findModelIndex(listenerModel, index) {
            if (listenerModel === model) {
                listenerModelIndex = index;
                return true;
            }
        });

        model.removeListener("change", this.__listeners.change[listenerModelIndex]);
        model.removeListener("delete", this.__listeners.change[listenerModelIndex]);

    }

});

module.exports = ModelCollection;<|endoftext|>


<commit_before>String.prototype.trunc = String.prototype.trunc ||
      function(n){
          return this.length>n ? this.substr(0,n-1)+'…' : this;
      };

client = {
	init : function() {
        /*
         * Initialize the server setting
         */
        var srch2ServerSetting = {
            serverUrl : "/srch2/", // use your own server URL
            debug : false, // enable the debug mode which will display debug messages to the console.
                          // IE may not have "console.log" function. If you are using IE, please set it to false.
        };
        srch2.init(srch2ServerSetting);    // Initialize server
        srch2.setSearchType("getAll");     // Set the search type to "getAll"
        srch2.setEnablePrefixSearch(true); // Enable prefix search
        srch2.setEnableFuzzySearch(true);  // Enable fuzzy search
        this.bindInput(); // bind input events to a function
    },
	/*
	* Bind the input box "query_box" key up event with
	* a function which sending the query to the server.
	*/
   bindInput : function() {
	   var element = document.getElementById("search-query");
	   this.bindEvent(element, "keyup", function(event) {
		   if (event.keyCode == 13) {
			   return;
		   }
		   var query = client.sendQuery();
	   });
   },
   /*
     * Bind the event "type" to the HTTP element "element".
     * If the "type" event is triggered, call the function "handler".
     */
    bindEvent : function(element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else {
            element.attachEvent('on' + type, handler);
        }
    },
	/*
     * This function gets the keyword query from the "query_box"
     * and sends the query to the server. The response
     * will trigger the function "this.responseHandler".
     */
    sendQuery : function() {
        var query = document.getElementById('search-query').value;
        srch2.sendQuery(query, this.responseHandler);
    },

    /*
     * "responseHandler" is called after we get the server response.
     * The "responseText" contains all the results in JSON format.
     */
    responseHandler : function(responseText) {
        if (responseText) {
            var output = "";
            var results = responseText.results;
            client.queryKeywords = responseText.query_keywords;
            for (var i = 0; i < results.length; i++) {
                output += "
";
                var record = results[i].record;
                var prefix = results[i].matching_prefix;
                output += "
" + client.addHighlighting(prefix, record.official_title) + "
";
				output += "
" + client.addHighlighting(prefix, record.detailed_description.trunc(500)) + "
";
                output += "
";
            }
            // client.log("got it", "debug");
            // client.log(JSON.stringify(responseText), "debug");
            var element = document.getElementById("search-result");
            if (output == "") {
                element.innerHTML = "No results mate!";
            } else {
                element.innerHTML = output;
            }
        } else {
            var element = document.getElementById("search-result");
            element.innerHTML = "No results mate!";
            client.log("empty response", "debug");
        }
    },

    /*
     * Highlight the prefix in the search results.
     */
    addHighlighting : function(prefix, input) {
        if (input) {
            input = input.toString();
            var words = input.split(/[ ]+/);
            // split by space
            var output = "";
            for (var wordIndex in words) {
                var word = words[wordIndex];
                var tempWord = word.toLocaleLowerCase();
                var match = this.regexMatch(prefix, word);
                var space = "";
                if (wordIndex > 0) {
                    space = " ";
                }
                if (match.success) {
                    var first_part = match.first;
                    var second_part = match.second;
                    var classStr = match.class;
                    output += space + "" + first_part + "" + second_part;
                } else {
                    output += space + word;
                }
            }
            return output;
        }
        return input;
    },
    regexMatch : function(prefixArray, word) {
        var prefixStr = prefixArray.join("|^");
        var re = new RegExp('^' + prefixStr, 'i');
        var m = re.exec(word);
        var returnObj = {};
        if (m == null) {
            this.log("no match", "debug");
            returnObj.success = false;
            return returnObj;
        } else {
            var first_part = word.substring(0, m[0].length);
            var second_part = word.substring(m[0].length);
            returnObj.success = true;
            returnObj.first = first_part;
            returnObj.second = second_part;
            returnObj.matched = m[0];

            if (this.findPrefix(this.queryKeywords, returnObj.matched)) {
                // exact
                if (word.length == m[0].length) {
                    // exact complete
                    returnObj.class = 'exact_complete';
                } else {
                    // exact prefix
                    returnObj.class = 'exact_prefix';
                }
            } else {
                // fuzzy
                if (word.length == m[0].length) {
                    // fuzzy complete
                    returnObj.class = 'fuzzy_complete';
                } else {
                    // fuzzy prefix
                    returnObj.class = 'fuzzy_prefix';
                }
            }
            return returnObj; facet_remove_filter
        }
    },
    findPrefix : function(keywords, prefix) {
        prefix = prefix.toLocaleLowerCase();
        for (var index in keywords) {
            if (keywords[index].localeCompare(prefix) == 0) {
                return true
            }
        }
        return false;
    },

    log : function(msg, debug) {
        /*
         Handy debug function. Use this function instead of alert or console.log
         */
        if (debug == "debug") {
            console.log(msg);
        }
    },
}
<commit_msg>use brief title as search result title in fuzzy search<commit_after>String.prototype.trunc = String.prototype.trunc ||
      function(n){
          return this.length>n ? this.substr(0,n-1)+'…' : this;
      };

client = {
	init : function() {
        /*
         * Initialize the server setting
         */
        var srch2ServerSetting = {
            serverUrl : "/srch2/", // use your own server URL
            debug : false, // enable the debug mode which will display debug messages to the console.
                          // IE may not have "console.log" function. If you are using IE, please set it to false.
        };
        srch2.init(srch2ServerSetting);    // Initialize server
        srch2.setSearchType("getAll");     // Set the search type to "getAll"
        srch2.setEnablePrefixSearch(true); // Enable prefix search
        srch2.setEnableFuzzySearch(true);  // Enable fuzzy search
        this.bindInput(); // bind input events to a function
    },
	/*
	* Bind the input box "query_box" key up event with
	* a function which sending the query to the server.
	*/
   bindInput : function() {
	   var element = document.getElementById("search-query");
	   this.bindEvent(element, "keyup", function(event) {
		   if (event.keyCode == 13) {
			   return;
		   }
		   var query = client.sendQuery();
	   });
   },
   /*
     * Bind the event "type" to the HTTP element "element".
     * If the "type" event is triggered, call the function "handler".
     */
    bindEvent : function(element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else {
            element.attachEvent('on' + type, handler);
        }
    },
	/*
     * This function gets the keyword query from the "query_box"
     * and sends the query to the server. The response
     * will trigger the function "this.responseHandler".
     */
    sendQuery : function() {
        var query = document.getElementById('search-query').value;
        srch2.sendQuery(query, this.responseHandler);
    },

    /*
     * "responseHandler" is called after we get the server response.
     * The "responseText" contains all the results in JSON format.
     */
    responseHandler : function(responseText) {
        if (responseText) {
            var output = "";
            var results = responseText.results;
            client.queryKeywords = responseText.query_keywords;
            for (var i = 0; i < results.length; i++) {
                output += "
";
                var record = results[i].record;
                var prefix = results[i].matching_prefix;
                output += "
" + client.addHighlighting(prefix, record.brief_title) + "
";
				output += "
" + client.addHighlighting(prefix, record.detailed_description.trunc(500)) + "
";
                output += "
";
            }
            // client.log("got it", "debug");
            // client.log(JSON.stringify(responseText), "debug");
            var element = document.getElementById("search-result");
            if (output == "") {
                element.innerHTML = "No results mate!";
            } else {
                element.innerHTML = output;
            }
        } else {
            var element = document.getElementById("search-result");
            element.innerHTML = "No results mate!";
            client.log("empty response", "debug");
        }
    },

    /*
     * Highlight the prefix in the search results.
     */
    addHighlighting : function(prefix, input) {
        if (input) {
            input = input.toString();
            var words = input.split(/[ ]+/);
            // split by space
            var output = "";
            for (var wordIndex in words) {
                var word = words[wordIndex];
                var tempWord = word.toLocaleLowerCase();
                var match = this.regexMatch(prefix, word);
                var space = "";
                if (wordIndex > 0) {
                    space = " ";
                }
                if (match.success) {
                    var first_part = match.first;
                    var second_part = match.second;
                    var classStr = match.class;
                    output += space + "" + first_part + "" + second_part;
                } else {
                    output += space + word;
                }
            }
            return output;
        }
        return input;
    },
    regexMatch : function(prefixArray, word) {
        var prefixStr = prefixArray.join("|^");
        var re = new RegExp('^' + prefixStr, 'i');
        var m = re.exec(word);
        var returnObj = {};
        if (m == null) {
            this.log("no match", "debug");
            returnObj.success = false;
            return returnObj;
        } else {
            var first_part = word.substring(0, m[0].length);
            var second_part = word.substring(m[0].length);
            returnObj.success = true;
            returnObj.first = first_part;
            returnObj.second = second_part;
            returnObj.matched = m[0];

            if (this.findPrefix(this.queryKeywords, returnObj.matched)) {
                // exact
                if (word.length == m[0].length) {
                    // exact complete
                    returnObj.class = 'exact_complete';
                } else {
                    // exact prefix
                    returnObj.class = 'exact_prefix';
                }
            } else {
                // fuzzy
                if (word.length == m[0].length) {
                    // fuzzy complete
                    returnObj.class = 'fuzzy_complete';
                } else {
                    // fuzzy prefix
                    returnObj.class = 'fuzzy_prefix';
                }
            }
            return returnObj; facet_remove_filter
        }
    },
    findPrefix : function(keywords, prefix) {
        prefix = prefix.toLocaleLowerCase();
        for (var index in keywords) {
            if (keywords[index].localeCompare(prefix) == 0) {
                return true
            }
        }
        return false;
    },

    log : function(msg, debug) {
        /*
         Handy debug function. Use this function instead of alert or console.log
         */
        if (debug == "debug") {
            console.log(msg);
        }
    },
}
<|endoftext|>