<commit_before>//@flow
import { objectPropertyTypes } from '../Meta';
import { dateHelpers } from 'utils';
import EditableGridFieldView from './views/EditableGridFieldView';
import SimplifiedFieldView from '../form/fields/SimplifiedFieldView';
import DateTimeService from '../form/editors/services/DateTimeService';

let factory;

type CellExtention = {
    templateContext(): Object
};

type Column = { key: string, columnClass: string, editable: boolean, type: string, dataType: string, format: string }; //todo wtf datatype

export default (factory = {
    getCellViewForColumn(column: Column, model: Backbone.Model) {
        if (column.editable) {
            return column.simplified ? SimplifiedFieldView : EditableGridFieldView;
        }

        return factory.getCellHtml(column, model);
    },

    getCellViewByDataType(type: string) {
        //Used by Product server Grid
        let result;

        switch (type) {
            case objectPropertyTypes.STRING:
                result = factory.getTextCellView();
                break;
            case objectPropertyTypes.INSTANCE:
                result = factory.getReferenceCellView();
                break;
            case objectPropertyTypes.ACCOUNT:
                result = factory.getUserCellView();
                break;
            case objectPropertyTypes.ENUM:
                result = factory.getEnumCellView();
                break;
            case objectPropertyTypes.INTEGER:
            case objectPropertyTypes.DOUBLE:
            case objectPropertyTypes.DECIMAL:
                result = factory.getNumberCellView();
                break;
            case objectPropertyTypes.DURATION:
                result = factory.getDurationCellView();
                break;
            case objectPropertyTypes.BOOLEAN:
                result = factory.getBooleanCellView();
                break;
            case objectPropertyTypes.DATETIME:
                result = factory.getDateTimeCellView();
                break;
            case objectPropertyTypes.DOCUMENT:
                result = factory.getDocumentCellView();
                break;
            default:
                result = factory.getHtmlCellView();
                break;
        }

        return result;
    },

    getTextCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return factory.__getSimpleView('{{highlightFragment value highlightedFragment}}', extention);
    },

    getReferenceCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return factory.__getSimpleView('{{#if value}}{{#if value.name}}{{highlightFragment value.name highlightedFragment}}{{/if}}{{/if}}', extention);
    },

    getUserCellView() {
        return factory.__getAccountView();
    },

    getEnumCellView() {
        return factory.__getEnumView();
    },

    getNumberCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return factory.__getSimpleView('{{value}}', extention);
    },

    getDurationCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return factory.__getSimpleView('{{renderShortDuration value}}', extention);
    },

    getBooleanCellView() {
        const extention = {
            templateContext() {
                const value = this.model.get(this.options.key);
                return {
                    value,
                    showIcon: _.isBoolean(value)
                };
            }
        };

        return factory.__getSimpleView(
            '{{#if showIcon}}' +
            '{{#if value}}<svg class="svg-grid-icons svg-icons_flag-yes"><use xlink:href="#icon-checked"></use></svg>{{/if}}' +
            '{{#unless value}}<svg class="svg-grid-icons svg-icons_flag-none"><use xlink:href="#icon-remove"></use></svg>{{/unless}}' +
            '{{/if}}',
            extention
        );
    },

    getDateTimeCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return factory.__getSimpleView('{{#if value}}{{renderFullDateTime value}}{{/if}}', extention);
    },

    getDocumentCellView() {
        return factory.__getDocumentView();
    },

    __getSimpleView(simpleTemplate: string, extention: CellExtention) {
        return Marionette.View.extend({
            template: Handlebars.compile(simpleTemplate),
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange',
                highlighted: '__handleHighlightedFragmentChange',
                unhighlighted: '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange() {
                this.render();
            },
            className: 'grid-cell',
            templateContext: extention.templateContext
        });
    },

    __getAccountView() {
        return Marionette.View.extend({
            template: Handlebars.compile('{{text}}'),
            templateContext() {
                const value = this.model.get(this.options.key);
                let text = '';
                if (value && value.length > 0) {
                    text = _.chain(value)
                        .map(item => ({
                            id: item.id,
                            text: item.text || item.name || (item.columns && item.columns[0])
                        }))
                        .sortBy(member => member.text)
                        .reduce((memo, member) => {
                            if (memo) {
                                return `${memo}, ${member.text}`;
                            }
                            return member.text;
                        }, null)
                        .value();
                } else if (value && value.name) {
                    text = value.name;
                }

                return {
                    text
                };
            },
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange() {
                this.render();
            },
            className: 'grid-cell'
        });
    },

    __getDocumentView() {
        return Marionette.View.extend({
            template: Handlebars.compile('{{#each documents}}{{text}}{{#unless @last}}, {{/unless}}{{/each}}'),

            templateContext() {
                const value = this.model.get(this.options.key);
                let documents = [];
                if (value && value.length > 0) {
                    documents = value
                        .map(item => ({
                            id: item.id,
                            text: item.text || item.name || (item.columns && item.columns[0]),
                            url: item.url || (item.columns && item.columns[1])
                        }))
                        .sort((a, b) => a.text > b.text);
                }

                return {
                    documents
                };
            },
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange() {
                this.render();
            },
            className: 'grid-cell'
        });
    },

    __getEnumView() {
        return Marionette.View.extend({
            template: Handlebars.compile('{{#if value}}{{valueExplained}}{{/if}}'),
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange() {
                this.render();
            },
            templateContext() {
                const value = this.model.get(this.options.key);
                return {
                    value,
                    valueExplained: value.valueExplained
                };
            },
            className: 'grid-cell'
        });
    },

    getHtmlCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return this.__getSimpleView('{{{value}}}', extention);
    },

    getCellHtml(column: Column, model: Backbone.Model) {
        const value = model.get(column.key);

        if (value === null || value === undefined) {
            return `<div class="cell ${column.columnClass}"></div>`;
        }
        let adjustedValue = value;

        switch (column.dataType || column.type) {
            case objectPropertyTypes.STRING:
                adjustedValue = this.__adjustValue(value);
                return `<div class="cell ${column.columnClass}" title="${column.format === 'HTML' ? '' : adjustedValue}">${adjustedValue}</div>`;
            case objectPropertyTypes.INSTANCE:
                if (Array.isArray(value)) {
                    adjustedValue = value.map(v => v && v.name).join(', ');
                } else if (value && value.name) {
                    adjustedValue = value.name;
                }
                return `<div class="cell ${column.columnClass}" title="${adjustedValue || ''}">${adjustedValue || ''}</div>`;
            case objectPropertyTypes.ACCOUNT:
                if (value.length > 0) {
                    adjustedValue = value
                        .map(item => ({
                            id: item.id,
                            text: item.text || item.name || (item.columns && item.columns[0])
                        }))
                        .sort((a, b) => a.text > b.text)
                        .reduce((memo, member) => {
                            if (memo) {
                                return `${memo}, ${member.text}`;
                            }
                            return member.text;
                        }, null);
                    return `<div class="cell ${column.columnClass}" title="${adjustedValue} || ''">${adjustedValue}</div>`;
                } else if (value.name) {
                    return `<div class="cell ${column.columnClass}" title="${value.name}">${value.name}</div>`;
                }
            case objectPropertyTypes.ENUM:
                adjustedValue = value ? value.valueExplained : '';
                return `<div class="cell ${column.columnClass}" title="${adjustedValue}">${adjustedValue}</div>`;
            case objectPropertyTypes.INTEGER:
            case objectPropertyTypes.DOUBLE:
            case objectPropertyTypes.DECIMAL:
                adjustedValue = Array.isArray(value) ? value : [value];
                adjustedValue = adjustedValue
                    .map(v => {
                        if (!v) {
                            return '';
                        }
                        if (column.formatOptions) {
                            if (column.formatOptions.format) {
                                return new Intl.NumberFormat(Localizer.langCode, {
                                    minimumIntegerDigits: 1,
                                    minimumFractionDigits: 2
                                }).format(value);
                            } else if (column.formatOptions.allowFloat === false) {
                                return Math.floor(v);
                            }
                        }
                        return value;
                    }).join(', ');
                return `<div class="cell cell-right ${column.columnClass}" title="${adjustedValue}">${adjustedValue}</div>`;
            case objectPropertyTypes.DURATION: {
                adjustedValue = Array.isArray(value) ? value : [value];
                adjustedValue = adjustedValue
                    .map(v => {
                        const defaultOptions = {
                            allowDays: true,
                            allowHours: true,
                            allowMinutes: true,
                            allowSeconds: true
                        };
                        const options = Object.assign(defaultOptions, _.pick(column.formatOptions || {}, Object.keys(defaultOptions)));
                        let result = '';
                        if (value === 0) {
                            return '0';
                        }
                        if (!value) {
                            return '';
                        }

                        const duration = dateHelpers.durationISOToObject(value);
                        if (options.allowDays) {
                            result += `${duration.days + Localizer.get('CORE.FORM.EDITORS.DURATION.WORKDURATION.DAYS')} `;
                        }
                        if (options.allowHours) {
                            result += `${duration.hours + Localizer.get('CORE.FORM.EDITORS.DURATION.WORKDURATION.HOURS')} `;
                        }
                        if (options.allowMinutes) {
                            result += `${duration.minutes + Localizer.get('CORE.FORM.EDITORS.DURATION.WORKDURATION.MINUTES')} `;
                        }
                        if (options.allowSeconds) {
                            result += `${duration.seconds + Localizer.get('CORE.FORM.EDITORS.DURATION.WORKDURATION.SECONDS')} `;
                        }
                        return result;
                    })
                    .join(', ')
                    .trim();

                return `<div class="cell ${column.columnClass}" title="${adjustedValue}">${adjustedValue}</div>`;
            }
            case objectPropertyTypes.BOOLEAN:
                adjustedValue = Array.isArray(value) ? value : [value || ''];
                adjustedValue = adjustedValue
                    .map(v => {
                        let result = '';
                        if (v === true) {
                            result = '<svg class="svg-grid-icons svg-icons_flag-yes"><use xlink:href="#icon-checked"></use></svg>';
                        } else if (v === false) {
                            result = '<svg class="svg-grid-icons svg-icons_flag-none"><use xlink:href="#icon-remove"></use></svg>';
                        }
                        return result;
                    })
                    .join(', ');
                return `<div class="cell ${column.columnClass}">${adjustedValue}</div>`;
            case objectPropertyTypes.DATETIME:
                adjustedValue = Array.isArray(value) ? value : [value];
                adjustedValue = adjustedValue
                    .map(v => {
                        if (column.formatOptions) {
                            const dateDisplayValue = column.formatOptions.dateDisplayFormat ? DateTimeService.getDateDisplayValue(v, column.formatOptions.dateDisplayFormat) : '';
                            const timeDisplayValue = column.formatOptions.timeDisplayFormat ? DateTimeService.getTimeDisplayValue(v, column.formatOptions.timeDisplayFormat) : '';
                            return `${dateDisplayValue} ${timeDisplayValue}`;
                        }
                        return dateHelpers.dateToDateTimeString(v, 'generalDateShortTime');
                    }).join(', ');
                return `<div class="cell ${column.columnClass}" title="${adjustedValue}">${adjustedValue}</div>`;
            case objectPropertyTypes.DOCUMENT:
                if (value.length > 0) {
                    return `
${value
                        .map(item => {
                            const text = item.text || item.name || (item.columns && item.columns[0]);
                            const url = item.url || (item.columns && item.columns[1]);
                            return `<a href="${url}" target="_blank" title="${text}">${text}</a>`;
                        })
                        .sort((a, b) => a.text > b.text)
                        .join(', ')}
`;
                }
            default:
                adjustedValue = this.__adjustValue(value);
                return `<div class="cell ${column.columnClass}">${adjustedValue || ''}</div>`;
        }
    },

    __adjustValue(value: Array<string | number> | string) {
        if (Array.isArray(value)) {
            return value.join(', ');
        }
        return value;
    }
});
<commit_msg>Fix currency<commit_after>//@flow
import { objectPropertyTypes } from '../Meta';
import { dateHelpers } from 'utils';
import EditableGridFieldView from './views/EditableGridFieldView';
import SimplifiedFieldView from '../form/fields/SimplifiedFieldView';
import DateTimeService from '../form/editors/services/DateTimeService';

