<commit_before>/**
 * 数值处理模块
 * @module echarts/util/number
 */

define(function (require) {

    var number = {};

    var RADIAN_EPSILON = 1e-4;

    function _trim(str) {
        return str.replace(/^\s+/, '').replace(/\s+$/, '');
    }

    /**
     * Linear mapping a value from domain to range
     * @memberOf module:echarts/util/number
     * @param  {(number|Array.<number>)} val
     * @param  {Array.<number>} domain Domain extent domain[0] can be bigger than domain[1]
     * @param  {Array.<number>} range  Range extent range[0] can be bigger than range[1]
     * @param  {boolean} clamp
     * @return {(number|Array.<number>}
     */
    number.linearMap = function (val, domain, range, clamp) {
        var subDomain = domain[1] - domain[0];
        var subRange = range[1] - range[0];

        if (subDomain === 0) {
            return subRange === 0
                ? range[0]
                : (range[0] + range[1]) / 2;
        }

        // Avoid accuracy problem in edge, such as
        // 146.39 - 62.83 === 83.55999999999999.
        // See echarts/test/ut/spec/util/number.js#linearMap#accuracyError
        // It is a little verbose for efficiency considering this method
        // is a hotspot.
        if (clamp) {
            if (subDomain > 0) {
                if (val <= domain[0]) {
                    return range[0];
                }
                else if (val >= domain[1]) {
                    return range[1];
                }
            }
            else {
                if (val >= domain[0]) {
                    return range[0];
                }
                else if (val <= domain[1]) {
                    return range[1];
                }
            }
        }
        else {
            if (val === domain[0]) {
                return range[0];
            }
            if (val === domain[1]) {
                return range[1];
            }
        }

        return (val - domain[0]) / subDomain * subRange + range[0];
    };

    /**
     * Convert a percent string to absolute number.
     * Returns NaN if percent is not a valid string or number
     * @memberOf module:echarts/util/number
     * @param {string|number} percent
     * @param {number} all
     * @return {number}
     */
    number.parsePercent = function(percent, all) {
        switch (percent) {
            case 'center':
            case 'middle':
                percent = '50%';
                break;
            case 'left':
            case 'top':
                percent = '0%';
                break;
            case 'right':
            case 'bottom':
                percent = '100%';
                break;
        }
        if (typeof percent === 'string') {
            if (_trim(percent).match(/%$/)) {
                return parseFloat(percent) / 100 * all;
            }

            return parseFloat(percent);
        }

        return percent == null ? NaN : +percent;
    };

    /**
     * Fix rounding error of float numbers
     * @param {number} x
     * @return {number}
     */
    number.round = function (x) {
        // PENDING
        return +(+x).toFixed(10);
    };

    number.asc = function (arr) {
        arr.sort(function (a, b) {
            return a - b;
        });
        return arr;
    };

    /**
     * Get precision
     * @param {number} val
     */
    number.getPrecision = function (val) {
        if (isNaN(val)) {
            return 0;
        }
        // It is much faster than methods converting number to string as follows
        //      var tmp = val.toString();
        //      return tmp.length - 1 - tmp.indexOf('.');
        // especially when precision is low
        var e = 1;
        var count = 0;
        while (Math.round(val * e) / e !== val) {
            e *= 10;
            count++;
        }
        return count;
    };

    /**
     * @param {Array.<number>} dataExtent
     * @param {Array.<number>} pixelExtent
     * @return {number}  precision
     */
    number.getPixelPrecision = function (dataExtent, pixelExtent) {
        var log = Math.log;
        var LN10 = Math.LN10;
        var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10);
        var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10);
        return Math.max(
            -dataQuantity + sizeQuantity,
            0
        );
    };

    // Number.MAX_SAFE_INTEGER, ie do not support.
    number.MAX_SAFE_INTEGER = 9007199254740991;

    /**
     * To 0 - 2 * PI, considering negative radian.
     * @param {number} radian
     * @return {number}
     */
    number.remRadian = function (radian) {
        var pi2 = Math.PI * 2;
        return (radian % pi2 + pi2) % pi2;
    };

    /**
     * @param {type} radian
     * @return {boolean}
     */
    number.isRadianAroundZero = function (val) {
        return val > -RADIAN_EPSILON && val < RADIAN_EPSILON;
    };

    /**
     * @param {string|Date|number} value
     * @return {number} timestamp
     */
    number.parseDate = function (value) {
        return value instanceof Date
            ? value
            : new Date(
                typeof value === 'string'
                    // FIXME Date.parse('1970-01-01') is UTC, Date.parse('1970/01/01') is local
                    ? (new Date(value.replace(/-/g, '/')) - new Date('1970/01/01'))
                    : Math.round(value)
            );
    };

    /**
     * Quantity of a number. e.g. 0.1, 1, 10, 100
     * @param  {number} val
     * @return {number}
     */
    number.quantity = function (val) {
        return Math.pow(10, Math.floor(Math.log(val) / Math.LN10));
    };

    // "Nice Numbers for Graph Labels" of Graphic Gems
    /**
     * find a “nice” number approximately equal to x. Round the number if round = true, take ceiling if round = false
     * The primary observation is that the “nicest” numbers in decimal are 1, 2, and 5, and all power-of-ten multiples of these numbers.
     * @param  {number} val
     * @param  {boolean} round
     * @return {number}
     */
    number.nice = function (val, round) {
        var exp10 = number.quantity(val);
        var f = val / exp10; // between 1 and 10
        var nf;
        if (round) {
            if (f < 1.5) { nf = 1; }
            else if (f < 2.5) { nf = 2; }
            else if (f < 4) { nf = 3; }
            else if (f < 7) { nf = 5; }
            else { nf = 10; }
        }
        else {
            if (f < 1) { nf = 1; }
            else if (f < 2) { nf = 2; }
            else if (f < 3) { nf = 3; }
            else if (f < 5) { nf = 5; }
            else { nf = 10; }
        }
        return nf * exp10;
    };

    return number;
});<commit_msg>number.getPrecision convert string to number. Fix #3585<commit_after>/**
 * 数值处理模块
 * @module echarts/util/number
 */

define(function (require) {

    var number = {};

    var RADIAN_EPSILON = 1e-4;

    function _trim(str) {
        return str.replace(/^\s+/, '').replace(/\s+$/, '');
    }

    /**
     * Linear mapping a value from domain to range
     * @memberOf module:echarts/util/number
     * @param  {(number|Array.<number>)} val
     * @param  {Array.<number>} domain Domain extent domain[0] can be bigger than domain[1]
     * @param  {Array.<number>} range  Range extent range[0] can be bigger than range[1]
     * @param  {boolean} clamp
     * @return {(number|Array.<number>}
     */
    number.linearMap = function (val, domain, range, clamp) {
        var subDomain = domain[1] - domain[0];
        var subRange = range[1] - range[0];

        if (subDomain === 0) {
            return subRange === 0
                ? range[0]
                : (range[0] + range[1]) / 2;
        }

        // Avoid accuracy problem in edge, such as
        // 146.39 - 62.83 === 83.55999999999999.
        // See echarts/test/ut/spec/util/number.js#linearMap#accuracyError
        // It is a little verbose for efficiency considering this method
        // is a hotspot.
        if (clamp) {
            if (subDomain > 0) {
                if (val <= domain[0]) {
                    return range[0];
                }
                else if (val >= domain[1]) {
                    return range[1];
                }
            }
            else {
                if (val >= domain[0]) {
                    return range[0];
                }
                else if (val <= domain[1]) {
                    return range[1];
                }
            }
        }
        else {
            if (val === domain[0]) {
                return range[0];
            }
            if (val === domain[1]) {
                return range[1];
            }
        }

        return (val - domain[0]) / subDomain * subRange + range[0];
    };

    /**
     * Convert a percent string to absolute number.
     * Returns NaN if percent is not a valid string or number
     * @memberOf module:echarts/util/number
     * @param {string|number} percent
     * @param {number} all
     * @return {number}
     */
    number.parsePercent = function(percent, all) {
        switch (percent) {
            case 'center':
            case 'middle':
                percent = '50%';
                break;
            case 'left':
            case 'top':
                percent = '0%';
                break;
            case 'right':
            case 'bottom':
                percent = '100%';
                break;
        }
        if (typeof percent === 'string') {
            if (_trim(percent).match(/%$/)) {
                return parseFloat(percent) / 100 * all;
            }

            return parseFloat(percent);
        }

        return percent == null ? NaN : +percent;
    };

    /**
     * Fix rounding error of float numbers
     * @param {number} x
     * @return {number}
     */
    number.round = function (x) {
        // PENDING
        return +(+x).toFixed(10);
    };

    number.asc = function (arr) {
        arr.sort(function (a, b) {
            return a - b;
        });
        return arr;
    };

    /**
     * Get precision
     * @param {number} val
     */
    number.getPrecision = function (val) {
        val = +val;
        if (isNaN(val)) {
            return 0;
        }
        // It is much faster than methods converting number to string as follows
        //      var tmp = val.toString();
        //      return tmp.length - 1 - tmp.indexOf('.');
        // especially when precision is low
        var e = 1;
        var count = 0;
        while (Math.round(val * e) / e !== val) {
            e *= 10;
            count++;
        }
        return count;
    };

    /**
     * @param {Array.<number>} dataExtent
     * @param {Array.<number>} pixelExtent
     * @return {number}  precision
     */
    number.getPixelPrecision = function (dataExtent, pixelExtent) {
        var log = Math.log;
        var LN10 = Math.LN10;
        var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10);
        var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10);
        return Math.max(
            -dataQuantity + sizeQuantity,
            0
        );
    };

    // Number.MAX_SAFE_INTEGER, ie do not support.
    number.MAX_SAFE_INTEGER = 9007199254740991;

    /**
     * To 0 - 2 * PI, considering negative radian.
     * @param {number} radian
     * @return {number}
     */
    number.remRadian = function (radian) {
        var pi2 = Math.PI * 2;
        return (radian % pi2 + pi2) % pi2;
    };

    /**
     * @param {type} radian
     * @return {boolean}
     */
    number.isRadianAroundZero = function (val) {
        return val > -RADIAN_EPSILON && val < RADIAN_EPSILON;
    };

    /**
     * @param {string|Date|number} value
     * @return {number} timestamp
     */
    number.parseDate = function (value) {
        return value instanceof Date
            ? value
            : new Date(
                typeof value === 'string'
                    // FIXME Date.parse('1970-01-01') is UTC, Date.parse('1970/01/01') is local
                    ? (new Date(value.replace(/-/g, '/')) - new Date('1970/01/01'))
                    : Math.round(value)
            );
    };

    /**
     * Quantity of a number. e.g. 0.1, 1, 10, 100
     * @param  {number} val
     * @return {number}
     */
    number.quantity = function (val) {
        return Math.pow(10, Math.floor(Math.log(val) / Math.LN10));
    };

    // "Nice Numbers for Graph Labels" of Graphic Gems
    /**
     * find a “nice” number approximately equal to x. Round the number if round = true, take ceiling if round = false
     * The primary observation is that the “nicest” numbers in decimal are 1, 2, and 5, and all power-of-ten multiples of these numbers.
     * @param  {number} val
     * @param  {boolean} round
     * @return {number}
     */
    number.nice = function (val, round) {
        var exp10 = number.quantity(val);
        var f = val / exp10; // between 1 and 10
        var nf;
        if (round) {
            if (f < 1.5) { nf = 1; }
            else if (f < 2.5) { nf = 2; }
            else if (f < 4) { nf = 3; }
            else if (f < 7) { nf = 5; }
            else { nf = 10; }
        }
        else {
            if (f < 1) { nf = 1; }
            else if (f < 2) { nf = 2; }
            else if (f < 3) { nf = 3; }
            else if (f < 5) { nf = 5; }
            else { nf = 10; }
        }
        return nf * exp10;
    };

    return number;
});<|endoftext|>


<commit_before>/**
 * @ngdoc controller
 * @name Umbraco.Editors.BlockList.BlockConfigurationController
 * @function
 *
 * @description
 * The controller for the content type editor property settings dialog
 */

(function () {
    "use strict";

    function TransferProperties(fromObject, toObject) {
        for (var p in fromObject) {
            toObject[p] = fromObject[p];
        }
    }

    function BlockConfigurationController($scope, elementTypeResource, overlayService, localizationService, editorService) {

        var vm = this;

        vm.openBlock = null;

        function onInit() {

            if (!$scope.model.value) {
                $scope.model.value = [];
            }

            loadElementTypes();

        }

        function loadElementTypes() {
            return elementTypeResource.getAll().then(function (elementTypes) {
                vm.elementTypes = elementTypes;
            });
        }

        vm.requestRemoveBlockByIndex = function (index) {
            localizationService.localizeMany(["general_delete", "blockEditor_confirmDeleteBlockMessage", "blockEditor_confirmDeleteBlockNotice"]).then(function (data) {
                var contentElementType = vm.getElementTypeByKey($scope.model.value[index].contentTypeKey);
                overlayService.confirmDelete({
                    title: data[0],
                    content: localizationService.tokenReplace(data[1], [contentElementType.name]),
                    confirmMessage: data[2],
                    close: function () {
                        overlayService.close();
                    },
                    submit: function () {
                        vm.removeBlockByIndex(index);
                        overlayService.close();
                    }
                });
            });
        }

        vm.removeBlockByIndex = function (index) {
            $scope.model.value.splice(index, 1);
        };

        vm.sortableOptions = {
            "ui-floating": true,
            items: "umb-block-card",
            cursor: "grabbing",
            placeholder: 'umb-block-card --sortable-placeholder'
        };

        vm.getAvailableElementTypes = function () {
            return vm.elementTypes.filter(function (type) {
                return !$scope.model.value.find(function (entry) {
                    return type.key === entry.contentTypeKey;
                });
            });
        };

        vm.getElementTypeByKey = function(key) {
            return _.find(vm.elementTypes, function (type) {
                return type.key === key;
            });
        };

        vm.openAddDialog = function ($event, entry) {

            //we have to add the 'alias' property to the objects, to make the data match the requirements of itempicker.
            var selectedItems = _.each(Utilities.copy($scope.model.value), function (obj) {
                obj.alias = vm.getElementTypeByKey(obj.contentTypeKey).alias;
                return obj;
            });

            var availableItems = vm.getAvailableElementTypes()

            localizationService.localizeMany(["blockEditor_headlineCreateBlock", "blockEditor_labelcreateNewElementType"]).then(function(localized) {

                var elemTypeSelectorOverlay = {
                    view: "itempicker",
                    title: localized[0],
                    availableItems: availableItems,
                    selectedItems: selectedItems,
                    createNewItem: {
                        action: function() {
                            overlayService.close();
                            vm.createElementTypeAndAdd(vm.addBlockFromElementTypeKey);
                        },
                        icon: "icon-add",
                        name: localized[1]
                    },
                    position: "target",
                    event: $event,
                    size: availableItems.length < 7 ? "small" : "medium",
                    submit: function (overlay) {
                        vm.addBlockFromElementTypeKey(overlay.selectedItem.key);
                        overlayService.close();
                    },
                    close: function () {
                        overlayService.close();
                    }
                };

                overlayService.open(elemTypeSelectorOverlay);

            });
        };

        vm.createElementTypeAndAdd = function(callback) {
            const editor = {
                create: true,
                infiniteMode: true,
                isElement: true,
                submit: function (model) {
                    loadElementTypes().then( function () {
                        callback(model.documentTypeKey);
                    });
                    editorService.close();
                },
                close: function () {
                    editorService.close();
                }
            };
            editorService.documentTypeEditor(editor);
        }

        vm.addBlockFromElementTypeKey = function(key) {

            var entry = {
                "contentTypeKey": key,
                "view": null,
                "labelTemplate": "",
                "settingsElementTypeKey": null
            };

            $scope.model.value.push(entry);
        };

        vm.openBlockOverlay = function (block) {

            localizationService.localize("blockEditor_blockConfigurationOverlayTitle", [vm.getElementTypeByKey(block.contentTypeKey).name]).then(function (data) {

                var clonedBlockData = Utilities.copy(block);
                vm.openBlock = block;

                var overlayModel = {
                    block: clonedBlockData,
                    title: data,
                    view: "views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.html",
                    size: "small",
                    submit: function(overlayModel) {
                        TransferProperties(overlayModel.block, block);// transfer properties back to block object. (Doing this cause we dont know if block object is added to model jet, therefor we cant use index or replace the object.)
                        overlayModel.close();
                    },
                    close: function() {
                        editorService.close();
                        vm.openBlock = null;
                    }
                };

                // open property settings editor
                editorService.open(overlayModel);

            });

        };

        onInit();

    }

    angular.module("umbraco").controller("Umbraco.PropertyEditors.BlockList.BlockConfigurationController", BlockConfigurationController);

})();
<commit_msg>define the full model for new configurations<commit_after>/**
 * @ngdoc controller
 * @name Umbraco.Editors.BlockList.BlockConfigurationController
 * @function
 *
 * @description
 * The controller for the content type editor property settings dialog
 */

(function () {
    "use strict";

    function TransferProperties(fromObject, toObject) {
        for (var p in fromObject) {
            toObject[p] = fromObject[p];
        }
    }

    function BlockConfigurationController($scope, elementTypeResource, overlayService, localizationService, editorService) {

        var vm = this;

        vm.openBlock = null;

        function onInit() {

            if (!$scope.model.value) {
                $scope.model.value = [];
            }

            loadElementTypes();

        }

        function loadElementTypes() {
            return elementTypeResource.getAll().then(function (elementTypes) {
                vm.elementTypes = elementTypes;
            });
        }

        vm.requestRemoveBlockByIndex = function (index) {
            localizationService.localizeMany(["general_delete", "blockEditor_confirmDeleteBlockMessage", "blockEditor_confirmDeleteBlockNotice"]).then(function (data) {
                var contentElementType = vm.getElementTypeByKey($scope.model.value[index].contentTypeKey);
                overlayService.confirmDelete({
                    title: data[0],
                    content: localizationService.tokenReplace(data[1], [contentElementType.name]),
                    confirmMessage: data[2],
                    close: function () {
                        overlayService.close();
                    },
                    submit: function () {
                        vm.removeBlockByIndex(index);
                        overlayService.close();
                    }
                });
            });
        }

        vm.removeBlockByIndex = function (index) {
            $scope.model.value.splice(index, 1);
        };

        vm.sortableOptions = {
            "ui-floating": true,
            items: "umb-block-card",
            cursor: "grabbing",
            placeholder: 'umb-block-card --sortable-placeholder'
        };

        vm.getAvailableElementTypes = function () {
            return vm.elementTypes.filter(function (type) {
                return !$scope.model.value.find(function (entry) {
                    return type.key === entry.contentTypeKey;
                });
            });
        };

        vm.getElementTypeByKey = function(key) {
            return _.find(vm.elementTypes, function (type) {
                return type.key === key;
            });
        };

        vm.openAddDialog = function ($event, entry) {

            //we have to add the 'alias' property to the objects, to make the data match the requirements of itempicker.
            var selectedItems = _.each(Utilities.copy($scope.model.value), function (obj) {
                obj.alias = vm.getElementTypeByKey(obj.contentTypeKey).alias;
                return obj;
            });

            var availableItems = vm.getAvailableElementTypes()

            localizationService.localizeMany(["blockEditor_headlineCreateBlock", "blockEditor_labelcreateNewElementType"]).then(function(localized) {

                var elemTypeSelectorOverlay = {
                    view: "itempicker",
                    title: localized[0],
                    availableItems: availableItems,
                    selectedItems: selectedItems,
                    createNewItem: {
                        action: function() {
                            overlayService.close();
                            vm.createElementTypeAndAdd(vm.addBlockFromElementTypeKey);
                        },
                        icon: "icon-add",
                        name: localized[1]
                    },
                    position: "target",
                    event: $event,
                    size: availableItems.length < 7 ? "small" : "medium",
                    submit: function (overlay) {
                        vm.addBlockFromElementTypeKey(overlay.selectedItem.key);
                        overlayService.close();
                    },
                    close: function () {
                        overlayService.close();
                    }
                };

                overlayService.open(elemTypeSelectorOverlay);

            });
        };

        vm.createElementTypeAndAdd = function(callback) {
            const editor = {
                create: true,
                infiniteMode: true,
                isElement: true,
                submit: function (model) {
                    loadElementTypes().then( function () {
                        callback(model.documentTypeKey);
                    });
                    editorService.close();
                },
                close: function () {
                    editorService.close();
                }
            };
            editorService.documentTypeEditor(editor);
        }

        vm.addBlockFromElementTypeKey = function(key) {

            var entry = {
                "contentTypeKey": key,
                "settingsElementTypeKey": null,
                "labelTemplate": "",
                "view": null,
                "stylesheet": null,
                "editorSize": "small",
                "iconColor": null,
                "backgroundColor": null,
                "thumbnail": null
            };

            $scope.model.value.push(entry);
        };

        vm.openBlockOverlay = function (block) {

            localizationService.localize("blockEditor_blockConfigurationOverlayTitle", [vm.getElementTypeByKey(block.contentTypeKey).name]).then(function (data) {

                var clonedBlockData = Utilities.copy(block);
                vm.openBlock = block;

                var overlayModel = {
                    block: clonedBlockData,
                    title: data,
                    view: "views/propertyeditors/blocklist/prevalue/blocklist.blockconfiguration.overlay.html",
                    size: "small",
                    submit: function(overlayModel) {
                        TransferProperties(overlayModel.block, block);// transfer properties back to block object. (Doing this cause we dont know if block object is added to model jet, therefor we cant use index or replace the object.)
                        overlayModel.close();
                    },
                    close: function() {
                        editorService.close();
                        vm.openBlock = null;
                    }
                };

                // open property settings editor
                editorService.open(overlayModel);

            });

        };

        onInit();

    }

    angular.module("umbraco").controller("Umbraco.PropertyEditors.BlockList.BlockConfigurationController", BlockConfigurationController);

})();
<|endoftext|>


<commit_before>/**
 * 超链接
 *
 * Created by GUY on 2015/9/9.
 * @class BI.A
 * @extends BI.Text
 * @abstract
 */