let factory;

type CellExtention = {
    templateContext(): Object
};

type Column = { key: string, columnClass: string, editable: boolean, type: string, dataType: string, format: string }; //todo wtf datatype

export default (factory = {
    getCellViewForColumn(column: Column, model: Backbone.Model) {
        if (column.editable) {
            return column.simplified ? SimplifiedFieldView : EditableGridFieldView;
        }

        return factory.getCellHtml(column, model);
    },

    getCellViewByDataType(type: string) {
        //Used by Product server Grid
        let result;

        switch (type) {
            case objectPropertyTypes.STRING:
                result = factory.getTextCellView();
                break;
            case objectPropertyTypes.INSTANCE:
                result = factory.getReferenceCellView();
                break;
            case objectPropertyTypes.ACCOUNT:
                result = factory.getUserCellView();
                break;
            case objectPropertyTypes.ENUM:
                result = factory.getEnumCellView();
                break;
            case objectPropertyTypes.INTEGER:
            case objectPropertyTypes.DOUBLE:
            case objectPropertyTypes.DECIMAL:
                result = factory.getNumberCellView();
                break;
            case objectPropertyTypes.DURATION:
                result = factory.getDurationCellView();
                break;
            case objectPropertyTypes.BOOLEAN:
                result = factory.getBooleanCellView();
                break;
            case objectPropertyTypes.DATETIME:
                result = factory.getDateTimeCellView();
                break;
            case objectPropertyTypes.DOCUMENT:
                result = factory.getDocumentCellView();
                break;
            default:
                result = factory.getHtmlCellView();
                break;
        }

        return result;
    },

    getTextCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return factory.__getSimpleView('{{highlightFragment value highlightedFragment}}', extention);
    },

    getReferenceCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return factory.__getSimpleView('{{#if value}}{{#if value.name}}{{highlightFragment value.name highlightedFragment}}{{/if}}{{/if}}', extention);
    },

    getUserCellView() {
        return factory.__getAccountView();
    },

    getEnumCellView() {
        return factory.__getEnumView();
    },

    getNumberCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return factory.__getSimpleView('{{value}}', extention);
    },

    getDurationCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return factory.__getSimpleView('{{renderShortDuration value}}', extention);
    },

    getBooleanCellView() {
        const extention = {
            templateContext() {
                const value = this.model.get(this.options.key);
                return {
                    value,
                    showIcon: _.isBoolean(value)
                };
            }
        };

        return factory.__getSimpleView(
            '{{#if showIcon}}' +
            '{{#if value}}<svg class="svg-grid-icons svg-icons_flag-yes"><use xlink:href="#icon-checked"></use></svg>{{/if}}' +
            '{{#unless value}}<svg class="svg-grid-icons svg-icons_flag-none"><use xlink:href="#icon-remove"></use></svg>{{/unless}}' +
            '{{/if}}',
            extention
        );
    },

    getDateTimeCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return factory.__getSimpleView('{{#if value}}{{renderFullDateTime value}}{{/if}}', extention);
    },

    getDocumentCellView() {
        return factory.__getDocumentView();
    },

    __getSimpleView(simpleTemplate: string, extention: CellExtention) {
        return Marionette.View.extend({
            template: Handlebars.compile(simpleTemplate),
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange',
                highlighted: '__handleHighlightedFragmentChange',
                unhighlighted: '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange() {
                this.render();
            },
            className: 'grid-cell',
            templateContext: extention.templateContext
        });
    },

    __getAccountView() {
        return Marionette.View.extend({
            template: Handlebars.compile('{{text}}'),
            templateContext() {
                const value = this.model.get(this.options.key);
                let text = '';
                if (value && value.length > 0) {
                    text = _.chain(value)
                        .map(item => ({
                            id: item.id,
                            text: item.text || item.name || (item.columns && item.columns[0])
                        }))
                        .sortBy(member => member.text)
                        .reduce((memo, member) => {
                            if (memo) {
                                return `${memo}, ${member.text}`;
                            }
                            return member.text;
                        }, null)
                        .value();
                } else if (value && value.name) {
                    text = value.name;
                }

                return {
                    text
                };
            },
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange() {
                this.render();
            },
            className: 'grid-cell'
        });
    },

    __getDocumentView() {
        return Marionette.View.extend({
            template: Handlebars.compile('{{#each documents}}{{text}}{{#unless @last}}, {{/unless}}{{/each}}'),

            templateContext() {
                const value = this.model.get(this.options.key);
                let documents = [];
                if (value && value.length > 0) {
                    documents = value
                        .map(item => ({
                            id: item.id,
                            text: item.text || item.name || (item.columns && item.columns[0]),
                            url: item.url || (item.columns && item.columns[1])
                        }))
                        .sort((a, b) => a.text > b.text);
                }

                return {
                    documents
                };
            },
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange() {
                this.render();
            },
            className: 'grid-cell'
        });
    },

    __getEnumView() {
        return Marionette.View.extend({
            template: Handlebars.compile('{{#if value}}{{valueExplained}}{{/if}}'),
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange() {
                this.render();
            },
            templateContext() {
                const value = this.model.get(this.options.key);
                return {
                    value,
                    valueExplained: value.valueExplained
                };
            },
            className: 'grid-cell'
        });
    },

    getHtmlCellView() {
        const extention = {
            templateContext() {
                return {
                    value: this.model.get(this.options.key)
                };
            }
        };
        return this.__getSimpleView('{{{value}}}', extention);
    },

    getCellHtml(column: Column, model: Backbone.Model) {
        const value = model.get(column.key);

        if (value === null || value === undefined) {
            return `<div class="cell ${column.columnClass}"></div>`;
        }
        let adjustedValue = value;

        switch (column.dataType || column.type) {
            case objectPropertyTypes.STRING:
                adjustedValue = this.__adjustValue(value);
                return `<div class="cell ${column.columnClass}" title="${column.format === 'HTML' ? '' : adjustedValue}">${adjustedValue}</div>`;
            case objectPropertyTypes.INSTANCE:
                if (Array.isArray(value)) {
                    adjustedValue = value.map(v => v && v.name).join(', ');
                } else if (value && value.name) {
                    adjustedValue = value.name;
                }
                return `<div class="cell ${column.columnClass}" title="${adjustedValue || ''}">${adjustedValue || ''}</div>`;
            case objectPropertyTypes.ACCOUNT:
                if (value.length > 0) {
                    adjustedValue = value
                        .map(item => ({
                            id: item.id,
                            text: item.text || item.name || (item.columns && item.columns[0])
                        }))
                        .sort((a, b) => a.text > b.text)
                        .reduce((memo, member) => {
                            if (memo) {
                                return `${memo}, ${member.text}`;
                            }
                            return member.text;
                        }, null);
                    return `<div class="cell ${column.columnClass}" title="${adjustedValue} || ''">${adjustedValue}</div>`;
                } else if (value.name) {
                    return `<div class="cell ${column.columnClass}" title="${value.name}">${value.name}</div>`;
                }
            case objectPropertyTypes.ENUM:
                adjustedValue = value ? value.valueExplained : '';
                return `<div class="cell ${column.columnClass}" title="${adjustedValue}">${adjustedValue}</div>`;
            case objectPropertyTypes.INTEGER:
            case objectPropertyTypes.DOUBLE:
            case objectPropertyTypes.DECIMAL:
                adjustedValue = Array.isArray(value) ? value : [value];
                adjustedValue = adjustedValue
                    .map(v => {
                        if (!v) {
                            return '';
                        }
                        if (column.formatOptions) {
                            if (column.formatOptions.intlOptions) {
                                return new Intl.NumberFormat(Localizer.langCode, column.formatOptions.intlOptions).format(value);
                            } else if (column.formatOptions.allowFloat === false) {
                                return Math.floor(v);
                            }
                        }
                        return value;
                    }).join(', ');
                return `<div class="cell cell-right ${column.columnClass}" title="${adjustedValue}">${adjustedValue}</div>`;
            case objectPropertyTypes.DURATION: {
                adjustedValue = Array.isArray(value) ? value : [value];
                adjustedValue = adjustedValue
                    .map(v => {
                        const defaultOptions = {
                            allowDays: true,
                            allowHours: true,
                            allowMinutes: true,
                            allowSeconds: true
                        };
                        const options = Object.assign(defaultOptions, _.pick(column.formatOptions || {}, Object.keys(defaultOptions)));
                        let result = '';
                        if (value === 0) {
                            return '0';
                        }
                        if (!value) {
                            return '';
                        }

                        const duration = dateHelpers.durationISOToObject(value);
                        if (options.allowDays) {
                            result += `${duration.days + Localizer.get('CORE.FORM.EDITORS.DURATION.WORKDURATION.DAYS')} `;
                        }
                        if (options.allowHours) {
                            result += `${duration.hours + Localizer.get('CORE.FORM.EDITORS.DURATION.WORKDURATION.HOURS')} `;
                        }
                        if (options.allowMinutes) {
                            result += `${duration.minutes + Localizer.get('CORE.FORM.EDITORS.DURATION.WORKDURATION.MINUTES')} `;
                        }
                        if (options.allowSeconds) {
                            result += `${duration.seconds + Localizer.get('CORE.FORM.EDITORS.DURATION.WORKDURATION.SECONDS')} `;
                        }
                        return result;
                    })
                    .join(', ')
                    .trim();

                return `<div class="cell ${column.columnClass}" title="${adjustedValue}">${adjustedValue}</div>`;
            }
            case objectPropertyTypes.BOOLEAN:
                adjustedValue = Array.isArray(value) ? value : [value || ''];
                adjustedValue = adjustedValue
                    .map(v => {
                        let result = '';
                        if (v === true) {
                            result = '<svg class="svg-grid-icons svg-icons_flag-yes"><use xlink:href="#icon-checked"></use></svg>';
                        } else if (v === false) {
                            result = '<svg class="svg-grid-icons svg-icons_flag-none"><use xlink:href="#icon-remove"></use></svg>';
                        }
                        return result;
                    })
                    .join(', ');
                return `<div class="cell ${column.columnClass}">${adjustedValue}</div>`;
            case objectPropertyTypes.DATETIME:
                adjustedValue = Array.isArray(value) ? value : [value];
                adjustedValue = adjustedValue
                    .map(v => {
                        if (column.formatOptions) {
                            const dateDisplayValue = column.formatOptions.dateDisplayFormat ? DateTimeService.getDateDisplayValue(v, column.formatOptions.dateDisplayFormat) : '';
                            const timeDisplayValue = column.formatOptions.timeDisplayFormat ? DateTimeService.getTimeDisplayValue(v, column.formatOptions.timeDisplayFormat) : '';
                            return `${dateDisplayValue} ${timeDisplayValue}`;
                        }
                        return dateHelpers.dateToDateTimeString(v, 'generalDateShortTime');
                    }).join(', ');
                return `<div class="cell ${column.columnClass}" title="${adjustedValue}">${adjustedValue}</div>`;
            case objectPropertyTypes.DOCUMENT:
                if (value.length > 0) {
                    return `
${value
                        .map(item => {
                            const text = item.text || item.name || (item.columns && item.columns[0]);
                            const url = item.url || (item.columns && item.columns[1]);
                            return `<a href="${url}" target="_blank" title="${text}">${text}</a>`;
                        })
                        .sort((a, b) => a.text > b.text)
                        .join(', ')}
`;
                }
            default:
                adjustedValue = this.__adjustValue(value);
                return `<div class="cell ${column.columnClass}">${adjustedValue || ''}</div>`;
        }
    },

    __adjustValue(value: Array<string | number> | string) {
        if (Array.isArray(value)) {
            return value.join(', ');
        }
        return value;
    }
});
<|endoftext|>