BI.A = BI.inherit(BI.Text, {
    _defaultConfig: function () {
        var conf = BI.A.superclass._defaultConfig.apply(this, arguments);
        return BI.extend(conf, {
            baseCls: (conf.baseCls || "") + " bi-a display-block",
            href: "",
            target: "_blank",
            el: null,
            tagName: "a"
        });
    },

    render: function () {
        var o = this.options;
        this.element.attr({href: o.href, target: o.target});
        if (o.el) {
            BI.createWidget(o.el, {
                element: this
            });
        }
    }
});

BI.shortcut("bi.a", BI.A);
<commit_msg>DEC-20930 fix: 【自动化】平台登录页的品牌信息不可见<commit_after>/**
 * 超链接
 *
 * Created by GUY on 2015/9/9.
 * @class BI.A
 * @extends BI.Text
 * @abstract
 */
BI.A = BI.inherit(BI.Text, {
    _defaultConfig: function () {
        var conf = BI.A.superclass._defaultConfig.apply(this, arguments);
        return BI.extend(conf, {
            baseCls: (conf.baseCls || "") + " bi-a display-block",
            href: "",
            target: "_blank",
            el: null,
            tagName: "a"
        });
    },

    _init: function () {
        var o = this.options;
        BI.A.superclass._init.apply(this, arguments);
        this.element.attr({href: o.href, target: o.target});
        if (o.el) {
            BI.createWidget(o.el, {
                element: this
            });
        }
    }
});

BI.shortcut("bi.a", BI.A);
<|endoftext|>


<commit_before>
setDefaults({
	weekMode: 'fixed'
});

function BasicView(element, calendar, viewName) {
	var t = this;

	// exports
	t.renderBasic = renderBasic;
	t.setHeight = setHeight;
	t.setWidth = setWidth;
	t.renderDayOverlay = renderDayOverlay;
	t.defaultSelectionEnd = defaultSelectionEnd;
	t.renderSelection = renderSelection;
	t.clearSelection = clearSelection;
	t.reportDayClick = reportDayClick; // for selection (kinda hacky)
	t.dragStart = dragStart;
	t.dragStop = dragStop;
	t.defaultEventEnd = defaultEventEnd;
	t.getHoverListener = function() { return hoverListener };
	t.colContentLeft = colContentLeft;
	t.colContentRight = colContentRight;
	t.dayOfWeekCol = dayOfWeekCol;
	t.dateCell = dateCell;
	t.cellDate = cellDate;
	t.cellIsAllDay = function() { return true };
	t.allDayRow = allDayRow;
	t.allDayBounds = allDayBounds;
	t.getRowCnt = function() { return rowCnt };
	t.getColCnt = function() { return colCnt };
	t.getColWidth = function() { return colWidth };
	t.getDaySegmentContainer = function() { return daySegmentContainer };

	// imports
	View.call(t, element, calendar, viewName);
	OverlayManager.call(t);
	SelectionManager.call(t);
	BasicEventRenderer.call(t);
	var opt = t.opt;
	var trigger = t.trigger;
	var clearEvents = t.clearEvents;
	var renderOverlay = t.renderOverlay;
	var clearOverlays = t.clearOverlays;
	var daySelectionMousedown = t.daySelectionMousedown;
	var formatDate = calendar.formatDate;

	// locals

	var head;
	var headCells;
	var body;
	var bodyRows;
	var bodyCells;
	var bodyFirstCells;
	var bodyCellTopInners;
	var daySegmentContainer;

	var viewWidth;
	var viewHeight;
	var colWidth;

	var rowCnt, colCnt;
	var coordinateGrid;
	var hoverListener;
	var colContentPositions;

	var rtl, dis, dit;
	var firstDay;
	var nwe;
	var tm;
	var colFormat;

	/* Rendering
	------------------------------------------------------------*/

	disableTextSelection(element.addClass('fc-grid'));

	function renderBasic(maxr, r, c, showNumbers) {
		rowCnt = r;
		colCnt = c;
		updateOptions();
		var firstTime = !body;
		if (firstTime) {
			buildSkeleton(maxr, showNumbers);
		}else{
			clearEvents();
		}
		updateCells(firstTime);
	}

	function updateOptions() {
		rtl = opt('isRTL');
		if (rtl) {
			dis = -1;
			dit = colCnt - 1;
		}else{
			dis = 1;
			dit = 0;
		}
		firstDay = opt('firstDay');
		nwe = opt('weekends') ? 0 : 1;
		tm = opt('theme') ? 'ui' : 'fc';
		colFormat = opt('columnFormat');
	}

	function buildSkeleton(maxRowCnt, showNumbers) {
		var s;
		var headerClass = tm + "-widget-header";
		var contentClass = tm + "-widget-content";
		var i, j;
		var table;

		s =
			"
" +
			"
" +
			"
";
		for (i=0; i<colCnt; i++) {
			s +=
				""; // need fc- for setDayID
		}
		s +=
			"
" +
			"
" +
			"
";
		for (i=0; i<maxRowCnt; i++) {
			s +=
				"
";
			for (j=0; j<colCnt; j++) {
				s +=
					"" + // need fc- for setDayID
					"
" +
					(showNumbers ?
						"
" :
						''
						) +
					"
" +
					"

" +
					"
" +
					"
" +
					"	";
			}
			s +=
				"
";
		}
		s +=
			"
" +
			"
";
		table = $(s).appendTo(element);

		head = table.find('thead');
		headCells = head.find('th');
		body = table.find('tbody');
		bodyRows = body.find('tr');
		bodyCells = body.find('td');
		bodyFirstCells = bodyCells.filter(':first-child');
		bodyCellTopInners = bodyRows.eq(0).find('div.fc-day-content div');

		markFirstLast(head.add(head.find('tr'))); // marks first+last tr/th's
		markFirstLast(bodyRows); // marks first+last td's
		bodyRows.eq(0).addClass('fc-first'); // fc-last is done in updateCells

		dayBind(bodyCells);

		daySegmentContainer =
			$("
")
				.appendTo(element);
	}

	function updateCells(firstTime) {
		var dowDirty = firstTime || rowCnt == 1; // could the cells' day-of-weeks need updating?
		var month = t.start.getMonth();
		var today = clearTime(new Date());
		var cell;
		var date;
		var row;

		if (dowDirty) {
			headCells.each(function(i, _cell) {
				cell = $(_cell);
				date = indexDate(i);
				cell.html(formatDate(date, colFormat));
				setDayID(cell, date);
			});
		}

		bodyCells.each(function(i, _cell) {
			cell = $(_cell);
			date = indexDate(i);
			if (date.getMonth() == month) {
				cell.removeClass('fc-other-month');
			}else{
				cell.addClass('fc-other-month');
			}
			if (+date == +today) {
				cell.addClass(tm + '-state-highlight fc-today');
			}else{
				cell.removeClass(tm + '-state-highlight fc-today');
			}
			cell.find('div.fc-day-number').text(date.getDate());
			if (dowDirty) {
				setDayID(cell, date);
			}
		});

		bodyRows.each(function(i, _row) {
			row = $(_row);
			if (i < rowCnt) {
				row.show();
				if (i == rowCnt-1) {
					row.addClass('fc-last');
				}else{
					row.removeClass('fc-last');
				}
			}else{
				row.hide();
			}
		});
	}

	function setHeight(height) {
		viewHeight = height;

		var bodyHeight = viewHeight - head.height();
		var rowHeight;
		var rowHeightLast;
		var cell;

		if (opt('weekMode') == 'variable') {
			rowHeight = rowHeightLast = Math.floor(bodyHeight / (rowCnt==1 ? 2 : 6));
		}else{
			rowHeight = Math.floor(bodyHeight / rowCnt);
			rowHeightLast = bodyHeight - rowHeight * (rowCnt-1);
		}

		bodyFirstCells.each(function(i, _cell) {
			if (i < rowCnt) {
				cell = $(_cell);
				setMinHeight(
					cell.find('> div'),
					(i==rowCnt-1 ? rowHeightLast : rowHeight) - vsides(cell)
				);
			}
		});

	}

	function setWidth(width) {
		viewWidth = width;
		colContentPositions.clear();
		colWidth = Math.floor(viewWidth / colCnt);
		setOuterWidth(headCells.slice(0, -1), colWidth);
	}

	/* Day clicking and binding
	-----------------------------------------------------------*/

	function dayBind(days) {
		days.click(dayClick)
			.mousedown(daySelectionMousedown);
	}

	function dayClick(ev) {
		if (!opt('selectable')) { // if selectable, SelectionManager will worry about dayClick
			var index = parseInt(this.className.match(/fc\-day(\d+)/)[1]); // TODO: maybe use .data
			var date = indexDate(index);
			trigger('dayClick', this, date, true, ev);
		}
	}

	/* Semi-transparent Overlay Helpers
	------------------------------------------------------*/

	function renderDayOverlay(overlayStart, overlayEnd, refreshCoordinateGrid) { // overlayEnd is exclusive
		if (refreshCoordinateGrid) {
			coordinateGrid.build();
		}
		var rowStart = cloneDate(t.visStart);
		var rowEnd = addDays(cloneDate(rowStart), colCnt);
		for (var i=0; i<rowCnt; i++) {
			var stretchStart = new Date(Math.max(rowStart, overlayStart));
			var stretchEnd = new Date(Math.min(rowEnd, overlayEnd));
			if (stretchStart < stretchEnd) {
				var colStart, colEnd;
				if (rtl) {
					colStart = dayDiff(stretchEnd, rowStart)*dis+dit+1;
					colEnd = dayDiff(stretchStart, rowStart)*dis+dit+1;
				}else{
					colStart = dayDiff(stretchStart, rowStart);
					colEnd = dayDiff(stretchEnd, rowStart);
				}
				dayBind(
					renderCellOverlay(i, colStart, i, colEnd-1)
				);
			}
			addDays(rowStart, 7);
			addDays(rowEnd, 7);
		}
	}

	function renderCellOverlay(row0, col0, row1, col1) { // row1,col1 is inclusive
		var rect = coordinateGrid.rect(row0, col0, row1, col1, element);
		return renderOverlay(rect, element);
	}

	/* Selection
	-----------------------------------------------------------------------*/

	function defaultSelectionEnd(startDate, allDay) {
		return cloneDate(startDate);
	}

	function renderSelection(startDate, endDate, allDay) {
		renderDayOverlay(startDate, addDays(cloneDate(endDate), 1), true); // rebuild every time???
	}

	function clearSelection() {
		clearOverlays();
	}

	function reportDayClick(date, allDay, ev) {
		var cell = dateCell(date);
		var _element = bodyCells[cell.row*colCnt + cell.col];
		trigger('dayClick', _element, date, allDay, ev);
	}

	/* External Dragging
	-----------------------------------------------------------------------*/

	function dragStart(_dragElement, ev, ui) {
		hoverListener.start(function(cell) {
			clearOverlays();
			if (cell) {
				renderCellOverlay(cell.row, cell.col, cell.row, cell.col);
			}
		}, ev);
	}

	function dragStop(_dragElement, ev, ui) {
		var cell = hoverListener.stop();
		clearOverlays();
		if (cell) {
			var d = cellDate(cell);
			trigger('drop', _dragElement, d, true, ev, ui);
		}
	}

	/* Utilities
	--------------------------------------------------------*/

	function defaultEventEnd(event) {
		return cloneDate(event.start);
	}

	coordinateGrid = new CoordinateGrid(function(rows, cols) {
		var e, n, p;
		headCells.each(function(i, _e) {
			e = $(_e);
			n = e.offset().left;
			if (i) {
				p[1] = n;
			}
			p = [n];
			cols[i] = p;
		});
		p[1] = n + e.outerWidth();
		bodyRows.each(function(i, _e) {
			if (i < rowCnt) {
				e = $(_e);
				n = e.offset().top;
				if (i) {
					p[1] = n;
				}
				p = [n];
				rows[i] = p;
			}
		});
		p[1] = n + e.outerHeight();
	});

	hoverListener = new HoverListener(coordinateGrid);

	colContentPositions = new HorizontalPositionCache(function(col) {
		return bodyCellTopInners.eq(col);
	});

	function colContentLeft(col) {
		return colContentPositions.left(col);
	}

	function colContentRight(col) {
		return colContentPositions.right(col);
	}

	function dateCell(date) {
		return {
			row: Math.floor(dayDiff(date, t.visStart) / 7),
			col: dayOfWeekCol(date.getDay())
		};
	}

	function cellDate(cell) {
		return _cellDate(cell.row, cell.col);
	}

	function _cellDate(row, col) {
		return addDays(cloneDate(t.visStart), row*7 + col*dis+dit);
		// what about weekends in middle of week?
	}

	function indexDate(index) {
		return _cellDate(Math.floor(index/colCnt), index%colCnt);
	}

	function dayOfWeekCol(dayOfWeek) {
		return ((dayOfWeek - Math.max(firstDay, nwe) + colCnt) % colCnt) * dis + dit;
	}

	function allDayRow(i) {
		return bodyRows.eq(i);
	}

	function allDayBounds(i) {
		return {
			left: 0,
			right: viewWidth
		};
	}

}
<commit_msg>Added dayRender trigger<commit_after>
setDefaults({
	weekMode: 'fixed'
});

function BasicView(element, calendar, viewName) {
	var t = this;

	// exports
	t.renderBasic = renderBasic;
	t.setHeight = setHeight;
	t.setWidth = setWidth;
	t.renderDayOverlay = renderDayOverlay;
	t.defaultSelectionEnd = defaultSelectionEnd;
	t.renderSelection = renderSelection;
	t.clearSelection = clearSelection;
	t.reportDayClick = reportDayClick; // for selection (kinda hacky)
	t.dragStart = dragStart;
	t.dragStop = dragStop;
	t.defaultEventEnd = defaultEventEnd;
	t.getHoverListener = function() { return hoverListener };
	t.colContentLeft = colContentLeft;
	t.colContentRight = colContentRight;
	t.dayOfWeekCol = dayOfWeekCol;
	t.dateCell = dateCell;
	t.cellDate = cellDate;
	t.cellIsAllDay = function() { return true };
	t.allDayRow = allDayRow;
	t.allDayBounds = allDayBounds;
	t.getRowCnt = function() { return rowCnt };
	t.getColCnt = function() { return colCnt };
	t.getColWidth = function() { return colWidth };
	t.getDaySegmentContainer = function() { return daySegmentContainer };

	// imports
	View.call(t, element, calendar, viewName);
	OverlayManager.call(t);
	SelectionManager.call(t);
	BasicEventRenderer.call(t);
	var opt = t.opt;
	var trigger = t.trigger;
	var clearEvents = t.clearEvents;
	var renderOverlay = t.renderOverlay;
	var clearOverlays = t.clearOverlays;
	var daySelectionMousedown = t.daySelectionMousedown;
	var formatDate = calendar.formatDate;

	// locals

	var head;
	var headCells;
	var body;
	var bodyRows;
	var bodyCells;
	var bodyFirstCells;
	var bodyCellTopInners;
	var daySegmentContainer;

	var viewWidth;
	var viewHeight;
	var colWidth;

	var rowCnt, colCnt;
	var coordinateGrid;
	var hoverListener;
	var colContentPositions;

	var rtl, dis, dit;
	var firstDay;
	var nwe;
	var tm;
	var colFormat;

	/* Rendering
	------------------------------------------------------------*/

	disableTextSelection(element.addClass('fc-grid'));

	function renderBasic(maxr, r, c, showNumbers) {
		rowCnt = r;
		colCnt = c;
		updateOptions();
		var firstTime = !body;
		if (firstTime) {
			buildSkeleton(maxr, showNumbers);
		}else{
			clearEvents();
		}
		updateCells(firstTime);
	}

	function updateOptions() {
		rtl = opt('isRTL');
		if (rtl) {
			dis = -1;
			dit = colCnt - 1;
		}else{
			dis = 1;
			dit = 0;
		}
		firstDay = opt('firstDay');
		nwe = opt('weekends') ? 0 : 1;
		tm = opt('theme') ? 'ui' : 'fc';
		colFormat = opt('columnFormat');
	}

	function buildSkeleton(maxRowCnt, showNumbers) {
		var s;
		var headerClass = tm + "-widget-header";
		var contentClass = tm + "-widget-content";
		var i, j;
		var table;

		s =
			"
" +
			"
" +
			"
";
		for (i=0; i<colCnt; i++) {
			s +=
				""; // need fc- for setDayID
		}
		s +=
			"
" +
			"
" +
			"
";
		for (i=0; i<maxRowCnt; i++) {
			s +=
				"
";
			for (j=0; j<colCnt; j++) {
				s +=
					"" + // need fc- for setDayID
					"
" +
					(showNumbers ?
						"
" :
						''
						) +
					"
" +
					"

" +
					"
" +
					"
" +
					"	";
			}
			s +=
				"
";
		}
		s +=
			"
" +
			"
";
		table = $(s).appendTo(element);

		head = table.find('thead');
		headCells = head.find('th');
		body = table.find('tbody');
		bodyRows = body.find('tr');
		bodyCells = body.find('td');
		bodyFirstCells = bodyCells.filter(':first-child');
		bodyCellTopInners = bodyRows.eq(0).find('div.fc-day-content div');

		markFirstLast(head.add(head.find('tr'))); // marks first+last tr/th's
		markFirstLast(bodyRows); // marks first+last td's
		bodyRows.eq(0).addClass('fc-first'); // fc-last is done in updateCells

		dayBind(bodyCells);

		daySegmentContainer =
			$("
")
				.appendTo(element);
	}

	function updateCells(firstTime) {
		var dowDirty = firstTime || rowCnt == 1; // could the cells' day-of-weeks need updating?
		var month = t.start.getMonth();
		var today = clearTime(new Date());
		var cell;
		var date;
		var row;

		if (dowDirty) {
			headCells.each(function(i, _cell) {
				cell = $(_cell);
				date = indexDate(i);
				cell.html(formatDate(date, colFormat));
				setDayID(cell, date);
			});
		}

		bodyCells.each(function(i, _cell) {
			cell = $(_cell);
			date = indexDate(i);
			if (date.getMonth() == month) {
				cell.removeClass('fc-other-month');
			}else{
				cell.addClass('fc-other-month');
			}
			if (+date == +today) {
				cell.addClass(tm + '-state-highlight fc-today');
			}else{
				cell.removeClass(tm + '-state-highlight fc-today');
			}
			cell.find('div.fc-day-number').text(date.getDate());
			trigger('dayRender', t, date, cell);
			if (dowDirty) {
				setDayID(cell, date);
			}
		});

		bodyRows.each(function(i, _row) {
			row = $(_row);
			if (i < rowCnt) {
				row.show();
				if (i == rowCnt-1) {
					row.addClass('fc-last');
				}else{
					row.removeClass('fc-last');
				}
			}else{
				row.hide();
			}
		});
	}

	function setHeight(height) {
		viewHeight = height;

		var bodyHeight = viewHeight - head.height();
		var rowHeight;
		var rowHeightLast;
		var cell;

		if (opt('weekMode') == 'variable') {
			rowHeight = rowHeightLast = Math.floor(bodyHeight / (rowCnt==1 ? 2 : 6));
		}else{
			rowHeight = Math.floor(bodyHeight / rowCnt);
			rowHeightLast = bodyHeight - rowHeight * (rowCnt-1);
		}

		bodyFirstCells.each(function(i, _cell) {
			if (i < rowCnt) {
				cell = $(_cell);
				setMinHeight(
					cell.find('> div'),
					(i==rowCnt-1 ? rowHeightLast : rowHeight) - vsides(cell)
				);
			}
		});

	}

	function setWidth(width) {
		viewWidth = width;
		colContentPositions.clear();
		colWidth = Math.floor(viewWidth / colCnt);
		setOuterWidth(headCells.slice(0, -1), colWidth);
	}

	/* Day clicking and binding
	-----------------------------------------------------------*/

	function dayBind(days) {
		days.click(dayClick)
			.mousedown(daySelectionMousedown);
	}

	function dayClick(ev) {
		if (!opt('selectable')) { // if selectable, SelectionManager will worry about dayClick
			var index = parseInt(this.className.match(/fc\-day(\d+)/)[1]); // TODO: maybe use .data
			var date = indexDate(index);
			trigger('dayClick', this, date, true, ev);
		}
	}

	/* Semi-transparent Overlay Helpers
	------------------------------------------------------*/

	function renderDayOverlay(overlayStart, overlayEnd, refreshCoordinateGrid) { // overlayEnd is exclusive
		if (refreshCoordinateGrid) {
			coordinateGrid.build();
		}
		var rowStart = cloneDate(t.visStart);
		var rowEnd = addDays(cloneDate(rowStart), colCnt);
		for (var i=0; i<rowCnt; i++) {
			var stretchStart = new Date(Math.max(rowStart, overlayStart));
			var stretchEnd = new Date(Math.min(rowEnd, overlayEnd));
			if (stretchStart < stretchEnd) {
				var colStart, colEnd;
				if (rtl) {
					colStart = dayDiff(stretchEnd, rowStart)*dis+dit+1;
					colEnd = dayDiff(stretchStart, rowStart)*dis+dit+1;
				}else{
					colStart = dayDiff(stretchStart, rowStart);
					colEnd = dayDiff(stretchEnd, rowStart);
				}
				dayBind(
					renderCellOverlay(i, colStart, i, colEnd-1)
				);
			}
			addDays(rowStart, 7);
			addDays(rowEnd, 7);
		}
	}

	function renderCellOverlay(row0, col0, row1, col1) { // row1,col1 is inclusive
		var rect = coordinateGrid.rect(row0, col0, row1, col1, element);
		return renderOverlay(rect, element);
	}

	/* Selection
	-----------------------------------------------------------------------*/

	function defaultSelectionEnd(startDate, allDay) {
		return cloneDate(startDate);
	}

	function renderSelection(startDate, endDate, allDay) {
		renderDayOverlay(startDate, addDays(cloneDate(endDate), 1), true); // rebuild every time???
	}

	function clearSelection() {
		clearOverlays();
	}

	function reportDayClick(date, allDay, ev) {
		var cell = dateCell(date);
		var _element = bodyCells[cell.row*colCnt + cell.col];
		trigger('dayClick', _element, date, allDay, ev);
	}

	/* External Dragging
	-----------------------------------------------------------------------*/

	function dragStart(_dragElement, ev, ui) {
		hoverListener.start(function(cell) {
			clearOverlays();
			if (cell) {
				renderCellOverlay(cell.row, cell.col, cell.row, cell.col);
			}
		}, ev);
	}

	function dragStop(_dragElement, ev, ui) {
		var cell = hoverListener.stop();
		clearOverlays();
		if (cell) {
			var d = cellDate(cell);
			trigger('drop', _dragElement, d, true, ev, ui);
		}
	}

	/* Utilities
	--------------------------------------------------------*/

	function defaultEventEnd(event) {
		return cloneDate(event.start);
	}

	coordinateGrid = new CoordinateGrid(function(rows, cols) {
		var e, n, p;
		headCells.each(function(i, _e) {
			e = $(_e);
			n = e.offset().left;
			if (i) {
				p[1] = n;
			}
			p = [n];
			cols[i] = p;
		});
		p[1] = n + e.outerWidth();
		bodyRows.each(function(i, _e) {
			if (i < rowCnt) {
				e = $(_e);
				n = e.offset().top;
				if (i) {
					p[1] = n;
				}
				p = [n];
				rows[i] = p;
			}
		});
		p[1] = n + e.outerHeight();
	});

	hoverListener = new HoverListener(coordinateGrid);

	colContentPositions = new HorizontalPositionCache(function(col) {
		return bodyCellTopInners.eq(col);
	});

	function colContentLeft(col) {
		return colContentPositions.left(col);
	}

	function colContentRight(col) {
		return colContentPositions.right(col);
	}

	function dateCell(date) {
		return {
			row: Math.floor(dayDiff(date, t.visStart) / 7),
			col: dayOfWeekCol(date.getDay())
		};
	}

	function cellDate(cell) {
		return _cellDate(cell.row, cell.col);
	}

	function _cellDate(row, col) {
		return addDays(cloneDate(t.visStart), row*7 + col*dis+dit);
		// what about weekends in middle of week?
	}

	function indexDate(index) {
		return _cellDate(Math.floor(index/colCnt), index%colCnt);
	}

	function dayOfWeekCol(dayOfWeek) {
		return ((dayOfWeek - Math.max(firstDay, nwe) + colCnt) % colCnt) * dis + dit;
	}

	function allDayRow(i) {
		return bodyRows.eq(i);
	}

	function allDayBounds(i) {
		return {
			left: 0,
			right: viewWidth
		};
	}

}
<|endoftext|>


<commit_before>import Utils from './utils';

class SwiperClass {
  constructor(params = {}) {
    const self = this;
    self.params = params;

    // Events
    self.eventsListeners = {};

    if (self.params && self.params.on) {
      Object.keys(self.params.on).forEach((eventName) => {
        self.on(eventName, self.params.on[eventName]);
      });
    }
  }

  on(events, handler, priority) {
    const self = this;
    if (typeof handler !== 'function') return self;
    const method = priority ? 'unshift' : 'push';
    events.split(' ').forEach((event) => {
      if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
      self.eventsListeners[event][method](handler);
    });
    return self;
  }

  once(events, handler, priority) {
    const self = this;
    if (typeof handler !== 'function') return self;
    function onceHandler(...args) {
      handler.apply(self, args);
      self.off(events, onceHandler);
    }
    return self.on(events, onceHandler, priority);
  }

  off(events, handler) {
    const self = this;
    if (!self.eventsListeners) return self;
    events.split(' ').forEach((event) => {
      if (typeof handler === 'undefined') {
        self.eventsListeners[event] = [];
      } else {
        self.eventsListeners[event].forEach((eventHandler, index) => {
          if (eventHandler === handler) {
            self.eventsListeners[event].splice(index, 1);
          }
        });
      }
    });
    return self;
  }

  emit(...args) {
    const self = this;
    if (!self.eventsListeners) return self;
    let events;
    let data;
    let context;
    if (typeof args[0] === 'string' || Array.isArray(args[0])) {
      events = args[0];
      data = args.slice(1, args.length);
      context = self;
    } else {
      events = args[0].events;
      data = args[0].data;
      context = args[0].context || self;
    }
    const eventsArray = Array.isArray(events) ? events : events.split(' ');
    eventsArray.forEach((event) => {
      if (self.eventsListeners && self.eventsListeners[event]) {
        const handlers = [];
        self.eventsListeners[event].forEach((eventHandler) => {
          handlers.push(eventHandler);
        });
        handlers.forEach((eventHandler) => {
          eventHandler.apply(context, data);
        });
      }
    });
    return self;
  }

  useModulesParams(instanceParams) {
    const instance = this;
    if (!instance.modules) return;
    Object.keys(instance.modules).forEach((moduleName) => {
      const module = instance.modules[moduleName];
      // Extend params
      if (module.params) {
        Utils.extend(instanceParams, module.params);
      }
    });
  }

  useModules(modulesParams = {}) {
    const instance = this;
    if (!instance.modules) return;
    Object.keys(instance.modules).forEach((moduleName) => {
      const module = instance.modules[moduleName];
      const moduleParams = modulesParams[moduleName] || {};
      // Extend instance methods and props
      if (module.instance) {
        Object.keys(module.instance).forEach((modulePropName) => {
          const moduleProp = module.instance[modulePropName];
          if (typeof moduleProp === 'function') {
            instance[modulePropName] = moduleProp.bind(instance);
          } else {
            instance[modulePropName] = moduleProp;
          }
        });
      }
      // Add event listeners
      if (module.on && instance.on) {
        Object.keys(module.on).forEach((moduleEventName) => {
          instance.on(moduleEventName, module.on[moduleEventName]);
        });
      }

      // Module create callback
      if (module.create) {
        module.create.bind(instance)(moduleParams);
      }
    });
  }

  static set components(components) {
    const Class = this;
    if (!Class.use) return;
    Class.use(components);
  }

  static installModule(module, ...params) {
    const Class = this;
    if (!Class.prototype.modules) Class.prototype.modules = {};
    const name = module.name || (`${Object.keys(Class.prototype.modules).length}_${Utils.now()}`);
    Class.prototype.modules[name] = module;
    // Prototype
    if (module.proto) {
      Object.keys(module.proto).forEach((key) => {
        Class.prototype[key] = module.proto[key];
      });
    }
    // Class
    if (module.static) {
      Object.keys(module.static).forEach((key) => {
        Class[key] = module.static[key];
      });
    }
    // Callback
    if (module.install) {
      module.install.apply(Class, params);
    }
    return Class;
  }

  static use(module, ...params) {
    const Class = this;
    if (Array.isArray(module)) {
      module.forEach(m => Class.installModule(m));
      return Class;
    }
    return Class.installModule(module, ...params);
  }
}

export default SwiperClass;
<commit_msg>Fixed handler unsubscription error on multiple create/destroy events in a row<commit_after>import Utils from './utils';

class SwiperClass {
  constructor(params = {}) {
    const self = this;
    self.params = params;

    // Events
    self.eventsListeners = {};

    if (self.params && self.params.on) {
      Object.keys(self.params.on).forEach((eventName) => {
        self.on(eventName, self.params.on[eventName]);
      });
    }
  }

  on(events, handler, priority) {
    const self = this;
    if (typeof handler !== 'function') return self;
    const method = priority ? 'unshift' : 'push';
    events.split(' ').forEach((event) => {
      if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
      self.eventsListeners[event][method](handler);
    });
    return self;
  }

  once(events, handler, priority) {
    const self = this;
    if (typeof handler !== 'function') return self;
    function onceHandler(...args) {
      handler.apply(self, args);
      self.off(events, onceHandler);
    }
    return self.on(events, onceHandler, priority);
  }

  off(events, handler) {
    const self = this;
    if (!self.eventsListeners) return self;
    events.split(' ').forEach((event) => {
      if (typeof handler === 'undefined') {
        self.eventsListeners[event] = [];
      } else if (self.eventsListeners[event] && self.eventsListeners[event].length) {
        self.eventsListeners[event].forEach((eventHandler, index) => {
          if (eventHandler === handler) {
            self.eventsListeners[event].splice(index, 1);
          }
        });
      }
    });
    return self;
  }

  emit(...args) {
    const self = this;
    if (!self.eventsListeners) return self;
    let events;
    let data;
    let context;
    if (typeof args[0] === 'string' || Array.isArray(args[0])) {
      events = args[0];
      data = args.slice(1, args.length);
      context = self;
    } else {
      events = args[0].events;
      data = args[0].data;
      context = args[0].context || self;
    }
    const eventsArray = Array.isArray(events) ? events : events.split(' ');
    eventsArray.forEach((event) => {
      if (self.eventsListeners && self.eventsListeners[event]) {
        const handlers = [];
        self.eventsListeners[event].forEach((eventHandler) => {
          handlers.push(eventHandler);
        });
        handlers.forEach((eventHandler) => {
          eventHandler.apply(context, data);
        });
      }
    });
    return self;
  }

  useModulesParams(instanceParams) {
    const instance = this;
    if (!instance.modules) return;
    Object.keys(instance.modules).forEach((moduleName) => {
      const module = instance.modules[moduleName];
      // Extend params
      if (module.params) {
        Utils.extend(instanceParams, module.params);
      }
    });
  }

  useModules(modulesParams = {}) {
    const instance = this;
    if (!instance.modules) return;
    Object.keys(instance.modules).forEach((moduleName) => {
      const module = instance.modules[moduleName];
      const moduleParams = modulesParams[moduleName] || {};
      // Extend instance methods and props
      if (module.instance) {
        Object.keys(module.instance).forEach((modulePropName) => {
          const moduleProp = module.instance[modulePropName];
          if (typeof moduleProp === 'function') {
            instance[modulePropName] = moduleProp.bind(instance);
          } else {
            instance[modulePropName] = moduleProp;
          }
        });
      }
      // Add event listeners
      if (module.on && instance.on) {
        Object.keys(module.on).forEach((moduleEventName) => {
          instance.on(moduleEventName, module.on[moduleEventName]);
        });
      }

      // Module create callback
      if (module.create) {
        module.create.bind(instance)(moduleParams);
      }
    });
  }

  static set components(components) {
    const Class = this;
    if (!Class.use) return;
    Class.use(components);
  }

  static installModule(module, ...params) {
    const Class = this;
    if (!Class.prototype.modules) Class.prototype.modules = {};
    const name = module.name || (`${Object.keys(Class.prototype.modules).length}_${Utils.now()}`);
    Class.prototype.modules[name] = module;
    // Prototype
    if (module.proto) {
      Object.keys(module.proto).forEach((key) => {
        Class.prototype[key] = module.proto[key];
      });
    }
    // Class
    if (module.static) {
      Object.keys(module.static).forEach((key) => {
        Class[key] = module.static[key];
      });
    }
    // Callback
    if (module.install) {
      module.install.apply(Class, params);
    }
    return Class;
  }

  static use(module, ...params) {
    const Class = this;
    if (Array.isArray(module)) {
      module.forEach(m => Class.installModule(m));
      return Class;
    }
    return Class.installModule(module, ...params);
  }
}

export default SwiperClass;
<|endoftext|>


<commit_before>'use strict';

describe("networkIndicator", function(){
	var $rootScope, networkIndicator;
	beforeEach(inject(function($injector){
		$rootScope = $injector.get('$rootScope');
		networkIndicator = $injector.get('networkIndicator');
	}));

	it("should start out hidden", function(){
		expect(networkIndicator.isVisible()).toBeFalsy();
	});

	describe("when the route changes", function(){
		beforeEach(function(){
			$rootScope.$broadcast('$routeChangeStart');
		});

		it("should show the indicator (by acquiring)", function(){
			expect(networkIndicator.isVisible()).toBeTruthy();
		});

		describe("when the route change finishes successfully", function(){
			beforeEach(function(){
				$rootScope.$broadcast('$routeChangeSuccess');
			});

			it("should be hidden", function(){
				expect(networkIndicator.isVisible()).toBeFalsy();
			});
		});

		describe("when the route fails to change", function(){
			beforeEach(function(){
				$rootScope.$broadcast('$routeChangeError');
			});

			it("should be hidden", function(){
				expect(networkIndicator.isVisible()).toBeFalsy();
			});
		});
	});

	describe("when acquired", function(){
		beforeEach(function(){
			networkIndicator.acquire();
		});

		it("should be visible", function(){
			expect(networkIndicator.isVisible()).toBeTruthy();
		});

		describe("when released", function(){
			beforeEach(function(){
				networkIndicator.release();
			});

			it("should be hidden", function(){
				expect(networkIndicator.isVisible()).toBeFalsy();
			});
		});
	});

	describe("when anyone still has the networkIndicator acquired", function(){
		beforeEach(function(){
			networkIndicator.acquire();
			networkIndicator.acquire();
			networkIndicator.acquire();
			networkIndicator.release();
			networkIndicator.acquire();
			networkIndicator.release();
			networkIndicator.release();
		});

		it("should still be visible", function(){
			expect(networkIndicator.isVisible()).toBeTruthy();
		});
	});
});

describe("ApiClient", function(){
	var client, $httpBackend, $q, networkIndicator;

	beforeEach(inject(function($injector){
		networkIndicator = $injector.get('networkIndicator');
		$httpBackend = $injector.get('$httpBackend');
		$q = $injector.get('$q');
		client = $injector.get('apiClient');
	}));

	afterEach(function() {
		$httpBackend.verifyNoOutstandingRequest();
	});

	describe("#get", function(){
		describe("when getting a url with params", function(){
			var result;
			beforeEach(function(){
				var response = {success: true, result: [1, 2]};
				$httpBackend.whenPOST('/api/4/', {semester_id: 1}).respond(response);
				client.get('/api/4/', {semester_id: 1}).then(function(theResult){
					result = theResult;
				});
			});

			it("should perform an ajax post request with csrf_token", function(){
				$httpBackend.expectPOST('/api/4/', {semester_id: 1} , {'X-CSRFToken': 'csrf-token'});
			});

			it("should activate the network indicator", function(){
				expect(networkIndicator.isVisible()).toBeTruthy();
			});

			describe("when the request succeeds", function(){
				beforeEach(function(){
					$httpBackend.flush();
				});

				it("should resolve its promise with the result", function(){
					expect(result).toEqual([1, 2]);
				});
			});
		});

		describe("when getting a url successfully", function(){
			var result;
			beforeEach(function(){
				var response = {success: true, result: [1, 2]};
				$httpBackend.whenPOST('/api/4/').respond(response);
				client.get('/api/4/').then(function(theResult){
					result = theResult;
				});
				$httpBackend.flush();
			});

			it("should perform an ajax request", function(){
				$httpBackend.expectPOST('/api/4/');
			});

			it("should resolve its promise with the result", function(){
				expect(result).toEqual([1, 2]);
			});

			it("should release the network indicator", function(){
				expect(networkIndicator.isVisible()).not.toBeTruthy();
			});

			it("should cache the response", function(){
				var newResult;
				client.get('/api/4/').then(function(theResult){
					newResult = theResult;
				});
				$httpBackend.verifyNoOutstandingExpectation();
				expect(result).toEqual(newResult);
			});
		});

		describe("when getting a url with a success: false api response", function(){
			var err;
			beforeEach(function(){
				var response = {success: false};
				$httpBackend.whenPOST('/api/4/').respond(response);
				client.get('/api/4/').then(angular.noop, function(error){
					err = error;
				});
				$httpBackend.flush();
			});

			it("should reject its promise", function(){
				expect(err).toBeTruthy();
			});

			it("should not cache the response", function(){
				client.get('/api/4/');
				$httpBackend.expectPOST('/api/4/');
			});

			it("should release the network indicator", function(){
				expect(networkIndicator.isVisible()).not.toBeTruthy();
			});
		});

		describe("when getting a non-200 http response status code", function(){
			var err;
			beforeEach(function(){
				var response = {success: true, result: 2};
				$httpBackend.whenPOST('/api/4/').respond(500, response);
				client.get('/api/4/').then(angular.noop, function(error){
					err = error;
				});
			});

			it("should reject its promise", function(){
				$httpBackend.flush();
				expect(err).toBeTruthy();
			});

			it("should not cache the response", function(){
				client.get('/api/4/');
				$httpBackend.expectPOST('/api/4/');
			});
		});
	});
});

<commit_msg>fixed broken specs<commit_after>'use strict';

describe("networkIndicator", function(){
	var $rootScope, networkIndicator;
	beforeEach(inject(function($injector){
		$rootScope = $injector.get('$rootScope');
		networkIndicator = $injector.get('networkIndicator');
	}));

	it("should start out hidden", function(){
		expect(networkIndicator.isVisible()).toBeFalsy();
	});

	describe("when the route changes", function(){
		beforeEach(function(){
			$rootScope.$broadcast('$routeChangeStart');
		});

		it("should show the indicator (by acquiring)", function(){
			expect(networkIndicator.isVisible()).toBeTruthy();
		});

		describe("when the route change finishes successfully", function(){
			beforeEach(function(){
				$rootScope.$broadcast('$routeChangeSuccess');
			});

			it("should be hidden", function(){
				expect(networkIndicator.isVisible()).toBeFalsy();
			});
		});

		describe("when the route fails to change", function(){
			beforeEach(function(){
				$rootScope.$broadcast('$routeChangeError');
			});

			it("should be hidden", function(){
				expect(networkIndicator.isVisible()).toBeFalsy();
			});
		});
	});

	describe("when acquired", function(){
		beforeEach(function(){
			networkIndicator.acquire();
		});

		it("should be visible", function(){
			expect(networkIndicator.isVisible()).toBeTruthy();
		});

		describe("when released", function(){
			beforeEach(function(){
				networkIndicator.release();
			});

			it("should be hidden", function(){
				expect(networkIndicator.isVisible()).toBeFalsy();
			});
		});
	});

	describe("when anyone still has the networkIndicator acquired", function(){
		beforeEach(function(){
			networkIndicator.acquire();
			networkIndicator.acquire();
			networkIndicator.acquire();
			networkIndicator.release();
			networkIndicator.acquire();
			networkIndicator.release();
			networkIndicator.release();
		});

		it("should still be visible", function(){
			expect(networkIndicator.isVisible()).toBeTruthy();
		});
	});
});

describe("ApiClient", function(){
	var client, $httpBackend, $q, networkIndicator;

	beforeEach(inject(function($injector){
		networkIndicator = $injector.get('networkIndicator');
		$httpBackend = $injector.get('$httpBackend');
		$q = $injector.get('$q');
		client = $injector.get('apiClient');
	}));

	afterEach(function() {
		$httpBackend.verifyNoOutstandingRequest();
	});

	describe("#get", function(){
		describe("when getting a url with params", function(){
			var result;
			beforeEach(function(){
				var response = {success: true, result: [1, 2]};
				$httpBackend.whenPOST('/api/4/', 'semester_id=1').respond(response);
				client.get('/api/4/', {semester_id: 1}).then(function(theResult){
					result = theResult;
				});
			});

			it("should perform an ajax post request with csrf_token", function(){
				$httpBackend.expectPOST('/api/4/', 'semester_id=1' , {'X-CSRFToken': 'csrf-token'});
			});

			it("should activate the network indicator", function(){
				expect(networkIndicator.isVisible()).toBeTruthy();
			});

			describe("when the request succeeds", function(){
				beforeEach(function(){
					$httpBackend.flush();
				});

				it("should resolve its promise with the result", function(){
					expect(result).toEqual([1, 2]);
				});
			});
		});

		describe("when getting a url successfully", function(){
			var result;
			beforeEach(function(){
				var response = {success: true, result: [1, 2]};
				$httpBackend.whenPOST('/api/4/').respond(response);
				client.get('/api/4/').then(function(theResult){
					result = theResult;
				});
				$httpBackend.flush();
			});

			it("should perform an ajax request", function(){
				$httpBackend.expectPOST('/api/4/');
			});

			it("should resolve its promise with the result", function(){
				expect(result).toEqual([1, 2]);
			});

			it("should release the network indicator", function(){
				expect(networkIndicator.isVisible()).not.toBeTruthy();
			});

			it("should cache the response", function(){
				var newResult;
				client.get('/api/4/').then(function(theResult){
					newResult = theResult;
				});
				$httpBackend.verifyNoOutstandingExpectation();
				expect(result).toEqual(newResult);
			});
		});

		describe("when getting a url with a success: false api response", function(){
			var err;
			beforeEach(function(){
				var response = {success: false};
				$httpBackend.whenPOST('/api/4/').respond(response);
				client.get('/api/4/').then(angular.noop, function(error){
					err = error;
				});
				$httpBackend.flush();
			});

			it("should reject its promise", function(){
				expect(err).toBeTruthy();
			});

			it("should not cache the response", function(){
				client.get('/api/4/');
				$httpBackend.expectPOST('/api/4/');
			});

			it("should release the network indicator", function(){
				expect(networkIndicator.isVisible()).not.toBeTruthy();
			});
		});

		describe("when getting a non-200 http response status code", function(){
			var err;
			beforeEach(function(){
				var response = {success: true, result: 2};
				$httpBackend.whenPOST('/api/4/').respond(500, response);
				client.get('/api/4/').then(angular.noop, function(error){
					err = error;
				});
			});

			it("should reject its promise", function(){
				$httpBackend.flush();
				expect(err).toBeTruthy();
			});

			it("should not cache the response", function(){
				client.get('/api/4/');
				$httpBackend.expectPOST('/api/4/');
			});
		});
	});
});

<|endoftext|>


<commit_before>import {Stream} from 'most'
import MulticastSource from 'most/lib/source/MulticastSource'
import hold from '@most/hold'

import {Subscription} from './subject'

class BehaviorSubscription extends Subscription {
  constructor(intialValue) {
    super()

    this.run = (sink, scheduler) => this._run(sink, scheduler)
    this.add = x => this._add(x)
    this.error = err => this._error(err)
    this.end = x => this._end(x)
    this.value = void 0

    if (typeof initialValue !== 'undefined') {
      this.value = initialValue
      this.add(x)
    }
  }

  _add(x) {
    this.value = x
    super._add(x)
  }
}

function create(initialValue) {
  const sink = new BehaviorSubscription(initialValue)
  const stream = new Stream(new MulticastSource(sink))
  const holdStream = hold(stream)
  holdStream.observe(x => {
    stream.value = x
  })
  return {sink, stream: holdStream}
}

export default create
<commit_msg>replace unneeded .observe() with .drain()<commit_after>import {Stream} from 'most'
import MulticastSource from 'most/lib/source/MulticastSource'
import hold from '@most/hold'

import {Subscription} from './subject'

class BehaviorSubscription extends Subscription {
  constructor(intialValue) {
    super()

    this.run = (sink, scheduler) => this._run(sink, scheduler)
    this.add = x => this._add(x)
    this.error = err => this._error(err)
    this.end = x => this._end(x)
    this.value = void 0

    if (typeof initialValue !== 'undefined') {
      this.value = initialValue
      this.add(x)
    }
  }

  _add(x) {
    this.value = x
    super._add(x)
  }
}

function create(initialValue) {
  const sink = new BehaviorSubscription(initialValue)
  const stream = new Stream(new MulticastSource(sink))
  const holdStream = hold(stream)
  holdStream.drain()
  return {sink, stream: holdStream}
}

export default create
<|endoftext|>


<commit_before>namespace('Sy');

/**
 * Default implementation of the service container interface
 *
 * @package Sy
 * @class
 * @implements {Sy.ServiceContainerInterface}
 *
 * @param {string} name
 */

Sy.ServiceContainer = function (name) {

    this.name = '';
    this.services = {};
    this.creators = {};
    this.parameters = {};

    this.setName(name);

};

Sy.ServiceContainer.prototype = Object.create(Sy.ServiceContainerInterface.prototype, {

    /**
     * @inheritDoc
     */

    setParameters: {
        value: function (params) {
            this.parameters = params;

            return this;
        }
    },

    /**
     * @inheritDoc
     */

    get: {

        value: function (serviceName) {

            if (this.services[serviceName] === undefined && this.creators[serviceName]) {

                var opts = this.creators[serviceName],
                    service;

                if (opts.type === 'creator') {
                    service = this.creators[serviceName].fn.apply(this, this.creators[serviceName].args);
                } else if (opts.type === 'prototype') {
                    if (opts.arguments) {
                        service = new (objectGetter(opts.constructor))(opts.arguments);
                    } else {
                        service = new (objectGetter(opts.constructor))();
                    }

                    if (opts.calls instanceof Array) {
                        for (var i = 0, l = opts.calls.length; i < l; i++) {
                            var args = opts.calls[i][1];

                            for (var a = 0, al = args.length; a < al; a++) {
                                if (typeof args[a] === 'string' && args[a].substring(0, 1) === '@') {
                                    args[a] = this.get(args[a].substr(1));
                                } else if (typeof args[a] === 'string' && new RegExp(/^%.*%$/i).test(args[a])) {
                                    args[a] = objectGetter.call(
                                        this.parameters,
                                        args[a].substring(1, args[a].length - 1)
                                    );
                                }
                            }

                            service[opts.calls[i][0]].apply(service, args);
                        }
                    }
                }

                this.services[serviceName] = service;
                delete this.creators[serviceName];

            } else if (this.services[serviceName] === undefined) {

                throw new ReferenceError('Unknown service');

            }

            return this.services[serviceName];

        }

    },

    /**
     * @inheritDoc
     */

    set: {

        value: function (serviceName, creator, args) {

            var regexp = new RegExp(/^((\w+::)|(\w+))+$/gi);

            if (serviceName instanceof Object) {

                for (var name in serviceName) {
                    if (serviceName.hasOwnProperty(name)) {
                        this.creators[name] = serviceName[name];
                        this.creators[name].type = 'prototype';
                    }
                }

            } else {

                if (!regexp.test(serviceName)) {
                    throw new SyntaxError('Service name "' + serviceName + '" does not follow pattern convention');
                }

                if (typeof creator != 'function'){
                    throw new TypeError('Invalid creator type');
                }

                if (args && !(args instanceof Array)) {
                    throw new TypeError('Invalid args type (must be an array)');
                }

                if (this.creators[serviceName] !== undefined || this.services[serviceName] !== undefined) {
                    throw new TypeError('Service name already used');
                }

                this.creators[serviceName] = {
                    fn: creator,
                    args: args,
                    type: 'creator'
                };

            }

            return this;

        }

    },

    /**
     * @inheritDoc
     */

    has: {
        value: function (name) {

            if (this.services[name] || this.creators[name]) {
                return true;
            }

            return false;

        }
    },

    /**
     * @inheritDoc
     */

    getName: {

        value: function () {

            return this.name;

        }

    },

    /**
     * @inheritDoc
     */

    setName: {
        value: function (name) {

            this.name = name;

            return this;

        }
    }

});<commit_msg>splitted the setting of two types of services into distinct functions<commit_after>namespace('Sy');

/**
 * Default implementation of the service container interface
 *
 * @package Sy
 * @class
 * @implements {Sy.ServiceContainerInterface}
 *
 * @param {string} name
 */

Sy.ServiceContainer = function (name) {

    this.name = '';
    this.services = {};
    this.creators = {};
    this.parameters = {};

    this.setName(name);

};

Sy.ServiceContainer.prototype = Object.create(Sy.ServiceContainerInterface.prototype, {

    /**
     * @inheritDoc
     */

    setParameters: {
        value: function (params) {
            this.parameters = params;

            return this;
        }
    },

    /**
     * @inheritDoc
     */

    get: {

        value: function (serviceName) {

            if (this.services[serviceName] === undefined && this.creators[serviceName]) {

                var opts = this.creators[serviceName],
                    service;

                if (opts.type === 'creator') {
                    service = this.creators[serviceName].fn.apply(this, this.creators[serviceName].args);
                } else if (opts.type === 'prototype') {
                    if (opts.arguments) {
                        service = new (objectGetter(opts.constructor))(opts.arguments);
                    } else {
                        service = new (objectGetter(opts.constructor))();
                    }

                    if (opts.calls instanceof Array) {
                        for (var i = 0, l = opts.calls.length; i < l; i++) {
                            var args = opts.calls[i][1];

                            for (var a = 0, al = args.length; a < al; a++) {
                                if (typeof args[a] === 'string' && args[a].substring(0, 1) === '@') {
                                    args[a] = this.get(args[a].substr(1));
                                } else if (typeof args[a] === 'string' && new RegExp(/^%.*%$/i).test(args[a])) {
                                    args[a] = objectGetter.call(
                                        this.parameters,
                                        args[a].substring(1, args[a].length - 1)
                                    );
                                }
                            }

                            service[opts.calls[i][0]].apply(service, args);
                        }
                    }
                }

                this.services[serviceName] = service;
                delete this.creators[serviceName];

            } else if (this.services[serviceName] === undefined) {

                throw new ReferenceError('Unknown service');

            }

            return this.services[serviceName];

        }

    },

    /**
     * @inheritDoc
     */

    set: {

        value: function (serviceName, creator, args) {

            if (serviceName instanceof Object) {
                this.setPrototypes(serviceName);
            } else {
                this.setCreator(serviceName, creator, args);
            }

            return this;

        }

    },

    /**
     * Register a new service creator definition
     *
     * @private
     * @param {string} serviceName
     * @param {funtcion} creator
     * @param {Array} args
     */

    setCreator: {
        value: function (serviceName, creator, args) {

            if (typeof creator !== 'function'){
                throw new TypeError('Invalid creator type');
            }

            if (args && !(args instanceof Array)) {
                throw new TypeError('Invalid args type (must be an array)');
            }

            if (this.has(serviceName)) {
                throw new TypeError('Service name "' + serviceName + '" already used');
            }

            this.creators[serviceName] = {
                fn: creator,
                args: args,
                type: 'creator'
            };

        }
    },

    /**
     * Register new services prototype definitions
     *
     * @private
     * @param {Object} definitions
     */

    setPrototypes: {
        value: function (definitions) {

            for (var name in definitions) {
                    if (definitions.hasOwnProperty(name)) {

                        if (this.has(name)) {
                            throw new TypeError('Service name "' + name + '" already used');
                        }

                        this.creators[name] = definitions[name];
                        this.creators[name].type = 'prototype';
                    }
                }

        }
    },

    /**
     * @inheritDoc
     */

    has: {
        value: function (name) {

            if (this.services[name] || this.creators[name]) {
                return true;
            }

            return false;

        }
    },

    /**
     * @inheritDoc
     */

    getName: {

        value: function () {

            return this.name;

        }

    },

    /**
     * @inheritDoc
     */

    setName: {
        value: function (name) {

            this.name = name;

            return this;

        }
    }

});<|endoftext|>


<commit_before>import Inferno from 'inferno'

export const generate = (pathname) => {
  switch(true) {
    case pathname == '/':
      return 'Home'
    break

    case pathname.indexOf('components') !== -1:
      return(

          Components
          {pathname.length > 12
            ? ['-',  {pathname.replace('/components/', '')}]
            : null
          }

      )
    break

    default:
      return '404 - Not Found'
    break
  }
}
<commit_msg>:sparkles: Improve title generation(split into links for the future linking)<commit_after>import Inferno from 'inferno'

export const generate = (pathname) => {
  switch(true) {
    case pathname == '/':
      return 'Home'
    break

    case pathname.indexOf('components') !== -1:
      const name = pathname.replace('/components/', '')
      const Name = name.charAt(0).toUpperCase() + name.slice(1)

      return pathname.length > 12
        ? [
          Components, // Links to the components list
          ' - ',             // Separator
          {Name}      // Links to this specific component
        ]
        : 'Components'

    break

    default:
      return '404 - Not Found'
    break
  }
}
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import SearchItem from '../components/SearchItem';
import Title from '../components/Title';
import Loader from '../components/Loader';
import SearchTabs from '../components/SearchTabs';
import Pagination from '../components/Pagination';
import './styles/search.css';

const endpoint = (model, page, filter) => {
    return `http://gamingdb.info/api/${model}?page=${page}&q={"filters":[{"or":${filter}}]}`;
}

const stringFilter = (attr, query) => {
    return {
        "name":attr,
        "op":"ilike",
        "val":"%" + query + "%"
    }
}

const numFilter = (attr, query) => {
    return {
        "name": attr,
        "op":"eq",
        "val": query
    }
}

const genreFilter = (query) => {
    return {
        "name":"genres",
        "op":"any",
        "val":{
            "name":"name",
            "op":"ilike",
            "val":"%" + query + "%"
        }
    }
}

const searchAttrs = {
    "game": {
        "strings": [
            "description",
            "name"
        ],
        "nums": [
            "rating"
        ],
        "genres": [
            "genres"
        ]
    },
    "developer": {
        "strings": [
            "description",
            "name",
            "location",
            "website"
        ],
        "nums": [
            "average_rating"
        ]
    },
    "platform": {
        "strings": [
            "description",
            "name",
            "website"
        ],
        "nums": [
            "average_rating"
        ]
    },
    "character": {
        "strings": [
            "gender",
            "name",
            "description"
        ]
    }
};

const tabIndex = {
    "game": {
        "endpoint": "/games/",
        "id": "game_id"
    },
    "developer": {
        "endpoint": "/developers/",
        "id": "developer_id"
    },
    "platform": {
        "endpoint": "/platforms/",
        "id": "platform_id"
    },
    "character": {
        "endpoint": "/characters/",
        "id": "character_id"
    }
}

const initialState = {
    currentTab: "game",
    game: {
        pageLimit: 0,
        results: [],
        page: 1,
        loading: true,
        filter: []
    },
    developer: {
        pageLimit: 0,
        page: 1,
        results: [],
        loading: true,
        filter: []
    },
    platform: {
        pageLimit: 0,
        page: 1,
        results: [],
        loading: true,
        filter: []
    },
    character: {
        pageLimit: 0,
        page: 1,
        results: [],
        loading: true,
        filter: []
    }
}

class Search extends Component {
    constructor(props) {
        super(props);
        this.state = initialState;
        this.changeTab = (tabName) => {
			return (event) => {
				event.stopPropagation();
				this.setState({
                    currentTab: tabName
                }, () => {
                    console.log(this.state.currentTab);
                });
				return false;
			};
		};
    }

    componentDidMount() {
        this._buildFilters(this.props.match.params.query.split(" "));
    };

    componentWillReceiveProps(nextProps){
		this._buildFilters(nextProps.match.params.query.split(" "));
    };

    componentDidUpdate(prevProps) {
        if (this.props.location !== prevProps.location) {
            this.onRouteChanged();
        }
    }

    onRouteChanged() {
        this.setState(initialState, () => {
            this._buildFilters(this.props.match.params.query.split(" "));
        })
    }

    fetchData(filter, modelType) {
        console.log(endpoint(modelType, this.state[modelType].page, JSON.stringify(filter)));
        fetch(endpoint(modelType, this.state[modelType].page, JSON.stringify(filter)),{
            method: 'GET'
        }).then(response => {
            if(response.ok) {
                return response.json();
            }
            throw new Error('Failed to retrieve response object for game.');
        })
        .then(response => {
            console.log(response);
            let resultObj = {};
            resultObj[modelType] = {
                pageLimit: response.total_pages,
                results: response.objects,
                loading: false,
                page: this.state[modelType].page,
                filter: filter
            };

            this.setState( resultObj, () => {
                console.log(modelType + " " + this.state[modelType].loading);
            } );
        }).catch(error => {
            console.log(error);
        });
    }

    render() {

        return (

Search Query: {this.props.match.params.query}

                    <SearchTabs tabs={["game", "developer", "platform", "character"]} changeTab={this.changeTab}/>
                    { this.visibleTab() }

        );
    }

    visibleTab = () => {
        let stateObj = this.state[this.state.currentTab];
        //console.log(stateObj);
        return (

                {stateObj.loading && <Loader/>}
                {!stateObj.loading &&

                        { stateObj.results.length < 1 ?

No results found

                            : stateObj.results.map( (obj) => {
                            return <SearchItem obj={obj} query={this.props.match.params.query}
                                link={tabIndex[this.state.currentTab].endpoint + obj[tabIndex[this.state.currentTab].id]}/>
                        })}
                        <Pagination page={stateObj.page} pagelimit={stateObj.pageLimit} decPage={this.decPage} incPage={this.incPage}/>

                }

        )
    }

    decPage = () => {
        let obj = Object.assign(this.state);
        obj[this.state.currentTab].page = parseInt(obj[this.state.currentTab].page, 10) - 1;
        obj[this.state.currentTab].results = [];
        obj[this.state.currentTab].loading = true;
        this.setState(obj,
        () => this.fetchData(this.state[this.state.currentTab].filter, this.state.currentTab));
    }

    incPage = () => {
        let obj = Object.assign(this.state);
        obj[this.state.currentTab].page = parseInt(obj[this.state.currentTab].page, 10) + 1;
        obj[this.state.currentTab].results = [];
        obj[this.state.currentTab].loading = true;
        console.log(obj);
        this.setState(obj,
        () => this.fetchData(this.state[this.state.currentTab].filter, this.state.currentTab));
    }

    _buildFilters(query) {
        let filters = {
            "game": [],
            "developer": [],
            "platform": [],
            "character": []
        };
        for (var i = 0; i < query.length; i++) {
            let currString = query[i];
            Object.keys(searchAttrs).forEach(function(model) {
                Object.keys(searchAttrs[model]).forEach(function(type) {
                    let currFilterArray = filters[model];
                    let attrArray = searchAttrs[model][type];
                    for (var j = 0; j < attrArray.length; j++) {
                        if (type == "strings" && isNaN(currString)) {
                            currFilterArray.push(stringFilter(attrArray[j], currString));
                        } else if (type == "nums" && !isNaN(currString)) {
                            currFilterArray.push(numFilter(attrArray[j], currString));
                        } else if (type == "genres" && isNaN(currString)) {
                            currFilterArray.push(genreFilter(currString));
                        }
                    }
                })
            });
        }
        let models = Object.keys(filters);
        for (var i = 0; i < models.length; i++) {
            let obj = Object.assign(this.state);
            obj[models[i]].filter = filters[models[i]];
            this.setState(obj);
            this.fetchData(filters[models[i]], models[i]);
        };
    }

}

export default Search;<commit_msg>removing pagination if there are no results<commit_after>import React, {Component} from 'react';
import SearchItem from '../components/SearchItem';
import Title from '../components/Title';
import Loader from '../components/Loader';
import SearchTabs from '../components/SearchTabs';
import Pagination from '../components/Pagination';
import './styles/search.css';

const endpoint = (model, page, filter) => {
    return `http://gamingdb.info/api/${model}?page=${page}&q={"filters":[{"or":${filter}}]}`;
}

const stringFilter = (attr, query) => {
    return {
        "name":attr,
        "op":"ilike",
        "val":"%" + query + "%"
    }
}

const numFilter = (attr, query) => {
    return {
        "name": attr,
        "op":"eq",
        "val": query
    }
}

const genreFilter = (query) => {
    return {
        "name":"genres",
        "op":"any",
        "val":{
            "name":"name",
            "op":"ilike",
            "val":"%" + query + "%"
        }
    }
}

const searchAttrs = {
    "game": {
        "strings": [
            "description",
            "name"
        ],
        "nums": [
            "rating"
        ],
        "genres": [
            "genres"
        ]
    },
    "developer": {
        "strings": [
            "description",
            "name",
            "location",
            "website"
        ],
        "nums": [
            "average_rating"
        ]
    },
    "platform": {
        "strings": [
            "description",
            "name",
            "website"
        ],
        "nums": [
            "average_rating"
        ]
    },
    "character": {
        "strings": [
            "gender",
            "name",
            "description"
        ]
    }
};

const tabIndex = {
    "game": {
        "endpoint": "/games/",
        "id": "game_id"
    },
    "developer": {
        "endpoint": "/developers/",
        "id": "developer_id"
    },
    "platform": {
        "endpoint": "/platforms/",
        "id": "platform_id"
    },
    "character": {
        "endpoint": "/characters/",
        "id": "character_id"
    }
}

const initialState = {
    currentTab: "game",
    game: {
        pageLimit: 0,
        results: [],
        page: 1,
        loading: true,
        filter: []
    },
    developer: {
        pageLimit: 0,
        page: 1,
        results: [],
        loading: true,
        filter: []
    },
    platform: {
        pageLimit: 0,
        page: 1,
        results: [],
        loading: true,
        filter: []
    },
    character: {
        pageLimit: 0,
        page: 1,
        results: [],
        loading: true,
        filter: []
    }
}

class Search extends Component {
    constructor(props) {
        super(props);
        this.state = initialState;
        this.changeTab = (tabName) => {
			return (event) => {
				event.stopPropagation();
				this.setState({
                    currentTab: tabName
                }, () => {
                    console.log(this.state.currentTab);
                });
				return false;
			};
		};
    }

    componentDidMount() {
        this._buildFilters(this.props.match.params.query.split(" "));
    };

    componentWillReceiveProps(nextProps){
		this._buildFilters(nextProps.match.params.query.split(" "));
    };

    componentDidUpdate(prevProps) {
        if (this.props.location !== prevProps.location) {
            this.onRouteChanged();
        }
    }

    onRouteChanged() {
        this.setState(initialState, () => {
            this._buildFilters(this.props.match.params.query.split(" "));
        })
    }

    fetchData(filter, modelType) {
        console.log(endpoint(modelType, this.state[modelType].page, JSON.stringify(filter)));
        fetch(endpoint(modelType, this.state[modelType].page, JSON.stringify(filter)),{
            method: 'GET'
        }).then(response => {
            if(response.ok) {
                return response.json();
            }
            throw new Error('Failed to retrieve response object for game.');
        })
        .then(response => {
            console.log(response);
            let resultObj = {};
            resultObj[modelType] = {
                pageLimit: response.total_pages,
                results: response.objects,
                loading: false,
                page: this.state[modelType].page,
                filter: filter
            };

            this.setState( resultObj, () => {
                console.log(modelType + " " + this.state[modelType].loading);
            } );
        }).catch(error => {
            console.log(error);
        });
    }

    render() {

        return (

Search Query: {this.props.match.params.query}

                    <SearchTabs tabs={["game", "developer", "platform", "character"]} changeTab={this.changeTab}/>
                    { this.visibleTab() }

        );
    }

    visibleTab = () => {
        let stateObj = this.state[this.state.currentTab];
        //console.log(stateObj);
        return (

                {stateObj.loading && <Loader/>}
                {!stateObj.loading &&

                        { stateObj.results.length < 1 ?

No results found

                            : stateObj.results.map( (obj) => {
                            return <SearchItem obj={obj} query={this.props.match.params.query}
                                link={tabIndex[this.state.currentTab].endpoint + obj[tabIndex[this.state.currentTab].id]}/>
                        })}
                        { stateObj.results.length < 1 ? ""
                            : <Pagination page={stateObj.page} pagelimit={stateObj.pageLimit} decPage={this.decPage} incPage={this.incPage}/>
                        }

                }

        )
    }

    decPage = () => {
        let obj = Object.assign(this.state);
        obj[this.state.currentTab].page = parseInt(obj[this.state.currentTab].page, 10) - 1;
        obj[this.state.currentTab].results = [];
        obj[this.state.currentTab].loading = true;
        this.setState(obj,
        () => this.fetchData(this.state[this.state.currentTab].filter, this.state.currentTab));
    }

    incPage = () => {
        let obj = Object.assign(this.state);
        obj[this.state.currentTab].page = parseInt(obj[this.state.currentTab].page, 10) + 1;
        obj[this.state.currentTab].results = [];
        obj[this.state.currentTab].loading = true;
        console.log(obj);
        this.setState(obj,
        () => this.fetchData(this.state[this.state.currentTab].filter, this.state.currentTab));
    }

    _buildFilters(query) {
        let filters = {
            "game": [],
            "developer": [],
            "platform": [],
            "character": []
        };
        for (var i = 0; i < query.length; i++) {
            let currString = query[i];
            Object.keys(searchAttrs).forEach(function(model) {
                Object.keys(searchAttrs[model]).forEach(function(type) {
                    let currFilterArray = filters[model];
                    let attrArray = searchAttrs[model][type];
                    for (var j = 0; j < attrArray.length; j++) {
                        if (type == "strings" && isNaN(currString)) {
                            currFilterArray.push(stringFilter(attrArray[j], currString));
                        } else if (type == "nums" && !isNaN(currString)) {
                            currFilterArray.push(numFilter(attrArray[j], currString));
                        } else if (type == "genres" && isNaN(currString)) {
                            currFilterArray.push(genreFilter(currString));
                        }
                    }
                })
            });
        }
        let models = Object.keys(filters);
        for (var i = 0; i < models.length; i++) {
            let obj = Object.assign(this.state);
            obj[models[i]].filter = filters[models[i]];
            this.setState(obj);
            this.fetchData(filters[models[i]], models[i]);
        };
    }

}

export default Search;<|endoftext|>