<commit_before>"use strict";

var DocumentNode = require('../node/node');
var _ = require('underscore');

var License = function(node, document) {
  DocumentNode.call(this, node, document);
};

// Type definition
// --------

License.type = {
  "id": "license",
  "properties": {
    "name": "string",
    "code": "string",
    "version": "string",
    "description": "string",
    "url": "string"
  }
};

// This is used for the auto-generated docs
// -----------------
//

License.description = {
  "name": "License",
  "remarks": [
    "Describes the content license used by the document"
  ],
  "properties": {
    "name": "License name",
    "code": "Coded license name, e.g. cc-by",
    "version": "License version",
    "description": "Text describing the license",
    "url": "URL for more information about the license"
  }
};

License.Prototype = function() {

};

License.available_licenses = {
  "none": {
    "id": "license",
    "type": "license",
    "name": "None",
    "code": "none",
    "description": "No license is attached to this article.",
    "version": "1.0",
    "url": ""
  },
  "public-domain": {
    "id": "license",
    "type": "license",
    "name": "Public Domain",
    "code": "public-domain",
    "description": "This work has been identified as being free of known restrictions under copyright law, including all related and neighboring rights. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.",
    "version": "1.0",
    "url": "http://creativecommons.org/publicdomain/mark/1.0/"
  },
  "cc-by": {
    "id": "license",
    "type": "license",
    "name": "Creative Commons Attribution",
    "code": "cc-by",
    "version": "3.0",
    "description": "This article is distributed under the terms of the Creative Commons Attribution License, which permits unrestricted use and redistribution provided that the original author and source are credited.",
    "url": "http://creativecommons.org/licenses/by/3.0/us/"
  },
  "gutenberg": {
    "id": "license",
    "type": "license",
    "name": "Project Gutenberg",
    "code": "gutenberg",
    "version": "1.0",
    "description": "This article is distributed under the terms of the Project Gutenberg License.",
    "url": "http://www.gutenberg.org/wiki/Gutenberg:The_Project_Gutenberg_License"
  }
};

License.Prototype.prototype = DocumentNode.prototype;
License.prototype = new License.Prototype();
License.prototype.constructor = License;

License.prototype.defineProperties();

module.exports = License;
<commit_msg>Slight changes to the license.<commit_after>"use strict";

var DocumentNode = require('../node/node');
var _ = require('underscore');

var License = function(node, document) {
  DocumentNode.call(this, node, document);
};

// Type definition
// --------

License.type = {
  "id": "license",
  "properties": {
    "name": "string",
    "code": "string",
    "version": "string",
    "description": "string",
    "url": "string"
  }
};

// This is used for the auto-generated docs
// -----------------
//

License.description = {
  "name": "License",
  "remarks": [
    "Describes the content license used by the document"
  ],
  "properties": {
    "name": "License name",
    "code": "Coded license name, e.g. cc-by",
    "version": "License version",
    "description": "Text describing the license",
    "url": "URL for more information about the license"
  }
};

License.Prototype = function() {

};

License.available_licenses = {
  "none": {
    "id": "license",
    "type": "license",
    "name": "None",
    "code": "none",
    "description": "No license is attached to this article.",
    "version": "1.0",
    "url": ""
  },
  "public-domain": {
    "id": "license",
    "type": "license",
    "name": "Public Domain",
    "code": "public-domain",
    "description": "This work has been identified as being free of known restrictions under copyright law, including all related and neighboring rights. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.",
    "version": "1.0",
    "url": "http://creativecommons.org/publicdomain/mark/1.0/"
  },
  "cc-by": {
    "id": "license",
    "type": "license",
    "name": "Creative Commons Attribution License",
    "code": "cc-by",
    "version": "3.0",
    "description": "This article is distributed under the terms of the Creative Commons Attribution License, which permits unrestricted use and redistribution provided that the original author and source are credited.",
    "url": "http://creativecommons.org/licenses/by/3.0/us/"
  },
  "gutenberg": {
    "id": "license",
    "type": "license",
    "name": "Project Gutenberg License",
    "code": "gutenberg",
    "version": "1.0",
    "description": "This article is distributed under the terms of the Project Gutenberg License.",
    "url": "http://www.gutenberg.org/wiki/Gutenberg:The_Project_Gutenberg_License"
  }
};

License.Prototype.prototype = DocumentNode.prototype;
License.prototype = new License.Prototype();
License.prototype.constructor = License;

License.prototype.defineProperties();

module.exports = License;
<|endoftext|>


<commit_before>/**
 * Developer: Grigory Kuznetsov
 * Date: 23.07.2015
 * Copyright: 2009-2016 Comindware®
 *       All Rights Reserved
 * Published under the MIT license
 */

"use strict";

import { objectPropertyTypes } from '../Meta';
import { helpers } from 'utils';
import { Handlebars } from 'lib';

let factory = {
    getCellViewByDataType: function(type) {
        var result;

        switch (type) {
        case objectPropertyTypes.STRING:
            result = factory.getTextCellView();
            break;
        case objectPropertyTypes.INSTANCE:
            result = factory.getReferenceCellView();
            break;
        case objectPropertyTypes.ACCOUNT:
            result = factory.getUserCellView();
            break;
        case objectPropertyTypes.ENUM:
            result = factory.getEnumCellView();
            break;
        case objectPropertyTypes.INTEGER:
        case objectPropertyTypes.DOUBLE:
        case objectPropertyTypes.DECIMAL:
            result = factory.getNumberCellView();
            break;
        case objectPropertyTypes.DURATION:
            result = factory.getDurationCellView();
            break;
        case objectPropertyTypes.BOOLEAN:
            result = factory.getBooleanCellView();
            break;
        case objectPropertyTypes.DATETIME:
            result = factory.getDateTimeCellView();
            break;
        case objectPropertyTypes.DOCUMENT:
            result = factory.getDocumentCellView();
            break;
        default:
            helpers.throwNotSupportedError('Data type' + type + 'is not supported');
            break;
        }

        return result;
    },

    getTextCellView: function () {
        return factory.__getSimpleView('{{highlightFragment value highlightedFragment}}');
    },

    getReferenceCellView: function () {
        return factory.__getSimpleView('{{#if value}}{{#if value.name}}{{highlightFragment value.name highlightedFragment}}{{/if}}{{/if}}');
    },

    getUserCellView: function () {
        return factory.__getAccountView();
    },

    getEnumCellView: function () {
        return factory.__getEnumView();
    },

    getNumberCellView: function () {
        return factory.__getSimpleView('{{value}}');
    },

    getDurationCellView: function () {
        return factory.__getSimpleView('{{renderShortDuration value}}');
    },

    getBooleanCellView: function () {
        const templateHelpers = {
            isTrue() {
                return this.value === true;
            },
            isFalse() {
                return this.value === false;
            }
        };
        return factory.__getSimpleView(
            "{{#if isTrue}}{{localize 'CORE.GRID.CELLVIEWFACTORY.BOOLEANCELLVIEW.YES'}}{{/if}}" +
            "{{#if isFalse}}{{localize 'CORE.GRID.CELLVIEWFACTORY.BOOLEANCELLVIEW.NO'}}{{/if}}",
            templateHelpers);
    },

    getDateTimeCellView: function () {
        return factory.__getSimpleView('{{#if value}}{{renderFullDate value}}{{/if}}');
    },

    getDocumentCellView: function () {
        return factory.__getDocumentView();
    },

    __getSimpleView: function (template, templateHelpers) {
        return Marionette.ItemView.extend({
            template: Handlebars.compile(template),
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange: function () {
                this.render();
            },
            className: 'grid-cell',
            templateHelpers: templateHelpers
        });
    },

    __getAccountView: function () {
        return Marionette.ItemView.extend({
            template: Handlebars.compile('{{text}}'),
            templateHelpers: function () {
                var value = this.model.get('value');
                var text = '';
                if (value && value.length > 0) {
                    text = _.chain(value).
                        map(function (item) {
                            return {
                                id: item.id,
                                text: item.columns[0]
                            };
                        }).
                        sortBy(function (member) {
                            return member.text;
                        }).
                        reduce(function (memo, member) {
                            if (memo) {
                                return memo + ', ' + member.text;
                            } else {
                                return member.text;
                            }
                        }, null).
                        value();
                }
                else if (value && value.name) {
                    text = value.name;
                }

                return {
                    text: text
                };
            },
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange: function () {
                this.render();
            },
            className: 'grid-cell'
        });
    },

    __getDocumentView: function () {
        return Marionette.ItemView.extend({
            template: Handlebars.compile('{{#each documents}}{{text}}{{#unless @last}}, {{/unless}}{{/each}}'),

            templateHelpers: function () {
                var value = this.model.get('value');
                var documents = [];
                if (value && value.length > 0) {
                    documents = _.chain(value).
                        map(function (item) {
                            return {
                                id: item.id,
                                text: item.text || item.name || item.columns && item.columns[0],
                                url: item.url || item.columns && item.columns[1]
                            };
                        }).
                        sortBy(function (document) {
                            return document.text;
                        }).
                        value();
                }

                return {
                    documents: documents
                };
            },
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange: function () {
                this.render();
            },
            className: 'grid-cell'
        });
    },

    __getEnumView: function() {
        return Marionette.ItemView.extend({
            template: Handlebars.compile("{{#if value}}{{valueExplained}}{{/if}}"),
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange: function () {
                this.render();
            },
            templateHelpers: function () {
                var value = this.model.get("value");
                return {
                    value: value,
                    valueExplained: value.valueExplained
                };
            },
            className: 'grid-cell'
        });
    }
};
export default factory;
<commit_msg>Review fixes<commit_after>/**
 * Developer: Grigory Kuznetsov
 * Date: 23.07.2015
 * Copyright: 2009-2016 Comindware®
 *       All Rights Reserved
 * Published under the MIT license
 */

"use strict";

import { objectPropertyTypes } from '../Meta';
import { helpers } from 'utils';
import { Handlebars } from 'lib';

let factory = {
    getCellViewByDataType: function(type) {
        var result;

        switch (type) {
        case objectPropertyTypes.STRING:
            result = factory.getTextCellView();
            break;
        case objectPropertyTypes.INSTANCE:
            result = factory.getReferenceCellView();
            break;
        case objectPropertyTypes.ACCOUNT:
            result = factory.getUserCellView();
            break;
        case objectPropertyTypes.ENUM:
            result = factory.getEnumCellView();
            break;
        case objectPropertyTypes.INTEGER:
        case objectPropertyTypes.DOUBLE:
        case objectPropertyTypes.DECIMAL:
            result = factory.getNumberCellView();
            break;
        case objectPropertyTypes.DURATION:
            result = factory.getDurationCellView();
            break;
        case objectPropertyTypes.BOOLEAN:
            result = factory.getBooleanCellView();
            break;
        case objectPropertyTypes.DATETIME:
            result = factory.getDateTimeCellView();
            break;
        case objectPropertyTypes.DOCUMENT:
            result = factory.getDocumentCellView();
            break;
        default:
            helpers.throwNotSupportedError('Data type' + type + 'is not supported');
            break;
        }

        return result;
    },

    getTextCellView: function () {
        return factory.__getSimpleView('{{highlightFragment value highlightedFragment}}');
    },

    getReferenceCellView: function () {
        return factory.__getSimpleView('{{#if value}}{{#if value.name}}{{highlightFragment value.name highlightedFragment}}{{/if}}{{/if}}');
    },

    getUserCellView: function () {
        return factory.__getAccountView();
    },

    getEnumCellView: function () {
        return factory.__getEnumView();
    },

    getNumberCellView: function () {
        return factory.__getSimpleView('{{value}}');
    },

    getDurationCellView: function () {
        return factory.__getSimpleView('{{renderShortDuration value}}');
    },

    getBooleanCellView: function () {
        const templateHelpers = {
            localizedValue() {
                if (this.value === true) {
                    return Localizer.get('CORE.GRID.CELLVIEWFACTORY.BOOLEANCELLVIEW.YES');
                } else if (this.value === false) {
                    return Localizer.get('CORE.GRID.CELLVIEWFACTORY.BOOLEANCELLVIEW.NO');
                } else {
                    return ''
                }
            }
        };
        return factory.__getSimpleView("{{localizedValue}}", templateHelpers);
    },

    getDateTimeCellView: function () {
        return factory.__getSimpleView('{{#if value}}{{renderFullDate value}}{{/if}}');
    },

    getDocumentCellView: function () {
        return factory.__getDocumentView();
    },

    __getSimpleView: function (template, templateHelpers) {
        return Marionette.ItemView.extend({
            template: Handlebars.compile(template),
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange: function () {
                this.render();
            },
            className: 'grid-cell',
            templateHelpers: templateHelpers
        });
    },

    __getAccountView: function () {
        return Marionette.ItemView.extend({
            template: Handlebars.compile('{{text}}'),
            templateHelpers: function () {
                var value = this.model.get('value');
                var text = '';
                if (value && value.length > 0) {
                    text = _.chain(value).
                        map(function (item) {
                            return {
                                id: item.id,
                                text: item.columns[0]
                            };
                        }).
                        sortBy(function (member) {
                            return member.text;
                        }).
                        reduce(function (memo, member) {
                            if (memo) {
                                return memo + ', ' + member.text;
                            } else {
                                return member.text;
                            }
                        }, null).
                        value();
                }
                else if (value && value.name) {
                    text = value.name;
                }

                return {
                    text: text
                };
            },
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange: function () {
                this.render();
            },
            className: 'grid-cell'
        });
    },

    __getDocumentView: function () {
        return Marionette.ItemView.extend({
            template: Handlebars.compile('{{#each documents}}{{text}}{{#unless @last}}, {{/unless}}{{/each}}'),

            templateHelpers: function () {
                var value = this.model.get('value');
                var documents = [];
                if (value && value.length > 0) {
                    documents = _.chain(value).
                        map(function (item) {
                            return {
                                id: item.id,
                                text: item.text || item.name || item.columns && item.columns[0],
                                url: item.url || item.columns && item.columns[1]
                            };
                        }).
                        sortBy(function (document) {
                            return document.text;
                        }).
                        value();
                }

                return {
                    documents: documents
                };
            },
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange: function () {
                this.render();
            },
            className: 'grid-cell'
        });
    },

    __getEnumView: function() {
        return Marionette.ItemView.extend({
            template: Handlebars.compile("{{#if value}}{{valueExplained}}{{/if}}"),
            modelEvents: {
                'change:highlightedFragment': '__handleHighlightedFragmentChange'
            },
            __handleHighlightedFragmentChange: function () {
                this.render();
            },
            templateHelpers: function () {
                var value = this.model.get("value");
                return {
                    value: value,
                    valueExplained: value.valueExplained
                };
            },
            className: 'grid-cell'
        });
    }
};
export default factory;
<|endoftext|>


<commit_before>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2016, Olivier Biot, Jason Oster, Aaron McLeod
 * http://www.melonjs.org
 */
(function () {
    // a basic progress bar object
    var ProgressBar = me.Renderable.extend({

        init: function (v, w, h) {
            this._super(me.Renderable, "init", [v.x, v.y, w, h]);
            // flag to know if we need to refresh the display
            this.invalidate = false;

            // default progress bar height
            this.barHeight = 4;

            // current progress
            this.progress = 0;

            this.autoTransform = false;
        },

        // make sure the screen is refreshed every frame
        onProgressUpdate : function (progress) {
            this.progress = ~~(progress * this.width);
            this.invalidate = true;
        },

        // make sure the screen is refreshed every frame
        update : function () {
            if (this.invalidate === true) {
                // clear the flag
                this.invalidate = false;
                // and return true
                return true;
            }
            // else return false
            return false;
        },

         // draw function
        draw : function (renderer) {
            // draw the progress bar
            renderer.setColor("black");
            renderer.fillRect(0, (this.height / 2) - (this.barHeight / 2), this.width, this.barHeight);

            renderer.setColor("#55aa00");
            renderer.fillRect(2, (this.height / 2) - (this.barHeight / 2), this.progress, this.barHeight);

            renderer.setColor("white");
        }
    });

    // the melonJS Logo
    var IconLogo = me.Renderable.extend({
        init : function (iconCanvas, x, y) {
            this._super(me.Renderable, "init", [x, y, 100, 85]);

            this.iconCanvas = iconCanvas;

            var context = me.video.renderer.getContext2d(this.iconCanvas);

            context.translate(this.pos.x, this.pos.y);
            context.beginPath();
            context.moveTo(0.7, 48.9);
            context.bezierCurveTo(10.8, 68.9, 38.4, 75.8, 62.2, 64.5);
            context.bezierCurveTo(86.1, 53.1, 97.2, 27.7, 87.0, 7.7);
            context.lineTo(87.0, 7.7);
            context.bezierCurveTo(89.9, 15.4, 73.9, 30.2, 50.5, 41.4);
            context.bezierCurveTo(27.1, 52.5, 5.2, 55.8, 0.7, 48.9);
            context.lineTo(0.7, 48.9);
            context.lineTo(0.7, 48.9);
            context.closePath();
            context.fillStyle = "rgb(255, 255, 255)";
            context.fill();

            context.beginPath();
            context.moveTo(84.0, 7.0);
            context.bezierCurveTo(87.6, 14.7, 72.5, 30.2, 50.2, 41.6);
            context.bezierCurveTo(27.9, 53.0, 6.9, 55.9, 3.2, 48.2);
            context.bezierCurveTo(-0.5, 40.4, 14.6, 24.9, 36.9, 13.5);
            context.bezierCurveTo(59.2, 2.2, 80.3, -0.8, 84.0, 7.0);
            context.lineTo(84.0, 7.0);
            context.closePath();
            context.lineWidth = 5.3;
            context.strokeStyle = "rgb(255, 255, 255)";
            context.lineJoin = "miter";
            context.miterLimit = 4.0;
            context.stroke();

            this.autoTransform = false;
        },

        draw : function (renderer) {
            renderer.drawImage(this.iconCanvas, 0, 0);
        }
    });

    // the melonJS Text Logo
    var TextLogo = me.Renderable.extend({
        // constructor
        init : function (w, h) {
            this._super(me.Renderable, "init", [0, 0, w, h]);
            this.logo1 = new me.Font("century gothic", 32, "white", "middle");
            this.logo2 = new me.Font("century gothic", 32, "#55aa00", "middle");
            this.logo2.bold();
            this.logo1.textBaseline = this.logo2.textBaseline = "alphabetic";

            this.autoTransform = false;
        },

        draw : function (renderer) {
            // measure the logo size
            var logo1_width = this.logo1.measureText(renderer, "melon").width;
            var xpos = (this.width - logo1_width - this.logo2.measureText(renderer, "JS").width) / 2;
            var ypos = (this.height / 2) + (this.logo2.measureText(renderer, "melon").height);

            // draw the melonJS string
            this.logo1.draw(renderer, "melon", xpos, ypos);
            xpos += logo1_width;
            this.logo2.draw(renderer, "JS", xpos, ypos);
        }

    });

    /**
     * a default loading screen
     * @memberOf me
     * @ignore
     * @constructor
     */
    me.DefaultLoadingScreen = me.ScreenObject.extend({
        // call when the loader is resetted
        onResetEvent : function () {
            // background color
            me.game.world.addChild(new me.ColorLayer("background", "#202020", 0), 0);

            // progress bar
            var progressBar = new ProgressBar(
                new me.Vector2d(),
                me.video.renderer.getWidth(),
                me.video.renderer.getHeight()
            );

            this.loaderHdlr = me.event.subscribe(
                me.event.LOADER_PROGRESS,
                progressBar.onProgressUpdate.bind(progressBar)
            );

            this.resizeHdlr = me.event.subscribe(
                me.event.VIEWPORT_ONRESIZE,
                progressBar.resize.bind(progressBar)
            );

            me.game.world.addChild(progressBar, 1);
            this.iconCanvas = me.video.createCanvas(me.game.viewport.width, me.game.viewport.height, false);
            // melonJS text & logo
            var icon = new IconLogo(
                this.iconCanvas,
                (me.video.renderer.getWidth() - 100) / 2,
                (me.video.renderer.getHeight() / 2) - (progressBar.barHeight / 2) - 90
            );
            me.game.world.addChild(icon, 1);
            me.game.world.addChild(new TextLogo(me.video.renderer.getWidth(), me.video.renderer.getHeight()), 1);
        },

        // destroy object at end of loading
        onDestroyEvent : function () {
            // cancel the callback
            me.event.unsubscribe(this.loaderHdlr);
            me.event.unsubscribe(this.resizeHdlr);
            this.loaderHdlr = this.resizeHdlr = null;
        }
    });
})();
<commit_msg>this is not required anymore<commit_after>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2016, Olivier Biot, Jason Oster, Aaron McLeod
 * http://www.melonjs.org
 */
(function () {
    // a basic progress bar object
    var ProgressBar = me.Renderable.extend({

        init: function (v, w, h) {
            this._super(me.Renderable, "init", [v.x, v.y, w, h]);
            // flag to know if we need to refresh the display
            this.invalidate = false;

            // default progress bar height
            this.barHeight = 4;

            // current progress
            this.progress = 0;
        },

        // make sure the screen is refreshed every frame
        onProgressUpdate : function (progress) {
            this.progress = ~~(progress * this.width);
            this.invalidate = true;
        },

        // make sure the screen is refreshed every frame
        update : function () {
            if (this.invalidate === true) {
                // clear the flag
                this.invalidate = false;
                // and return true
                return true;
            }
            // else return false
            return false;
        },

         // draw function
        draw : function (renderer) {
            // draw the progress bar
            renderer.setColor("black");
            renderer.fillRect(0, (this.height / 2) - (this.barHeight / 2), this.width, this.barHeight);

            renderer.setColor("#55aa00");
            renderer.fillRect(2, (this.height / 2) - (this.barHeight / 2), this.progress, this.barHeight);

            renderer.setColor("white");
        }
    });

    // the melonJS Logo
    var IconLogo = me.Renderable.extend({
        init : function (iconCanvas, x, y) {
            this._super(me.Renderable, "init", [x, y, 100, 85]);

            this.iconCanvas = iconCanvas;

            var context = me.video.renderer.getContext2d(this.iconCanvas);

            context.translate(this.pos.x, this.pos.y);
            context.beginPath();
            context.moveTo(0.7, 48.9);
            context.bezierCurveTo(10.8, 68.9, 38.4, 75.8, 62.2, 64.5);
            context.bezierCurveTo(86.1, 53.1, 97.2, 27.7, 87.0, 7.7);
            context.lineTo(87.0, 7.7);
            context.bezierCurveTo(89.9, 15.4, 73.9, 30.2, 50.5, 41.4);
            context.bezierCurveTo(27.1, 52.5, 5.2, 55.8, 0.7, 48.9);
            context.lineTo(0.7, 48.9);
            context.lineTo(0.7, 48.9);
            context.closePath();
            context.fillStyle = "rgb(255, 255, 255)";
            context.fill();

            context.beginPath();
            context.moveTo(84.0, 7.0);
            context.bezierCurveTo(87.6, 14.7, 72.5, 30.2, 50.2, 41.6);
            context.bezierCurveTo(27.9, 53.0, 6.9, 55.9, 3.2, 48.2);
            context.bezierCurveTo(-0.5, 40.4, 14.6, 24.9, 36.9, 13.5);
            context.bezierCurveTo(59.2, 2.2, 80.3, -0.8, 84.0, 7.0);
            context.lineTo(84.0, 7.0);
            context.closePath();
            context.lineWidth = 5.3;
            context.strokeStyle = "rgb(255, 255, 255)";
            context.lineJoin = "miter";
            context.miterLimit = 4.0;
            context.stroke();
        },

        draw : function (renderer) {
            renderer.drawImage(this.iconCanvas, 0, 0);
        }
    });

    // the melonJS Text Logo
    var TextLogo = me.Renderable.extend({
        // constructor
        init : function (w, h) {
            this._super(me.Renderable, "init", [0, 0, w, h]);
            this.logo1 = new me.Font("century gothic", 32, "white", "middle");
            this.logo2 = new me.Font("century gothic", 32, "#55aa00", "middle");
            this.logo2.bold();
            this.logo1.textBaseline = this.logo2.textBaseline = "alphabetic";
        },

        draw : function (renderer) {
            // measure the logo size
            var logo1_width = this.logo1.measureText(renderer, "melon").width;
            var xpos = (this.width - logo1_width - this.logo2.measureText(renderer, "JS").width) / 2;
            var ypos = (this.height / 2) + (this.logo2.measureText(renderer, "melon").height);

            // draw the melonJS string
            this.logo1.draw(renderer, "melon", xpos, ypos);
            xpos += logo1_width;
            this.logo2.draw(renderer, "JS", xpos, ypos);
        }

    });

    /**
     * a default loading screen
     * @memberOf me
     * @ignore
     * @constructor
     */
    me.DefaultLoadingScreen = me.ScreenObject.extend({
        // call when the loader is resetted
        onResetEvent : function () {
            // background color
            me.game.world.addChild(new me.ColorLayer("background", "#202020", 0), 0);

            // progress bar
            var progressBar = new ProgressBar(
                new me.Vector2d(),
                me.video.renderer.getWidth(),
                me.video.renderer.getHeight()
            );

            this.loaderHdlr = me.event.subscribe(
                me.event.LOADER_PROGRESS,
                progressBar.onProgressUpdate.bind(progressBar)
            );

            this.resizeHdlr = me.event.subscribe(
                me.event.VIEWPORT_ONRESIZE,
                progressBar.resize.bind(progressBar)
            );

            me.game.world.addChild(progressBar, 1);
            this.iconCanvas = me.video.createCanvas(me.game.viewport.width, me.game.viewport.height, false);
            // melonJS text & logo
            var icon = new IconLogo(
                this.iconCanvas,
                (me.video.renderer.getWidth() - 100) / 2,
                (me.video.renderer.getHeight() / 2) - (progressBar.barHeight / 2) - 90
            );
            me.game.world.addChild(icon, 1);
            me.game.world.addChild(new TextLogo(me.video.renderer.getWidth(), me.video.renderer.getHeight()), 1);
        },

        // destroy object at end of loading
        onDestroyEvent : function () {
            // cancel the callback
            me.event.unsubscribe(this.loaderHdlr);
            me.event.unsubscribe(this.resizeHdlr);
            this.loaderHdlr = this.resizeHdlr = null;
        }
    });
})();
<|endoftext|>


<commit_before>/*globals chrome,fdom:true,console,Promise*/
/*jslint indent:2,white:true,sloppy:true */
/**
 * A freedom.js interface to Chrome sockets
 * @constructor
 * @private
 * @param {fdom.Port} channel the module creating this provider.
 * @param {Function} dispatchEvent Method for emitting events.
 * @param {number?} id A pre-existing socket Id for the socket.
 */
var Socket_chrome = function(channel, dispatchEvent, id) {
  this.dispatchEvent = dispatchEvent;
  this.id = id || undefined;
  if (this.id) {
    this.startReadLoop_();
  }
};

/**
 * Get Information about the socket.
 * @method getInfo
 * @return {Object} connection and address information about the socket.
 */
Socket_chrome.prototype.getInfo = function(continuation) {
  if (this.id) {
    chrome.socket.getInfo(this.id, continuation);
  } else {
    continuation({
      connected: false
    });
  }
};

/**
 * Connect to a designated location and begin reading.
 * @method connect
 * @param {String} hostname The host or ip to connect to.
 * @param {number} port The port to connect on.
 * @param {Function} cb Function to call with completion or error.
 */
Socket_chrome.prototype.connect = function(hostname, port, cb) {
  if (this.id) {
    cb(undefined, {
      "errcode": "ALREADY_CONNECTED",
      "message": "Cannot Connect Existing Socket"
    });
    return;
  }
  chrome.socket.create('tcp', {}, function(createInfo) {
    this.id = createInfo.socketId;
    chrome.socket.connect(this.id, hostname, port, function (result) {
      if (result < 0) {
        cb(undefined, {
          "errcode": "CONNECTION_FAILED",
          "message": "Chrome Connection Failed: " +
              Socket_chrome.ERROR_MAP[result]
        });
      } else {
        cb();
      }
      this.read();
    }.bind(this));
  }.bind(this));
};

Socket_chrome.prototype.write = function(data, cb) {
  if (!this.id) {
    cb(undefined, {
      "errcode": "SOCKET_CLOSED",
      "message": "Cannot Write on Closed Socket"
    });
    return;
  }
  chrome.socket.write(this.id, data, cb);
};

// Error codes are at:
// https://code.google.com/p/chromium/codesearch#
//     chromium/src/net/base/net_error_list.h
Socket_chrome.ERROR_MAP = {
  '-1': 'IO_PENDING',
  '-2': 'FAILED',
  '-3': 'ABORTED',
  '-4': 'INVALID_ARGUMENT',
  '-5': 'INVALID_HANDLE',
  '-7': 'TIMED_OUT',
  '-13': 'OUT_OF_MEMORY',
  '-15': 'SOCKET_NOT_CONNECTED',
  '-21': 'NETWORK_CHANGED',
  '-23': 'SOCKET_IS_CONNECTED',
  '-100': 'CONNECTION_CLOSED',
  '-101': 'CONNECTION_RESET',
  '-102': 'CONNECTION_REFUSED',
  '-103': 'CONNECTION_ABORTED',
  '-104': 'CONNECTION_FAILED',
  '-105': 'NAME_NOT_RESOLVED',
  '-106': 'INTERNET_DISCONNECTED',
  '-1000': 'GENERIC_CORDOVA_FAILURE'  //See Cordova Plugin socket.js
};

Socket_chrome.errorStringOfCode_ = function(code) {
  return Socket_chrome.ERROR_MAP[String(code)] ||
      "UNKOWN ERROR: " + code;
};

/*
 * Read data on a socket in an event loop until the socket is closed or an
 * error occurs.
 * @method read
 * @private
 */
Socket_chrome.prototype.dispatchDisconnect_ = function (code) {
  if (code === 0) {
    this.dispatchEvent('onDisconnect', {
      errcode: 'NONE',
      message: 'CLOSED1'
    });
  } else if(readInfo.resultCode === -100) {
    this.dispatchEvent('onDisconnect', {
      errcode: 'NONE',
      message: 'CLOSED2'
    });
  } else if(readInfo.resultCode < 0) {
    this.dispatchEvent('onDisconnect', {
      errcode: Socket_chrome.errorStringOfCode_(readInfo.resultCode),
      message: 'unexpected socket error'
    });
  }
  return Promise.Reject();
};

Socket_chrome.prototype.handleReadData_ = function (readInfo) {
  if(readInfo.resultCode <= 0) {
    reading = false;
    this.dispatchDisconnect_(readInfo.resultCode);
    return;
  }
  this.dispatchEvent('onData', {data: readInfo.data});
};

/*
 * Read data on a socket in an event loop until the socket is closed or an
 * error occurs.
 * @method read
 * @private
 */
Socket_chrome.prototype.startReadLoop_ = function() {
  var loop = function() {
    return this.makeSocketReadPromise_()
      .then(this.handleReadData_.bind(this))
      .then(loop);
  };
  loop();
};

/**
 * Return a promise based on a chrome.read call.
 * @method doRead
 * @private
 */
Socket_chrome.prototype.makeSocketReadPromise_ = function() {
  return new Promise(function(resolve) {
    chrome.socket.read(this.id, null, resolve);
  }.bind(this));
};

/**
 * Listen on a socket to accept new clients.
 * @method listen
 * @param {String} address the address to listen on
 * @param {number} port the port to listen on
 * @param {Function} callback Callback to call when listening has occured.
 */
Socket_chrome.prototype.listen = function(address, port, callback) {
  if (this.id) {
    callback(undefined, {
      errcode: "ALREADY_CONNECTED",
      message: "Cannot Listen on existing socket."
    });
    return;
  }
  chrome.socket.create('tcp', {}, function(createInfo) {
    this.id = createInfo.socketId;
    chrome.socket.listen(this.id, address, port, 20,
        this.accept.bind(this, callback));
  }.bind(this));
};

Socket_chrome.prototype.accept = function(callback, result) {
  var acceptCallback;

  if (result !== 0) {
    var errorMsg;
    if (Socket_chrome.ERROR_MAP.hasOwnProperty(result)) {
      errorMsg = "Chrome Listen failed: " + Socket_chrome.ERROR_MAP[result];
    } else {
      errorMsg = "Chrome Listen failed: Unknown code " + result;
    }
    callback(undefined, {
      errcode: "CONNECTION_FAILURE",
      message: errorMsg
    });
    return;
  } else {
    callback();
  }

  // Begin accepting on the listening socket.
  acceptCallback = function(acceptInfo) {
    if (acceptInfo.resultCode === 0) {
      chrome.socket.getInfo(acceptInfo.socketId, function(info) {
        this.dispatchEvent('onConnection', {
          socket: acceptInfo.socketId,
          host: info.peerAddress,
          port: info.peerPort
        });
      }.bind(this));
      chrome.socket.accept(this.id, acceptCallback);
    // -15 is socket_not_connected.
    } else if (acceptInfo.resultCode !== -15) {
      console.warn('Failed to accept ' + this.id + ': ' +
          acceptInfo.resultCode);
    } else {
      chrome.socket.accept(this.id, acceptCallback);
    }
  }.bind(this);

  chrome.socket.accept(this.id, acceptCallback);
};

/**
 * Close and Destroy a socket
 * @method close
 * @param {Function} continuation Function to call once socket is destroyed.
 */
Socket_chrome.prototype.close = function(continuation) {
  if (this.id) {
    chrome.socket.disconnect(this.id);
    chrome.socket.destroy(this.id);
    delete this.id;
    continuation();
  } else {
    continuation(undefined, {
      "errcode": "SOCKET_CLOSED",
      "message": "Socket Already Closed"
    });
  }
};

/** REGISTER PROVIDER **/
if (typeof fdom !== 'undefined') {
  fdom.apis.register("core.tcpsocket", Socket_chrome);
}
<commit_msg>fixed errCode value for disconnect<commit_after>/*globals chrome,fdom:true,console,Promise*/
/*jslint indent:2,white:true,sloppy:true */
/**
 * A freedom.js interface to Chrome sockets
 * @constructor
 * @private
 * @param {fdom.Port} channel the module creating this provider.
 * @param {Function} dispatchEvent Method for emitting events.
 * @param {number?} id A pre-existing socket Id for the socket.
 */
var Socket_chrome = function(channel, dispatchEvent, id) {
  this.dispatchEvent = dispatchEvent;
  this.id = id || undefined;
  if (this.id) {
    this.startReadLoop_();
  }
};

/**
 * Get Information about the socket.
 * @method getInfo
 * @return {Object} connection and address information about the socket.
 */
Socket_chrome.prototype.getInfo = function(continuation) {
  if (this.id) {
    chrome.socket.getInfo(this.id, continuation);
  } else {
    continuation({
      connected: false
    });
  }
};

/**
 * Connect to a designated location and begin reading.
 * @method connect
 * @param {String} hostname The host or ip to connect to.
 * @param {number} port The port to connect on.
 * @param {Function} cb Function to call with completion or error.
 */
Socket_chrome.prototype.connect = function(hostname, port, cb) {
  if (this.id) {
    cb(undefined, {
      "errcode": "ALREADY_CONNECTED",
      "message": "Cannot Connect Existing Socket"
    });
    return;
  }
  chrome.socket.create('tcp', {}, function(createInfo) {
    this.id = createInfo.socketId;
    chrome.socket.connect(this.id, hostname, port, function (result) {
      if (result < 0) {
        cb(undefined, {
          "errcode": "CONNECTION_FAILED",
          "message": "Chrome Connection Failed: " +
              Socket_chrome.ERROR_MAP[result]
        });
      } else {
        cb();
      }
      this.read();
    }.bind(this));
  }.bind(this));
};

Socket_chrome.prototype.write = function(data, cb) {
  if (!this.id) {
    cb(undefined, {
      "errcode": "SOCKET_CLOSED",
      "message": "Cannot Write on Closed Socket"
    });
    return;
  }
  chrome.socket.write(this.id, data, cb);
};

// Error codes are at:
// https://code.google.com/p/chromium/codesearch#
//     chromium/src/net/base/net_error_list.h
Socket_chrome.ERROR_MAP = {
  '-1': 'IO_PENDING',
  '-2': 'FAILED',
  '-3': 'ABORTED',
  '-4': 'INVALID_ARGUMENT',
  '-5': 'INVALID_HANDLE',
  '-7': 'TIMED_OUT',
  '-13': 'OUT_OF_MEMORY',
  '-15': 'SOCKET_NOT_CONNECTED',
  '-21': 'NETWORK_CHANGED',
  '-23': 'SOCKET_IS_CONNECTED',
  '-100': 'CONNECTION_CLOSED',
  '-101': 'CONNECTION_RESET',
  '-102': 'CONNECTION_REFUSED',
  '-103': 'CONNECTION_ABORTED',
  '-104': 'CONNECTION_FAILED',
  '-105': 'NAME_NOT_RESOLVED',
  '-106': 'INTERNET_DISCONNECTED',
  '-1000': 'GENERIC_CORDOVA_FAILURE'  //See Cordova Plugin socket.js
};

Socket_chrome.errorStringOfCode_ = function(code) {
  return Socket_chrome.ERROR_MAP[String(code)] ||
      "UNKOWN ERROR: " + code;
};

/*
 * Read data on a socket in an event loop until the socket is closed or an
 * error occurs.
 * @method read
 * @private
 */
Socket_chrome.prototype.dispatchDisconnect_ = function (code) {
  if (code === 0) {
    this.dispatchEvent('onDisconnect', {
      errcode: 'NONE',
      message: 'CLOSED1'
    });
  } else if(readInfo.resultCode === -100) {
    this.dispatchEvent('onDisconnect', {
      errcode: 'NONE',
      message: 'CLOSED2'
    });
  } else if(readInfo.resultCode < 0) {
    this.dispatchEvent('onDisconnect', {
      errcode: Socket_chrome.errorStringOfCode_(readInfo.resultCode),
      message: 'unexpected socket error'
    });
  }
  return Promise.Reject();
};

Socket_chrome.prototype.handleReadData_ = function (readInfo) {
  if(readInfo.resultCode <= 0) {
    reading = false;
    this.dispatchDisconnect_(readInfo.resultCode);
    return;
  }
  this.dispatchEvent('onData', {data: readInfo.data});
};

/*
 * Read data on a socket in an event loop until the socket is closed or an
 * error occurs.
 * @method read
 * @private
 */
Socket_chrome.prototype.startReadLoop_ = function() {
  var loop = function() {
    return this.makeSocketReadPromise_()
      .then(this.handleReadData_.bind(this))
      .then(loop);
  }.bind(this);
  loop();
};

/**
 * Return a promise based on a chrome.read call.
 * @method doRead
 * @private
 */
Socket_chrome.prototype.makeSocketReadPromise_ = function() {
  return new Promise(function(resolve) {
    chrome.socket.read(this.id, null, resolve);
  }.bind(this));
};

/**
 * Listen on a socket to accept new clients.
 * @method listen
 * @param {String} address the address to listen on
 * @param {number} port the port to listen on
 * @param {Function} callback Callback to call when listening has occured.
 */
Socket_chrome.prototype.listen = function(address, port, callback) {
  if (this.id) {
    callback(undefined, {
      errcode: "ALREADY_CONNECTED",
      message: "Cannot Listen on existing socket."
    });
    return;
  }
  chrome.socket.create('tcp', {}, function(createInfo) {
    this.id = createInfo.socketId;
    chrome.socket.listen(this.id, address, port, 20,
        this.accept.bind(this, callback));
  }.bind(this));
};

Socket_chrome.prototype.accept = function(callback, result) {
  var acceptCallback;

  if (result !== 0) {
    var errorMsg;
    if (Socket_chrome.ERROR_MAP.hasOwnProperty(result)) {
      errorMsg = "Chrome Listen failed: " + Socket_chrome.ERROR_MAP[result];
    } else {
      errorMsg = "Chrome Listen failed: Unknown code " + result;
    }
    callback(undefined, {
      errcode: "CONNECTION_FAILURE",
      message: errorMsg
    });
    return;
  } else {
    callback();
  }

  // Begin accepting on the listening socket.
  acceptCallback = function(acceptInfo) {
    if (acceptInfo.resultCode === 0) {
      chrome.socket.getInfo(acceptInfo.socketId, function(info) {
        this.dispatchEvent('onConnection', {
          socket: acceptInfo.socketId,
          host: info.peerAddress,
          port: info.peerPort
        });
      }.bind(this));
      chrome.socket.accept(this.id, acceptCallback);
    // -15 is socket_not_connected.
    } else if (acceptInfo.resultCode !== -15) {
      console.warn('Failed to accept ' + this.id + ': ' +
          acceptInfo.resultCode);
    } else {
      chrome.socket.accept(this.id, acceptCallback);
    }
  }.bind(this);

  chrome.socket.accept(this.id, acceptCallback);
};

/**
 * Close and Destroy a socket
 * @method close
 * @param {Function} continuation Function to call once socket is destroyed.
 */
Socket_chrome.prototype.close = function(continuation) {
  if (this.id) {
    chrome.socket.disconnect(this.id);
    chrome.socket.destroy(this.id);
    delete this.id;
    continuation();
  } else {
    continuation(undefined, {
      "errcode": "SOCKET_CLOSED",
      "message": "Socket Already Closed"
    });
  }
};

/** REGISTER PROVIDER **/
if (typeof fdom !== 'undefined') {
  fdom.apis.register("core.tcpsocket", Socket_chrome);
}
<|endoftext|>


<commit_before>var room = require('../models/room/index.js');

module.exports = function(io) {

    io.on('connection', function (socket) {
        // Socket de connexion d'un nouveau joueur.
        io.on('user', function (data, fn) {
            console.log('Inscription de : ' + data["pseudo"] + ' dans la room ' + data["room"]);
            var userToken = room.getRoom(data["room"]).memberJoin();
            // Si le user est valide, on l'ajoute sur la page de la room.
            if(userToken){

                //Sauvegarde du username et de la room dans la session
                io.username = data["pseudo"];
                io.room = data["room"];
                io.token = userToken;
                io.score = 0;

            //     socket.broadcast.emit('new-user-'+data["room"], {user : data["pseudo"],
            //                                                         usertoken : userToken,
            //                                                         nbUsers : room.getRoom( data["room"]).getMembers().length});
             }

            // if(! room.getRoom(data["room"]).notEnough()){
            //     socket.broadcast.emit('start-party-room-'+data["room"]);
            // }

            //Le token est retourné au client pour identifier les traitements
            fn({userToken:userToken});
        });
    });
};<commit_msg>fix socket<commit_after>var room = require('../models/room/index.js');

module.exports = function(io) {

    io.on('connection', function (socket) {
        // Socket de connexion d'un nouveau joueur.
        socket.on('user', function (data, fn) {
            console.log('Inscription de : ' + data["pseudo"] + ' dans la room ' + data["room"]);
            var userToken = room.getRoom(data["room"]).memberJoin();
            // Si le user est valide, on l'ajoute sur la page de la room.
            if(userToken){

                //Sauvegarde du username et de la room dans la session
                io.username = data["pseudo"];
                io.room = data["room"];
                io.token = userToken;
                io.score = 0;

            //     socket.broadcast.emit('new-user-'+data["room"], {user : data["pseudo"],
            //                                                         usertoken : userToken,
            //                                                         nbUsers : room.getRoom( data["room"]).getMembers().length});
             }

            // if(! room.getRoom(data["room"]).notEnough()){
            //     socket.broadcast.emit('start-party-room-'+data["room"]);
            // }

            //Le token est retourné au client pour identifier les traitements
            fn({userToken:userToken});
        });
    });
};<|endoftext|>