<commit_before>(function ($) {
    // extend jQuery --------------------------------------------------------------------
    $.fn.butterCombobox = function () {
        return this.each(function () {
            new FilterableCombobox(this);
        });
    };

    // define objects --------------------------------------------------------------------

    /**
     * @class
     */
    var FilterableComboboxMouseEventListener = Class.extend({
        /**
         * Is called when a mouse down event is triggered on a result list option. Intended to be overridden.
         * @param {String} value the value of the result list option
         */
        onResultItemMouseDown: function (value) {
        },

        /**
         * Is called when a mouse enter event is triggered on a result list option. Intended to be overridden.
         * @param {String} value the value of the result list option
         */
        onResultItemMouseEnter: function (value) {
        }
    });

    /**
     * @class
     */
    var FilterableComboboxOption = Class.extend({
        /**
         * @constructs
         * @param {HTMLElement} optionElement
         * @param {FilterableComboboxMouseEventListener} mouseEventListener
         * @param {jQuery} $template
         */
        init: function (optionElement, mouseEventListener, $template) {
            this._$optionElement = $(optionElement);
            this._mouseEventListener = mouseEventListener;
            this._$resultElement;

            this._$noResultOption = $("<li>")
                .text("Keine Einträge vorhanden!")
                .addClass("butter-dropdownlist-container-noResultItems");

            this._initResultItem($template);
        },

        _initResultItem: function ($template) {
            var self = this;
            var resultItemHtml = self._$optionElement.text();
            if ($template !== undefined) {
                var dataFields = self._$optionElement.data();
                resultItemHtml = $template;
                $template.replace(/\{\{(.*?)\}\}/g, function (group0, group1) {
                    resultItemHtml = resultItemHtml.replace("{{" + group1 + "}}", dataFields[group1.toLowerCase()])
                    return;
                })
            }

            this._$resultElement = $("<li>")
                .html(resultItemHtml)
                .addClass("butter-dropdownlist-resultItem")
                .on("mousedown", function () {
                    self._mouseEventListener.onResultItemMouseDown(self.getValue());
                })
                .on("mouseenter", function () {
                    self._mouseEventListener.onResultItemMouseEnter(self.getValue());
                });
        },

        /**
         * @returns {String} the option's value
         */
        getValue: function () {
            return this._$optionElement.val();
        },

        /**
         * @returns {jQuery} a jQuery extended HTML element
         */
        getResultElement: function () {
            return this._$resultElement;
        }
    });

    /**
     * @class
     */
    var FilterableComboboxOptionList = Class.extend({
        /**
         * @constructs
         */
        init: function () {
            this._options = {};
        },

        /**
         * @param {FilterableComboboxOption} resultOption
         */
        add: function (resultOption) {
            this._options[resultOption.getValue()] = resultOption;
        },

        /**
         *
         * @param filter {String} the filter text
         * @returns {Array} the array with the filtered option elements
         */
        getFilteredResultElements: function (filter) {
            var filteredElements = [];
            for (var key in this._options) {
                var $resultElement = this._options[key];
                $resultElement.getResultElement().highlight(filter);
                if (filter === undefined || filter === "") {
                    filteredElements.push($resultElement.getResultElement());
                } else if ($resultElement.getResultElement().find(".search-highlighted").length > 0) {
                    filteredElements.push($resultElement.getResultElement());
                }
            }
            return filteredElements;
        },

        /**
         *
         * @param {String} value the value of the options that should be selected
         */
        select: function (value) {
            this.unselect();
            // TODO implementieren
        },

        selectPrevious: function (value) {
            // TODO implementieren
        },

        selectNext: function (value) {
            // TODO implementieren
        },

        /**
         * Unselect possible selected option
         */
        unselect: function () {
            // TODO implementieren
        },

        /**
         * * @returns {FilterableComboboxOption} the option that is selected
         */
        getSelected: function () {
            // TODO implementieren
            return;
        }
    });

    /**
     * @class
     */
    var FilterableCombobox = FilterableComboboxMouseEventListener.extend({
        /**
         * @constructs
         * @param {HTMLElement} rootElement
         */
        init: function (rootElement) {
            this.$select = $(rootElement).find("select");
            this.$template = this.$select.parent().siblings(".butter-component-combobox-resultListItemTemplate").html();
            this.$ghostInput = null;
            this.$resultContainer = null;
            this.$resultListContainer = null;
            this._optionList;
            this._hasFocus = false;
            this._disabled = this.$select.is('[disabled=disabled]');
            this.isMouseClickBlocked = false;

            this._keyCodes = {
                //backspace: 8,
                tab: 9,
                enter: 13,
                shift: 16,
                ctrl: 17,
                alt: 18,
                pause: 19,
                caps_lock: 20,
                escape: 27,
                page_up: 33,
                page_down: 34,
                end: 35,
                home: 36,
                arrow_left: 37,
                arrow_up: 38,
                arrow_right: 39,
                arrow_down: 40,
                insert: 45,
                // 'delete' is a reserved key word
                delete_key: 46,
                left_window_key: 91,
                right_window_key: 92,
                select_key: 93,
                num_lock: 144,
                scroll_lock: 145
            };

            this._initializeGhostElement();
            this._initializeDropDownButton();
            this._initializeOptionList();
        },

        _initializeGhostElement: function () {
            var self = this;
            self.$ghostInput = self.$select.parent().find(".butter-component-combobox-ghost")
                //.addClass($select.attr("class"))
                .val(self.$select.find("option:selected").text())
                .on("focus", function () {
                    self._hasFocus = true;
                    // automatically select whole text on focus
                    self._selectCompleteTextInGhostInput();
                })
                .on("mouseup", function (event) {
                    // in safari the mouseup event unselects the text, so we have to prevent this
                    self._stopEvent(event);
                })
                .on("blur", function () {
                    self._hasFocus = false;
                    // block next mouse click only if the result list is opened
                    self.isMouseClickBlocked = self.$resultContainer !== null;

                    window.setTimeout(function () {
                        self.isMouseClickBlocked = false;
                        if (!self._hasFocus) {
                            self._hideOptionResultList();
                            self._resetDisplayValue();
                        }
                    }, 200);
                })
                .on("keydown", function (event) {
                    if (event.which === self._keyCodes.enter) {
                        self._handleEnterKeyDown(event);
                    } else if (event.which === self._keyCodes.arrow_up || event.which === self._keyCodes.arrow_down) {
                        self._handleArrowUpAndDownKeyDown(event);
                    } else if (event.which === self._keyCodes.escape) {
                        self._handleEscapeKeyDown(event);
                    }
                })
                .on("keyup", function (event) {
                    // don't handle other keys than character keys
                    for (keyName in self._keyCodes) {
                        if (self._keyCodes[keyName] === event.which) {
                            self._stopEvent(event);
                            return;
                        }
                    }

                    var searchText = $(this).val();
                    self._showOptionResultList(searchText);
                });

            if (self._disabled) {
                self.$ghostInput.attr('disabled', 'disabled');
            }
        },

        _initializeOptionList: function () {
            var self = this;
            self._optionList = new FilterableComboboxOptionList();
            self.$select.find("option").each(function (index, element) {
                self._optionList.add(new FilterableComboboxOption(element, self, self.$template));
            });
        },

        _handleEnterKeyDown: function (event) {
            if (this.$selectedOption !== null) {
                this._stopEvent(event);
                this._setSelectedValue();
                this._selectCompleteTextInGhostInput();
            } else if (this.$selectedOption === null && this.$resultContainer !== null) {
                // deactivate enter key if result list is opened but nothing is selected
                this._stopEvent(event);
            } else {
                this._resetDisplayValue();
            }
        },

        _handleArrowUpAndDownKeyDown: function (event) {
            this._stopEvent(event);
            // TODO
            /* if (this.optionResultList.length === 0) {
             this._createOptionResultList();
             }
             if (this.$resultContainer === null) {
             this._showOptionResultList();
             }*/

            // don't select the no result items message
            if (this.$resultListContainer.find(".butter-dropdownlist-container-noResultItems").length === 0) {
                if (this.$selectedOption === null) {
                    this._selectResultOptionElement(this.$resultListContainer.children()[0]);
                } else {
                    this._moveResultOptionElementSelectionCursor(event.which === this._keyCodes.arrow_up ? -1 : 1);
                }
            }
        },

        _handleEscapeKeyDown: function (event) {
            if (this.$resultContainer !== null) {
                this._hideOptionResultList();
                this._resetDisplayValue();
                this._selectCompleteTextInGhostInput();
            } else {
                this.$ghostInput.blur();
            }
        },

        _initializeDropDownButton: function () {
            var self = this;
            if (!self._disabled) {
                self.$ghostInput.next()
                    .on("click", function (event) {
                        self._stopEvent(event);

                        if (self.isMouseClickBlocked) {
                            return;
                        }

                        self._showOptionResultList();
                        self.$ghostInput.focus();
                    });
            } else {
                self.$ghostInput.next().addClass('disabled');
            }
        },

        _showOptionResultList: function (searchText) {
            var self = this;

            // create container elements if necessary
            if (self.$resultContainer === null) {
                var $inputGroup = self.$ghostInput.parent();
                var inputGroupOffset = $inputGroup.offset();
                self.$resultContainer = $("<div>")
                    .addClass("butter-dropdownlist-container")
                    .addClass("butter-component-combobox-dropdownlist-container")
                    .css({
                        position: "absolute",
                        left: inputGroupOffset.left,
                        top: inputGroupOffset.top + $inputGroup.outerHeight(),
                        width: $inputGroup.innerWidth()
                    });

                self.$resultListContainer = $("<ul>")
                    .addClass("butter-dropdownlist-resultList")
                    .on("mouseleave", function () {
                        self._clearResultOptionSelection();
                    })
                    .appendTo(self.$resultContainer);
                $("body").append(self.$resultContainer);
            }

            self.$resultListContainer.empty();
            self.$selectedOption = null;

            $.each(self._optionList.getFilteredResultElements(searchText), function (index, element) {
                self.$resultListContainer.append(element);
            });
        },

        _hideOptionResultList: function () {
            var self = this;
            if (self.$resultContainer !== null) {
                self.$resultContainer.remove();
                self.$resultContainer = null;
                self.$resultListContainer = null;
                this.$selectedOption = null;
            }
        },

        _selectResultOptionElement: function (optionElement) {
            this._clearResultOptionSelection();
            var $selectedOptionElement = $(optionElement);
            $selectedOptionElement.addClass("butter-dropdownlist-resultItem-selected");
            this.$selectedOption = $selectedOptionElement;
        },

        _clearResultOptionSelection: function () {
            this.$selectedOption = null;
            this.$resultListContainer
                .find(".butter-dropdownlist-resultItem-selected")
                .removeClass("butter-dropdownlist-resultItem-selected");
        },

        /**
         * @inheritdoc
         */
        onResultItemMouseDown: function (value) {
            console.log("onResultItemMouseDown: %s", value);
        },

        /**
         * @inheritdoc
         */
        onResultItemMouseEnter: function (value) {
            console.log("onResultItemMouseEnter: %s", value);
        },

        _moveResultOptionElementSelectionCursor: function (direction) {
            if (direction > 0) {
                this._optionList.selectNext();
            } else {
                this._optionList.selectPrevious();
            }
        },

        _setSelectedValue: function () {
            var $selectedOption = this.$selectedOption;
            if ($selectedOption !== null) {
                var valueData = $selectedOption.attr("data-select-value");
                if (valueData !== undefined) {
                    this.$select
                        .val(valueData)
                        .change();
                    this.$ghostInput.val($selectedOption.attr("data-select-label"));
                    this._hideOptionResultList();
                }
            }
        },

        _resetDisplayValue: function () {
            // set old value
            this.$ghostInput.val(this.$select.find("option:selected").text());
        },

        _stopEvent: function (event) {
            event.stopPropagation();
            event.preventDefault();
        },

        _selectCompleteTextInGhostInput: function () {
            this.$ghostInput[0].setSelectionRange(0, this.$ghostInput.val().length);
        }
    });
}(jQuery));<commit_msg>BUT-341 appending and detaching result list elements<commit_after>(function ($) {
    // extend jQuery --------------------------------------------------------------------
    $.fn.butterCombobox = function () {
        return this.each(function () {
            new FilterableCombobox(this);
        });
    };

    // define objects --------------------------------------------------------------------

    /**
     * @class
     */
    var FilterableComboboxMouseEventListener = Class.extend({
        /**
         * Is called when a mouse down event is triggered on a result list option. Intended to be overridden.
         * @param {String} value the value of the result list option
         */
        onResultItemMouseDown: function (value) {
        },

        /**
         * Is called when a mouse enter event is triggered on a result list option. Intended to be overridden.
         * @param {String} value the value of the result list option
         */
        onResultItemMouseEnter: function (value) {
        }
    });

    /**
     * @class
     */
    var FilterableComboboxOption = Class.extend({
        /**
         * @constructs
         * @param {HTMLElement} optionElement
         * @param {FilterableComboboxMouseEventListener} mouseEventListener
         * @param {jQuery} $template
         */
        init: function (optionElement, mouseEventListener, $template) {
            this._$optionElement = $(optionElement);
            this._mouseEventListener = mouseEventListener;
            this._$resultElement;

            this._$noResultOption = $("<li>")
                .text("Keine Einträge vorhanden!")
                .addClass("butter-dropdownlist-container-noResultItems");

            this._initResultItem($template);
        },

        _initResultItem: function ($template) {
            var self = this;
            var resultItemHtml = self._$optionElement.text();
            if ($template !== undefined) {
                var dataFields = self._$optionElement.data();
                resultItemHtml = $template;
                $template.replace(/\{\{(.*?)\}\}/g, function (group0, group1) {
                    resultItemHtml = resultItemHtml.replace("{{" + group1 + "}}", dataFields[group1.toLowerCase()])
                    return;
                })
            }

            this._$resultElement = $("<li>")
                .html(resultItemHtml)
                .addClass("butter-dropdownlist-resultItem")
                .on("mousedown", function () {
                    self._mouseEventListener.onResultItemMouseDown(self.getValue());
                })
                .on("mouseenter", function () {
                    self._mouseEventListener.onResultItemMouseEnter(self.getValue());
                });
        },

        /**
         * @returns {String} the option's value
         */
        getValue: function () {
            return this._$optionElement.val();
        },

        /**
         * @returns {jQuery} a jQuery extended HTML element
         */
        getResultElement: function () {
            return this._$resultElement;
        }
    });

    /**
     * @class
     */
    var FilterableComboboxOptionList = Class.extend({
        /**
         * @constructs
         */
        init: function () {
            this._options = {};
        },

        /**
         * @param {FilterableComboboxOption} resultOption
         */
        add: function (resultOption) {
            this._options[resultOption.getValue()] = resultOption;
        },

        /**
         *
         * @param filter {String} the filter text
         * @returns {Array} the array with the filtered option elements
         */
        getFilteredResultElements: function (filter) {
            var filteredElements = [];
            for (var key in this._options) {
                var $resultElement = this._options[key];
                $resultElement.getResultElement().highlight(filter);
                if (filter === undefined || filter === "") {
                    filteredElements.push($resultElement.getResultElement());
                } else if ($resultElement.getResultElement().find(".search-highlighted").length > 0) {
                    filteredElements.push($resultElement.getResultElement());
                }
            }
            return filteredElements;
        },

        /**
         *
         * @param {String} value the value of the options that should be selected
         */
        select: function (value) {
            this.unselect();
            // TODO implementieren
        },

        selectPrevious: function (value) {
            // TODO implementieren
        },

        selectNext: function (value) {
            // TODO implementieren
        },

        /**
         * Unselect possible selected option
         */
        unselect: function () {
            // TODO implementieren
        },

        /**
         * * @returns {FilterableComboboxOption} the option that is selected
         */
        getSelected: function () {
            // TODO implementieren
            return;
        }
    });

    /**
     * @class
     */
    var FilterableCombobox = FilterableComboboxMouseEventListener.extend({
        /**
         * @constructs
         * @param {HTMLElement} rootElement
         */
        init: function (rootElement) {
            this.$select = $(rootElement).find("select");
            this.$template = this.$select.parent().siblings(".butter-component-combobox-resultListItemTemplate").html();
            this.$ghostInput = null;
            this.$resultContainer = null;
            this.$resultListContainer = null;
            this._optionList;
            this._hasFocus = false;
            this._disabled = this.$select.is('[disabled=disabled]');
            this.isMouseClickBlocked = false;

            this._keyCodes = {
                //backspace: 8,
                tab: 9,
                enter: 13,
                shift: 16,
                ctrl: 17,
                alt: 18,
                pause: 19,
                caps_lock: 20,
                escape: 27,
                page_up: 33,
                page_down: 34,
                end: 35,
                home: 36,
                arrow_left: 37,
                arrow_up: 38,
                arrow_right: 39,
                arrow_down: 40,
                insert: 45,
                // 'delete' is a reserved key word
                delete_key: 46,
                left_window_key: 91,
                right_window_key: 92,
                select_key: 93,
                num_lock: 144,
                scroll_lock: 145
            };

            this._initializeGhostElement();
            this._initializeDropDownButton();
            this._initializeOptionList();
        },

        _initializeGhostElement: function () {
            var self = this;
            self.$ghostInput = self.$select.parent().find(".butter-component-combobox-ghost")
                //.addClass($select.attr("class"))
                .val(self.$select.find("option:selected").text())
                .on("focus", function () {
                    self._hasFocus = true;
                    // automatically select whole text on focus
                    self._selectCompleteTextInGhostInput();
                })
                .on("mouseup", function (event) {
                    // in safari the mouseup event unselects the text, so we have to prevent this
                    self._stopEvent(event);
                })
                .on("blur", function () {
                    self._hasFocus = false;
                    // block next mouse click only if the result list is opened
                    self.isMouseClickBlocked = self.$resultContainer !== null;

                    window.setTimeout(function () {
                        self.isMouseClickBlocked = false;
                        if (!self._hasFocus) {
                            self._hideOptionResultList();
                            self._resetDisplayValue();
                        }
                    }, 200);
                })
                .on("keydown", function (event) {
                    if (event.which === self._keyCodes.enter) {
                        self._handleEnterKeyDown(event);
                    } else if (event.which === self._keyCodes.arrow_up || event.which === self._keyCodes.arrow_down) {
                        self._handleArrowUpAndDownKeyDown(event);
                    } else if (event.which === self._keyCodes.escape) {
                        self._handleEscapeKeyDown(event);
                    }
                })
                .on("keyup", function (event) {
                    // don't handle other keys than character keys
                    for (keyName in self._keyCodes) {
                        if (self._keyCodes[keyName] === event.which) {
                            self._stopEvent(event);
                            return;
                        }
                    }

                    var searchText = $(this).val();
                    self._showOptionResultList(searchText);
                });

            if (self._disabled) {
                self.$ghostInput.attr('disabled', 'disabled');
            }
        },

        _initializeOptionList: function () {
            var self = this;
            self._optionList = new FilterableComboboxOptionList();
            self.$select.find("option").each(function (index, element) {
                self._optionList.add(new FilterableComboboxOption(element, self, self.$template));
            });
        },

        _handleEnterKeyDown: function (event) {
            if (this.$selectedOption !== null) {
                this._stopEvent(event);
                this._setSelectedValue();
                this._selectCompleteTextInGhostInput();
            } else if (this.$selectedOption === null && this.$resultContainer !== null) {
                // deactivate enter key if result list is opened but nothing is selected
                this._stopEvent(event);
            } else {
                this._resetDisplayValue();
            }
        },

        _handleArrowUpAndDownKeyDown: function (event) {
            this._stopEvent(event);
            // TODO
            /* if (this.optionResultList.length === 0) {
             this._createOptionResultList();
             }
             if (this.$resultContainer === null) {
             this._showOptionResultList();
             }*/

            // don't select the no result items message
            if (this.$resultListContainer.find(".butter-dropdownlist-container-noResultItems").length === 0) {
                if (this.$selectedOption === null) {
                    this._selectResultOptionElement(this.$resultListContainer.children()[0]);
                } else {
                    this._moveResultOptionElementSelectionCursor(event.which === this._keyCodes.arrow_up ? -1 : 1);
                }
            }
        },

        _handleEscapeKeyDown: function (event) {
            if (this.$resultContainer !== null) {
                this._hideOptionResultList();
                this._resetDisplayValue();
                this._selectCompleteTextInGhostInput();
            } else {
                this.$ghostInput.blur();
            }
        },

        _initializeDropDownButton: function () {
            var self = this;
            if (!self._disabled) {
                self.$ghostInput.next()
                    .on("click", function (event) {
                        self._stopEvent(event);

                        if (self.isMouseClickBlocked) {
                            return;
                        }

                        self._showOptionResultList();
                        self.$ghostInput.focus();
                    });
            } else {
                self.$ghostInput.next().addClass('disabled');
            }
        },

        _showOptionResultList: function (searchText) {
            var self = this;

            // create container elements if necessary
            if (self.$resultContainer === null) {
                var $inputGroup = self.$ghostInput.parent();
                var inputGroupOffset = $inputGroup.offset();
                self.$resultContainer = $("<div>")
                    .addClass("butter-dropdownlist-container")
                    .addClass("butter-component-combobox-dropdownlist-container")
                    .css({
                        position: "absolute",
                        left: inputGroupOffset.left,
                        top: inputGroupOffset.top + $inputGroup.outerHeight(),
                        width: $inputGroup.innerWidth()
                    });

                self.$resultListContainer = $("<ul>")
                    .addClass("butter-dropdownlist-resultList")
                    .on("mouseleave", function () {
                        self._clearResultOptionSelection();
                    })
                    .appendTo(self.$resultContainer);
                $("body").append(self.$resultContainer);
            }

            self._detachResultListElements();
            self.$selectedOption = null;

            $.each(self._optionList.getFilteredResultElements(searchText), function (index, element) {
                self.$resultListContainer.append(element);
            });
        },

        _hideOptionResultList: function () {
            var self = this;
            if (self.$resultContainer !== null) {
                self._detachResultListElements();
                self.$resultContainer.remove();
                self.$resultContainer = null;
                self.$resultListContainer = null;
                this.$selectedOption = null;
            }
        },

        _selectResultOptionElement: function (optionElement) {
            this._clearResultOptionSelection();
            var $selectedOptionElement = $(optionElement);
            $selectedOptionElement.addClass("butter-dropdownlist-resultItem-selected");
            this.$selectedOption = $selectedOptionElement;
        },

        _clearResultOptionSelection: function () {
            this.$selectedOption = null;
            this.$resultListContainer
                .find(".butter-dropdownlist-resultItem-selected")
                .removeClass("butter-dropdownlist-resultItem-selected");
        },

        _detachResultListElements: function () {
            this.$resultListContainer.children().detach();
        },

        /**
         * @inheritdoc
         */
        onResultItemMouseDown: function (value) {
            console.log("FilterableCombobox.onResultItemMouseDown: %s", value);
        },

        /**
         * @inheritdoc
         */
        onResultItemMouseEnter: function (value) {
            console.log("FilterableCombobox.onResultItemMouseEnter: %s", value);
        },

        _moveResultOptionElementSelectionCursor: function (direction) {
            if (direction > 0) {
                this._optionList.selectNext();
            } else {
                this._optionList.selectPrevious();
            }
        },

        _setSelectedValue: function () {
            var $selectedOption = this.$selectedOption;
            if ($selectedOption !== null) {
                var valueData = $selectedOption.attr("data-select-value");
                if (valueData !== undefined) {
                    this.$select
                        .val(valueData)
                        .change();
                    this.$ghostInput.val($selectedOption.attr("data-select-label"));
                    this._hideOptionResultList();
                }
            }
        },

        _resetDisplayValue: function () {
            // set old value
            this.$ghostInput.val(this.$select.find("option:selected").text());
        },

        _stopEvent: function (event) {
            event.stopPropagation();
            event.preventDefault();
        },

        _selectCompleteTextInGhostInput: function () {
            this.$ghostInput[0].setSelectionRange(0, this.$ghostInput.val().length);
        }
    });
}(jQuery));<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var path = require('path'),
    fs = require('fs'),
    mongoose = require('mongoose'),
    Saving = mongoose.model('Saving'),
    User = mongoose.model('User'),
    errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')),
    _ = require('lodash');

/**
 * Create a saving
 */
exports.create = function (req, res) {
    var saving = new Saving(req.body);
    saving.user = req.user;

    saving.save(function (err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(saving);
        }
    });
};

/**
 * Show the current saving
 */
exports.read = function (req, res) {
    res.json(req.saving);
};

/**
 * Update a saving
 */
exports.update = function (req, res) {

    var saving = req.saving;

    //saving.title  = req.body.title;
    //saving.retailer  = req.body.retailer;
    //saving.price  = req.body.price;
    //saving.image  = req.body.image;
    //saving.votes = req.body.votes;
    //saving.votesreal = req.body.votesreal;
    //saving.urlimage  = req.body.urlimage;
    //saving.tags  = req.body.tags;
    //saving.upVoters  = req.body.upVoters;
    //saving.downVoters  = req.body.downVoters;
    //saving.link  = req.body.link;
    //saving.details  = req.body.details;
    //saving.currency  = req.body.currency;

    saving = _.extend(saving, req.body);

    saving.save(function (err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(saving);
        }
    });
};

/**
 * Delete an saving
 */
exports.delete = function (req, res) {
    var saving = req.saving;

    saving.remove(function (err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(saving);
        }
    });
};

/**
 * List of Savings
 */
exports.list = function (req, res) {
    Saving.find().sort('-created').populate('user').exec(function (err, savings) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(savings);
        }
    });
};

/**
 * Saving middleware
 */
exports.savingByID = function (req, res, next, id) {

    if (!mongoose.Types.ObjectId.isValid(id)) {
        return res.status(400).send({
            message: 'Saving is invalid'
        });
    }

    Saving.findById(id).populate('user').exec(function (err, saving) {
        if (err) {
            return next(err);
        } else if (!saving) {
            return res.status(404).send({
                message: 'No saving with that identifier has been found'
            });
        }
        req.saving = saving;
        next();
    });
};

/**
 * Count of Deals
 */
exports.countSavings = function (req, res) {
    Saving.count({},

        function (err, savingsCount) {
            if (err) {
                return res.status(400).send({
                    message: errorHandler.getErrorMessage(err)

                });
            } else {
                var data = {};
                data.count = savingsCount;
                res.jsonp(data);
            }
        });
};

///**
// * Count of Deals by User
// */
//exports.usersSavingsPostedTotal = function (req, res) {
//
//    Saving.count({
//
//            $where: function () {
//                return this.userIdString === req.params.userIdString;
//            }
//
//    },
//
//        function (err, savingsCount) {
//            if (err) {
//                return res.status(400).send({
//
//                    message: errorHandler.getErrorMessage(err)
//
//                });
//            } else {
//                var data = {};
//                data.count = savingsCount;
//                res.jsonp(data);
//            }
//        });
//};

exports.usersSavingsPostedTotal = function(req, res) {

    Saving.find( {

        userIdString: req.params.userIdString }).sort('-created').populate('_id').exec(function (err, savings) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(savings);
        }
    });
};

// Count Upvotes by a user

exports.usersUpvotesTotal = function(req, res) {

    Saving.find( {

        upVoters: req.params.userIdString }).sort('-created').populate('_id').exec(function (err, savings) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(savings);
        }
    });
};

// Count Upvotes by a user

/**
 * List of Savings
 */
exports.removeVotesDaily = function (req, res) {

    Saving.find().sort('created').populate('votes').exec(function (err, savings) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {

            for (var i = 0; i < savings.length; i++) {

                if(savings[i].votes > 100){

                    savings[i].votes = savings[i].votes - (savings[i].votes / 5);
                    savings[i].update();
                    console.log("removed votes");

                }else{
                    savings[i].votes = 100;
                    console.log("changed to 100");
                }

            }

            res.json(savings);
        }
    });

};

/**
 * App Upvote a saving.
 */
exports.appUpvoteSaving = function (req, res) {

    var saving = req.saving;

    saving = _.extend(saving, req.body);

    var hasVoted = saving.upVoters.filter(function (voter) {

            return voter === req.params.email;

        }).length > 0;

    if(!hasVoted){

        saving.votes++;
        saving.votesreal++;
        saving.upVoters.push(req.params.email);

    }

    var hasVoted3 = saving.downVoters.filter(function (voter) {

            return voter === req.params.email;

        }).length > 0;

    if (hasVoted3) {

        for (var i = saving.downVoters.length - 1; i >= 0; i--) {

            if (saving.downVoters[i] === req.params.email) {
                saving.downVoters.splice(i, 1);
            }
        }
    }

    saving.save(function (err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(saving);
        }
    });
};

// Count Upvotes by a user

/**
 * List of Savings
 */
exports.removeVotesDaily = function (req, res) {

    Saving.find().sort('created').populate('votes').exec(function (err, savings) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {

            for (var i = 0; i < savings.length; i++) {

                if(savings[i].votes > 100){

                    savings[i].votes = savings[i].votes - (savings[i].votes / 5);
                    savings[i].update();
                    console.log("removed votes");

                }else{
                    savings[i].votes = 100;
                    console.log("changed to 100");
                }

            }

            res.json(savings);
        }
    });

};

/**
 * App Downvote a saving.
 */
exports.appDownvoteSaving = function (req, res) {

    var saving = req.saving;

    saving = _.extend(saving, req.body);

    var hasVoted4 = saving.downVoters.filter(function (voter) {

            return voter === req.params.email;

        }).length > 0;

    if(!hasVoted4){

        saving.votes--;
        saving.votesreal--;
        saving.downVoters.push(req.params.email);

    }

    var hasVoted3 = saving.upVoters.filter(function (voter) {

            return voter === req.params.email;

        }).length > 0;

    if (hasVoted3) {

        for (var i = saving.upVoters.length - 1; i >= 0; i--) {

            if (saving.upVoters[i] === req.params.email) {
                saving.upVoters.splice(i, 1);
            }
        }
    }

    saving.save(function (err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)

            });

        } else {
            res.json(saving);
        }
    });
};

exports.listOf = function(req, res) {

    Saving.find( {

        user: req.params.userid }).sort('-created').exec(function(err, posts) {

    if (err) {
        return res.status(400).send({
            message: errorHandler.getErrorMessage(err)
        });
    } else {
        //console.log(req.params.userid);
        res.jsonp(posts);
    }
});
};

/**
 * Count of Deals Today
 */
exports.countSavingsToday = function (req, res) {
    Saving.count({

        $where: function () {
            return Date.now() - this._id.getTimestamp() < (24 * 60 * 60 * 1000);
        }

        },

        function (err, savingsCount) {
            if (err) {
                return res.status(400).send({
                    message: errorHandler.getErrorMessage(err)
                });
            } else {
                var data = {};
                data.count = savingsCount;
                res.jsonp(data);
            }
        });
};

/**
 * Update product picture
 */
exports.changeProductPictureSaving = function (req, res) {

    var user = req.user;
    var message = null;

    if (user) {
        fs.writeFile('./modules/savings/client/img/uploads/' + req.files.file.name, req.files.file.buffer, function (uploadError) {
            if (uploadError) {
                return res.status(400).send({
                    message: 'Error occurred while uploading profile picture'
                });
            } else {

                user.imageURL = './modules/savings/client/img/uploads/' + req.files.file.name;

                user.save(function (saveError) {
                    if (saveError) {
                        return res.status(400).send({
                            message: errorHandler.getErrorMessage(saveError)
                        });
                    } else {
                        req.login(user, function (err) {
                            if (err) {
                                res.status(400).send(err);
                            } else {
                                res.json(user);
                            }
                        });
                    }
                });
            }
        });
    } else {
        res.status(400).send({
            message: 'User is not signed in'
        });
    }
};
<commit_msg>Routes.<commit_after>'use strict';

/**
 * Module dependencies.
 */
var path = require('path'),
    fs = require('fs'),
    mongoose = require('mongoose'),
    Saving = mongoose.model('Saving'),
    User = mongoose.model('User'),
    errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')),
    _ = require('lodash');

/**
 * Create a saving
 */
exports.create = function (req, res) {
    var saving = new Saving(req.body);
    saving.user = req.user;

    saving.save(function (err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(saving);
        }
    });
};

/**
 * Show the current saving
 */
exports.read = function (req, res) {
    res.json(req.saving);
};

/**
 * Update a saving
 */
exports.update = function (req, res) {

    var saving = req.saving;

    //saving.title  = req.body.title;
    //saving.retailer  = req.body.retailer;
    //saving.price  = req.body.price;
    //saving.image  = req.body.image;
    //saving.votes = req.body.votes;
    //saving.votesreal = req.body.votesreal;
    //saving.urlimage  = req.body.urlimage;
    //saving.tags  = req.body.tags;
    //saving.upVoters  = req.body.upVoters;
    //saving.downVoters  = req.body.downVoters;
    //saving.link  = req.body.link;
    //saving.details  = req.body.details;
    //saving.currency  = req.body.currency;

    saving = _.extend(saving, req.body);

    saving.save(function (err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(saving);
        }
    });
};

/**
 * Delete an saving
 */
exports.delete = function (req, res) {
    var saving = req.saving;

    saving.remove(function (err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(saving);
        }
    });
};

/**
 * List of Savings
 */
exports.list = function (req, res) {
    Saving.find().sort('-created').populate('user').exec(function (err, savings) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(savings);
        }
    });
};

/**
 * Saving middleware
 */
exports.savingByID = function (req, res, next, id) {

    if (!mongoose.Types.ObjectId.isValid(id)) {
        return res.status(400).send({
            message: 'Saving is invalid'
        });
    }

    Saving.findById(id).populate('user').exec(function (err, saving) {
        if (err) {
            return next(err);
        } else if (!saving) {
            return res.status(404).send({
                message: 'No saving with that identifier has been found'
            });
        }
        req.saving = saving;
        next();
    });
};

/**
 * Count of Deals
 */
exports.countSavings = function (req, res) {
    Saving.count({},

        function (err, savingsCount) {
            if (err) {
                return res.status(400).send({
                    message: errorHandler.getErrorMessage(err)

                });
            } else {
                var data = {};
                data.count = savingsCount;
                res.jsonp(data);
            }
        });
};

///**
// * Count of Deals by User
// */
//exports.usersSavingsPostedTotal = function (req, res) {
//
//    Saving.count({
//
//            $where: function () {
//                return this.userIdString === req.params.userIdString;
//            }
//
//    },
//
//        function (err, savingsCount) {
//            if (err) {
//                return res.status(400).send({
//
//                    message: errorHandler.getErrorMessage(err)
//
//                });
//            } else {
//                var data = {};
//                data.count = savingsCount;
//                res.jsonp(data);
//            }
//        });
//};

exports.usersSavingsPostedTotal = function(req, res) {

    Saving.find( {

        userIdString: req.params.userIdString }).sort('-created').populate('_id').exec(function (err, savings) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(savings);
        }
    });
};

// Count Upvotes by a user

exports.usersUpvotesTotal = function(req, res) {

    Saving.find( {

        upVoters: req.params.userIdString }).sort('-created').populate('_id').exec(function (err, savings) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(savings);
        }
    });
};

// Count Upvotes by a user

/**
 * List of Savings
 */
exports.removeVotesDaily = function (req, res) {

    Saving.find().sort('created').populate('votes').exec(function (err, savings) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {

            for (var i = 0; i < savings.length; i++) {

                if(savings[i].votes > 100){

                    savings[i].votes = savings[i].votes - (savings[i].votes / 5);
                    savings[i].update();
                    console.log("removed votes");

                }else{
                    savings[i].votes = 100;
                    console.log("changed to 100");
                }

            }

            res.json(savings);
        }
    });

};

// /**
//  * App Upvote a saving.
//  */
// exports.appUpvoteSaving = function (req, res) {
//
//     var saving = req.saving;
//
//     saving = _.extend(saving, req.body);
//
//     var hasVoted = saving.upVoters.filter(function (voter) {
//
//             return voter === req.params.email;
//
//         }).length > 0;
//
//     if(!hasVoted){
//
//         saving.votes++;
//         saving.votesreal++;
//         saving.upVoters.push(req.params.email);
//
//     }
//
//     var hasVoted3 = saving.downVoters.filter(function (voter) {
//
//             return voter === req.params.email;
//
//         }).length > 0;
//
//     if (hasVoted3) {
//
//         for (var i = saving.downVoters.length - 1; i >= 0; i--) {
//
//             if (saving.downVoters[i] === req.params.email) {
//                 saving.downVoters.splice(i, 1);
//             }
//         }
//     }
//
//     saving.save(function (err) {
//         if (err) {
//             return res.status(400).send({
//                 message: errorHandler.getErrorMessage(err)
//             });
//         } else {
//             res.json(saving);
//         }
//     });
// };

// Count Upvotes by a user

/**
 * List of Savings
 */
exports.removeVotesDaily = function (req, res) {

    Saving.find().sort('created').populate('votes').exec(function (err, savings) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {

            for (var i = 0; i < savings.length; i++) {

                if(savings[i].votes > 100){

                    savings[i].votes = savings[i].votes - (savings[i].votes / 5);
                    savings[i].update();
                    console.log("removed votes");

                }else{
                    savings[i].votes = 100;
                    console.log("changed to 100");
                }

            }

            res.json(savings);
        }
    });

};

/**
 * App Downvote a saving.
 */
exports.appDownvoteSaving = function (req, res) {

    var saving = req.saving;

    saving = _.extend(saving, req.body);

    var hasVoted4 = saving.downVoters.filter(function (voter) {

            return voter === req.params.email;

        }).length > 0;

    if(!hasVoted4){

        saving.votes--;
        saving.votesreal--;
        saving.downVoters.push(req.params.email);

    }

    var hasVoted3 = saving.upVoters.filter(function (voter) {

            return voter === req.params.email;

        }).length > 0;

    if (hasVoted3) {

        for (var i = saving.upVoters.length - 1; i >= 0; i--) {

            if (saving.upVoters[i] === req.params.email) {
                saving.upVoters.splice(i, 1);
            }
        }
    }

    saving.save(function (err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)

            });

        } else {
            res.json(saving);
        }
    });
};

exports.listOf = function(req, res) {

    Saving.find( {

        user: req.params.userid }).sort('-created').exec(function(err, posts) {

    if (err) {
        return res.status(400).send({
            message: errorHandler.getErrorMessage(err)
        });
    } else {
        //console.log(req.params.userid);
        res.jsonp(posts);
    }
});
};

/**
 * Count of Deals Today
 */
exports.countSavingsToday = function (req, res) {
    Saving.count({

        $where: function () {
            return Date.now() - this._id.getTimestamp() < (24 * 60 * 60 * 1000);
        }

        },

        function (err, savingsCount) {
            if (err) {
                return res.status(400).send({
                    message: errorHandler.getErrorMessage(err)
                });
            } else {
                var data = {};
                data.count = savingsCount;
                res.jsonp(data);
            }
        });
};

/**
 * Update product picture
 */
exports.changeProductPictureSaving = function (req, res) {

    var user = req.user;
    var message = null;

    if (user) {
        fs.writeFile('./modules/savings/client/img/uploads/' + req.files.file.name, req.files.file.buffer, function (uploadError) {
            if (uploadError) {
                return res.status(400).send({
                    message: 'Error occurred while uploading profile picture'
                });
            } else {

                user.imageURL = './modules/savings/client/img/uploads/' + req.files.file.name;

                user.save(function (saveError) {
                    if (saveError) {
                        return res.status(400).send({
                            message: errorHandler.getErrorMessage(saveError)
                        });
                    } else {
                        req.login(user, function (err) {
                            if (err) {
                                res.status(400).send(err);
                            } else {
                                res.json(user);
                            }
                        });
                    }
                });
            }
        });
    } else {
        res.status(400).send({
            message: 'User is not signed in'
        });
    }
};
<|endoftext|>


<commit_before>// @flow

import { NavigationActions } from 'react-navigation';

type ScreenDetectType = 'SCREEN_DETECT';
export const SCREEN_DETECT: ScreenDetectType = 'SCREEN_DETECT';

type ScreenBeaconListType = 'SCREEN_BEACON_LIST';
export const SCREEN_BEACON_LIST: ScreenBeaconListType = 'SCREEN_BEACON_LIST';

type ScreenDataType = 'SCREEN_DATA';
export const SCREEN_DATA: ScreenDataType = 'SCREEN_DATA';

type ScreenBeaconInfoDetectType = 'SCREEN_BEACON_INFO_DETECT';
export const SCREEN_BEACON_INFO_DETECT: ScreenBeaconInfoDetectType = 'SCREEN_BEACON_INFO_DETECT';

type ScreenBeaconInfoBeaconsType = 'SCREEN_BEACON_INFO_BEACONS';
export const SCREEN_BEACON_INFO_BEACONS: ScreenBeaconInfoBeaconsType = 'SCREEN_BEACON_INFO_BEACONS';

type TabDetectType = 'TAB_DETECT';
export const TAB_DETECT: TabDetectType = 'TAB_DETECT';

type TabBeaconsType = 'TAB_BEACONS';
export const TAB_BEACONS: TabBeaconsType = 'TAB_BEACONS';

type TabDataType = 'TAB_DATA';
export const TAB_DATA: TabDataType = 'TAB_DATA';

export type ScreensType =
  | ScreenDetectType
  | ScreenBeaconListType
  | ScreenDataType
  | ScreenBeaconInfoDetectType
  | ScreenBeaconInfoBeaconsType
  | TabDetectType
  | TabBeaconsType
  | TabDataType;

export function navigate(screenName: ScreensType, props: ?any): void {
  return NavigationActions.navigate({
    routeName: screenName,
    params: { ...props },
  });
}
export type NavigateType = typeof navigate;
<commit_msg>Create new navigateAndCreateBeacon action<commit_after>// @flow

import { NavigationActions } from 'react-navigation';
import { List } from 'immutable';

import { Beacon, updateBeacon } from './beacons';

type ScreenDetectType = 'SCREEN_DETECT';
export const SCREEN_DETECT: ScreenDetectType = 'SCREEN_DETECT';

type ScreenBeaconListType = 'SCREEN_BEACON_LIST';
export const SCREEN_BEACON_LIST: ScreenBeaconListType = 'SCREEN_BEACON_LIST';

type ScreenDataType = 'SCREEN_DATA';
export const SCREEN_DATA: ScreenDataType = 'SCREEN_DATA';

type ScreenBeaconInfoDetectType = 'SCREEN_BEACON_INFO_DETECT';
export const SCREEN_BEACON_INFO_DETECT: ScreenBeaconInfoDetectType = 'SCREEN_BEACON_INFO_DETECT';

type ScreenBeaconInfoBeaconsType = 'SCREEN_BEACON_INFO_BEACONS';
export const SCREEN_BEACON_INFO_BEACONS: ScreenBeaconInfoBeaconsType = 'SCREEN_BEACON_INFO_BEACONS';

type TabDetectType = 'TAB_DETECT';
export const TAB_DETECT: TabDetectType = 'TAB_DETECT';

type TabBeaconsType = 'TAB_BEACONS';
export const TAB_BEACONS: TabBeaconsType = 'TAB_BEACONS';

type TabDataType = 'TAB_DATA';
export const TAB_DATA: TabDataType = 'TAB_DATA';

export type ScreensType =
  | ScreenDetectType
  | ScreenBeaconListType
  | ScreenDataType
  | ScreenBeaconInfoDetectType
  | ScreenBeaconInfoBeaconsType
  | TabDetectType
  | TabBeaconsType
  | TabDataType;

export function navigateAndCreateBeacon(screenName: ScreensType, props: ?any, uuid): void {
  return (dispatch, getState) => {
    const newBeacon = Beacon({
      uuid,
      name: 'Unnamed',
      floor: 'Unassigned',
      regions: List(),
      blocks: List(),
    });

    dispatch(updateBeacon(newBeacon));

    dispatch(
      NavigationActions.navigate({
        routeName: screenName,
        params: { ...props },
      }),
    );
  };
}

export function navigate(screenName: ScreensType, props: ?any): void {
  return NavigationActions.navigate({
    routeName: screenName,
    params: { ...props },
  });
}
export type NavigateType = typeof navigate;
<|endoftext|>


<commit_before>/*
 * grunt-htmltosass
 *
 *
 * Copyright (c) 2013 Yuri akella Artyukh
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

	// Please see the Grunt documentation for more information regarding task
	// creation: http://gruntjs.com/creating-tasks

	grunt.registerMultiTask('htmltosass', 'Your task description goes here.', function() {
		// Merge task-specific and/or target-specific options with these defaults.
		var options = this.options({
			punctuation: '.',
			separator: ', '
		});

		// Iterate over all specified file groups.
		this.files.forEach(function(f) {
			// Concat specified files.
			var src = f.src.filter(function(filepath) {
				// Warn on and remove invalid source files (if nonull was set).
				if (!grunt.file.exists(filepath)) {
					grunt.log.warn('Source file "' + filepath + '" not found.');
					return false;
				} else {
					return true;
				}
			}).map(function(filepath) {
				// Read file source.
				return grunt.file.read(filepath);
			}).join(grunt.util.normalizelf(options.separator));

			// Handle options.
			src += options.punctuation;
			//src += '-------------';
			// here goes html 2 sass conversion, magic
			// BEGIN MAGIC
			//===================================
			var allclasses;
			var uniqueclasses;
			var sass = '';
			allclasses = src.match(/(class="([^"]+)")/g).map(function(s){return s.replace(/class="|"/g, '')}).join(' ').split(' '); //tnx Egor Lvivski for this

			uniqueclasses = allclasses.filter(function(elem, pos) {
					return allclasses.indexOf(elem) == pos;
			});// removing duplicates

			uniqueclasses.sort();//alphabet sorting

			var currentdad, a;
			// @todo generate SASS file based on this
			for (var i = 0; i < uniqueclasses.length; i++) {
				currentdad = uniqueclasses[i];
				//sass += uniqueclasses[i]+'{}\n';
				if(uniqueclasses[i].indexOf("__") != -1){
					sass += '\t.' + uniqueclasses[i] + '{\n\t\n\t}\n'; // elements
				}
				else{
					if(i!=0){a='}\n.';}
					else{a='.';}
					sass += a+uniqueclasses[i]+'{\n'; // block
				}
				//Do something
			}
			sass += '}'; //last bracket
			grunt.log.writeln(sass); // works!

			//===================================
			 // END OF MAGIC
			// Write the destination file.
			// for now jus
			grunt.file.write(f.dest, sass);

			// Print a success message.
			grunt.log.writeln('File "' + f.dest + '" created.');
		});
	});

};
<commit_msg>supporting modifications<commit_after>/*
 * grunt-htmltosass
 *
 *
 * Copyright (c) 2013 Yuri akella Artyukh
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

	// Please see the Grunt documentation for more information regarding task
	// creation: http://gruntjs.com/creating-tasks

	grunt.registerMultiTask('htmltosass', 'Your task description goes here.', function() {
		// Merge task-specific and/or target-specific options with these defaults.
		var options = this.options({
			punctuation: '.',
			separator: ', '
		});

		// Iterate over all specified file groups.
		this.files.forEach(function(f) {
			// Concat specified files.
			var src = f.src.filter(function(filepath) {
				// Warn on and remove invalid source files (if nonull was set).
				if (!grunt.file.exists(filepath)) {
					grunt.log.warn('Source file "' + filepath + '" not found.');
					return false;
				} else {
					return true;
				}
			}).map(function(filepath) {
				// Read file source.
				return grunt.file.read(filepath);
			}).join(grunt.util.normalizelf(options.separator));

			// Handle options.
			src += options.punctuation;
			//src += '-------------';
			// here goes html 2 sass conversion, magic
			// BEGIN MAGIC
			//===================================
			var allclasses;
			var uniqueclasses;
			var sass = '';
			allclasses = src.match(/(class="([^"]+)")/g).map(function(s){return s.replace(/class="|"/g, '')}).join(' ').split(' '); //tnx Egor Lvivski for this

			uniqueclasses = allclasses.filter(function(elem, pos) {
					return allclasses.indexOf(elem) == pos;
			});// removing duplicates

			uniqueclasses.sort();//alphabet sorting

			var currentdad, a, s;
			// @todo generate SASS file based on this
			for (var i = 0; i < uniqueclasses.length; i++) {
				s = uniqueclasses[i];
				//sass += uniqueclasses[i]+'{}\n';
				if(s.indexOf("__") != -1 || s.indexOf("_") != -1){
					if(s.indexOf("__") == -1 && s.indexOf("_") != -1){
						sass += '\t&.' + s + '{\n\t\t\n\t}\n'; // modification
					}
					else{//this is element inside block
						sass += '\t.' + s + '{\n\t\t\n\t}\n'; // element
					}
				}
				else{
					if(i!=0){a='}\n.';}
					else{a='.';}
					sass += a+s+'{\n'; // block
				}
				//Do something with modifications
			}
			sass += '}'; //last bracket
			grunt.log.writeln(sass); // works!

			//===================================
			 // END OF MAGIC
			// Write the destination file.
			// for now jus
			grunt.file.write(f.dest, sass);

			// Print a success message.
			grunt.log.writeln('File "' + f.dest + '" created.');
		});
	});

};
<|endoftext|>


<commit_before>import React from 'react';
import { NavLink } from 'fluxible-router';
import SearchBox  from '../Search/AutocompleteComponents/HeaderSearchBox';
//import UserNotificationsBadge from '../User/UserNotificationsPanel/UserNotificationsBadge';
import LoginModal from '../Login/LoginModal.js';
import HeaderDropdown from '../Login/HeaderDropdown.js';
import {connectToStores} from 'fluxible-addons-react';
import UserProfileStore from '../../stores/UserProfileStore';
import userSignOut from '../../actions/user/userSignOut';
import LocaleSwitcher from '../LocaleSwitcher/LocaleSwitcher';
import CookieBanner from 'react-cookie-banner';
import BannerContent from 'react-cookie-banner';
import cookie from 'react-cookie';

let MediaQuery = require ('react-responsive');
class Header extends React.Component {

    constructor(props) {
        super(props);
        this.state =  {user_cookies: cookie.load('user-has-accepted-cookies')};
    }
    componentDidMount() {
        $(this.refs.menubar)
            .sidebar({ 'silent': true, 'transition': 'overlay', 'mobileTransition': 'overlay' });
    }

    toggleSidebar() {
        $(this.refs.menubar)
            .sidebar('toggle');
    }

    closeSidebar(event) {
        if(($(event.target).hasClass('item') && !$(event.target).hasClass('search')))
            $(this.refs.menubar).sidebar('hide');
    }

    handleLoginButton() {
        $('.ui.login.modal')
            .modal('toggle');
        this.closeSidebar({target: ''});
    }

    logout() {
        this.context.executeAction(userSignOut, { username: this.props.UserProfileStore.username });
    }

    render() {
        let loginButton = <button ref="loginButton" className="ui inverted button" onClick={this.handleLoginButton.bind(this)}>Sign In</button>;
        let mobileLoginButton =  Sign in;
        let notification_locale = '';
        let cookieBanner = '';

        if (this.props.UserProfileStore.username !== '') {
            loginButton = <HeaderDropdown/>;
            mobileLoginButton = (

              <NavLink className="item" href={'/user/' + this.props.UserProfileStore.username}>My Decks</NavLink>
              <NavLink className="item" href={'/user/' + this.props.UserProfileStore.username + '/settings/profile'}>My Settings</NavLink>
              Logout

);
            notification_locale = ''; ///*<UserNotificationsBadge className="ui item"/>*/

        } else{
            notification_locale =
<LocaleSwitcher className = 'ui item'/>
;
        }

        if (!this.state.user_cookies) {
            cookieBanner = <CookieBanner
            message='This website uses cookies to ensure you get the best experience on our website.'
            cookie='user-has-accepted-cookies'
            dismissOnScroll={false}
            onAccept={() => {}}
            />;
        }

        return (

            {cookieBanner}
              <MediaQuery minDeviceWidth={768} values={{deviceWidth: 1600}}>

                            <SearchBox className="item"/>

                              <NavLink routeName="addDeck" activeClass="active" className="ui right labeled icon button">
                                  Add deck
                              </NavLink>

                            {notification_locale}

{loginButton}<LoginModal/>

              </MediaQuery>
              <MediaQuery maxDeviceWidth={767}>

                  <button className="ui icon button item" onClick={this.toggleSidebar.bind(this)}></button>

                    <NavLink className="item" href='/'>
                         SlideWiki
                    </NavLink>

                    <NavLink className="item" href='/'>
                         Homepage
                    </NavLink>
                    <NavLink className="item" routeName="addDeck">
                        Add Deck
                    </NavLink>
                    {/*<UserNotificationsBadge className="ui item"/>*/}
                    {mobileLoginButton}
                    <LoginModal/>

                        <SearchBox className="item"/>

              </MediaQuery>

        );
    }
}

Header.contextTypes = {
    executeAction: React.PropTypes.func.isRequired,
    getUser: React.PropTypes.func
};

Header = connectToStores(Header, [UserProfileStore], (context, props) => {
    return {
        UserProfileStore: context.getStore(UserProfileStore).getState()
    };
});

export default Header;
<commit_msg>link to logo fix<commit_after>import React from 'react';
import { NavLink } from 'fluxible-router';
import SearchBox  from '../Search/AutocompleteComponents/HeaderSearchBox';
//import UserNotificationsBadge from '../User/UserNotificationsPanel/UserNotificationsBadge';
import LoginModal from '../Login/LoginModal.js';
import HeaderDropdown from '../Login/HeaderDropdown.js';
import {connectToStores} from 'fluxible-addons-react';
import UserProfileStore from '../../stores/UserProfileStore';
import userSignOut from '../../actions/user/userSignOut';
import LocaleSwitcher from '../LocaleSwitcher/LocaleSwitcher';
import CookieBanner from 'react-cookie-banner';
import BannerContent from 'react-cookie-banner';
import cookie from 'react-cookie';

let MediaQuery = require ('react-responsive');
class Header extends React.Component {

    constructor(props) {
        super(props);
        this.state =  {user_cookies: cookie.load('user-has-accepted-cookies')};
    }
    componentDidMount() {
        $(this.refs.menubar)
            .sidebar({ 'silent': true, 'transition': 'overlay', 'mobileTransition': 'overlay' });
    }

    toggleSidebar() {
        $(this.refs.menubar)
            .sidebar('toggle');
    }

    closeSidebar(event) {
        if(($(event.target).hasClass('item') && !$(event.target).hasClass('search')))
            $(this.refs.menubar).sidebar('hide');
    }

    handleLoginButton() {
        $('.ui.login.modal')
            .modal('toggle');
        this.closeSidebar({target: ''});
    }

    logout() {
        this.context.executeAction(userSignOut, { username: this.props.UserProfileStore.username });
    }

    render() {
        let loginButton = <button ref="loginButton" className="ui inverted button" onClick={this.handleLoginButton.bind(this)}>Sign In</button>;
        let mobileLoginButton =  Sign in;
        let notification_locale = '';
        let cookieBanner = '';

        if (this.props.UserProfileStore.username !== '') {
            loginButton = <HeaderDropdown/>;
            mobileLoginButton = (

              <NavLink className="item" href={'/user/' + this.props.UserProfileStore.username}>My Decks</NavLink>
              <NavLink className="item" href={'/user/' + this.props.UserProfileStore.username + '/settings/profile'}>My Settings</NavLink>
              Logout

);
            notification_locale = ''; ///*<UserNotificationsBadge className="ui item"/>*/

        } else{
            notification_locale =
<LocaleSwitcher className = 'ui item'/>
;
        }

        if (!this.state.user_cookies) {
            cookieBanner = <CookieBanner
            message='This website uses cookies to ensure you get the best experience on our website.'
            cookie='user-has-accepted-cookies'
            dismissOnScroll={false}
            onAccept={() => {}}
            />;
        }

        return (

            {cookieBanner}
              <MediaQuery minDeviceWidth={768} values={{deviceWidth: 1600}}>

                            <SearchBox className="item"/>

                              <NavLink routeName="addDeck" activeClass="active" className="ui right labeled icon button">
                                  Add deck
                              </NavLink>

                            {notification_locale}

{loginButton}<LoginModal/>

              </MediaQuery>
              <MediaQuery maxDeviceWidth={767}>

                  <button className="ui icon button item" onClick={this.toggleSidebar.bind(this)}></button>

                    <NavLink className="item" href='/'>
                         SlideWiki
                    </NavLink>

                    <NavLink className="item" href='/'>
                         Homepage
                    </NavLink>
                    <NavLink className="item" routeName="addDeck">
                        Add Deck
                    </NavLink>
                    {/*<UserNotificationsBadge className="ui item"/>*/}
                    {mobileLoginButton}
                    <LoginModal/>

                        <SearchBox className="item"/>

              </MediaQuery>

        );
    }
}

Header.contextTypes = {
    executeAction: React.PropTypes.func.isRequired,
    getUser: React.PropTypes.func
};

Header = connectToStores(Header, [UserProfileStore], (context, props) => {
    return {
        UserProfileStore: context.getStore(UserProfileStore).getState()
    };
});

export default Header;
<|endoftext|>


<commit_before>const { BrowserWindow, ipcMain, Menu, app, dialog } = require('electron');
const path = require('path');
const template = require('./menus/mainMenu');
const registerShortcuts = require('./localShortcuts');
const registerIpcListeners = require('./ipcMainListeners');
require('electron-debug')();

const isDevelopment = (process.env.NODE_ENV === 'development');

const installExtensions = async () => {
  const installer = require('electron-devtools-installer');
  const extensions = [
    'REACT_DEVELOPER_TOOLS',
    'REDUX_DEVTOOLS'
  ];
  const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
  for (const name of extensions) {
    try {
      await installer.default(installer[name], forceDownload);
    } catch (e) {
      console.log(`Error installing ${name} extension: ${e.message}`);
    }
  }
};

//Main window Init
app.on('ready', async () => {

  //install React & Redux Extensions
  await installExtensions();

  //initialize main window
  let win = new BrowserWindow({
    width: 1000,
    height: 800
  });

  //load index.html to main window
  win.loadURL('file://' + path.join(__dirname, '../renderer/index.html'));

  //initialize menus
  let menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);

  //toggle devtools only if development
  if (isDevelopment) win.toggleDevTools();

  //put Main window instance in global variable for use in other modules
  global.mainWindow = win;

  //Register listeners and shortcuts
  registerIpcListeners();
  registerShortcuts(win);
});
<commit_msg>removed unused packages from electron module in main.js<commit_after>const { app, BrowserWindow, Menu } = require('electron');
const path = require('path');
const template = require('./menus/mainMenu');
const registerShortcuts = require('./localShortcuts');
const registerIpcListeners = require('./ipcMainListeners');
require('electron-debug')();

const isDevelopment = (process.env.NODE_ENV === 'development');

const installExtensions = async () => {
  const installer = require('electron-devtools-installer');
  const extensions = [
    'REACT_DEVELOPER_TOOLS',
    'REDUX_DEVTOOLS'
  ];
  const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
  for (const name of extensions) {
    try {
      await installer.default(installer[name], forceDownload);
    } catch (e) {
      console.log(`Error installing ${name} extension: ${e.message}`);
    }
  }
};

//Main window Init
app.on('ready', async () => {

  //install React & Redux Extensions
  await installExtensions();

  //initialize main window
  let win = new BrowserWindow({
    width: 1000,
    height: 800
  });

  //load index.html to main window
  win.loadURL('file://' + path.join(__dirname, '../renderer/index.html'));

  //initialize menus
  let menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);

  //toggle devtools only if development
  if (isDevelopment) win.toggleDevTools();

  //put Main window instance in global variable for use in other modules
  global.mainWindow = win;

  //Register listeners and shortcuts
  registerIpcListeners();
  registerShortcuts(win);
});
<|endoftext|>


<commit_before>// Unit test for a.model (plugin)

module('plugin/model.js', {
    setup: function() {

    },
    teardown: function() {
        a.modelManager.clear();
    }
});

// Test nullable properties
test('a.model.property-nullable', function() {
    var unittest = a.model('unittest-nullable', {
        testnullable: {
            nullable: true,
            init: 'ok'
        },
        testnotnullable: {
            nullable: false,
            init: 'ok'
        }
    });
    var unit = new unittest();

    // Test changing data for null
    unit.set('testnullable', null);
    unit.set('testnotnullable', null);

    strictEqual(unit.get('testnullable'), null, 'Test nullable');
    strictEqual(unit.get('testnotnullable'), 'ok', 'Test not nullable');
});

// Test init properties
test('a.model.property-init', function() {
    var unittest = a.model('unittest-prop-init', {
        testinit: {
            init: 'ok'
        }
    });

    var unit = new unittest();

    // Test changing data
    strictEqual(unit.get('testinit'), 'ok', 'Test init');

    unit.set('testinit', 'something');
    strictEqual(unit.get('testinit'), 'something', 'Test erase init');

    unit.init();

    strictEqual(unit.get('testinit'), 'ok', 'Test clear init');
});

// Test property needed
test('a.model.property-needed', function() {
    var unittest = a.model('unittest-needed', {
        need: {
            needed: true,
            init: 'ok'
        },
        notneeded: {
            needed: false,
            init: 'ok'
        }
    });

    var unit = new unittest();

    unit.takeSnapshot();
    var snapshot = unit.differenceSnapshot(true);

    // Test outputted value
    strictEqual(snapshot.needed, undefined);
    strictEqual(snapshot.need, 'ok');
});

// Test property check
test('a.model.property-check', function() {
    var unittest = a.model('unittest-check', {
        testcheck: {
            init: 'ok',
            check: 'String'
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testcheck'), 'ok', 'Test init value');

    unit.set('testcheck', 'get');
    strictEqual(unit.get('testcheck'), 'get', 'Test second value');

    unit.get('testcheck', 12);
    strictEqual(unit.get('testcheck'), 'get', 'Test thrid value not setted');
});

// Test property check, for a model (a model include a model)
test('a.model.property-check-model', function() {
    var child = a.model('unittest-check-child', {
        test: {
            init: 'ok',
            check: 'String',
            validate: function(value) {
                strictEqual(value, 'piou');
            }
        }
    });

    var parent = a.model('unittest-check-parent', {
        sub: {
            check: 'unittest-check-child'
        }
    });

    // We create a new parent, and check validation is raised on child
    // element
    var c = new parent(),
        d = new child();

    c.set('sub', d);

    // Set element raise the validate method
    c.get('sub').set('test', 'piou');
});

// Test property validate
test('a.model.property-validate', function() {
    var unittest = a.model('unittest-validate', {
        testvalidate: {
            init: 'ok',
            validate: function(value, old) {
                if(value == 'something') {
                    return true;
                }
            }
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testvalidate'), 'ok', 'Test init value');

    unit.set('testvalidate', 'another');
    strictEqual(unit.get('testvalidate'), 'ok', 'Test still init value');

    unit.set('testvalidate', 'something');
    strictEqual(unit.get('testvalidate'), 'something', 'Test accepted');
});

// Test property transform
test('a.model.property-transform', function() {
    var unittest = a.model('unittest-transform', {
        testtransform: {
            init: 'ok',
            transform: function piou(value, old) {
                return '' + old + value;
            }
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testtransform'), 'ok', 'Test init value');

    unit.set('testtransform', 'something');
    strictEqual(unit.get('testtransform'), 'oksomething', 'Test concat');

    unit.set('testtransform', 'another');
    strictEqual(unit.get('testtransform'), 'oksomethinganother', 'Second');
});

// Test property event
asyncTest('a.model.property-event', function() {
    expect(2);

    var unittest = a.model('unittest-event', {
        evt: {
            init: 'another',
            event: 'super'
        }
    });

    var unit = new unittest();

    function eventMatcher(data) {
        if(data.value == 'something') {
            strictEqual(data.value, 'something', 'Test something value');
        } else {
            strictEqual(data.value, 'ok', 'Test ok value');
            start();
        }
    };

    unit.bind('super', eventMatcher);

    unit.set('evt', 'something');

    setTimeout(function() {
        unit.set('evt', 'ok');
    }, 150);
});

// Test property apply
asyncTest('a.model.property-apply', function() {
    expect(1);

    var unittest = a.model('unittest-apply', {
        app: {
            init: 'another',
            apply: function(value, old) {
                strictEqual(value, 'ok');
                start();
            }
        }
    });

    var unit = new unittest();

    unit.set('app', 'ok');
});

// Test list function
test('a.model.list', function() {
    var unittest = a.model('unittest-list', {
        A: {
            init: 'ok'
        },
        B: {
            init: 'something'
        }
    });

    var unit = new unittest();
    var list = unit.list();

    strictEqual(list.join(','), 'A,B');
});

// Test has function
test('a.model.has', function() {
    var unittest = a.model('unittest-has', {
        A: {
            init: 'ok'
        },
        B: {
            init: 'something'
        }
    });

    var unit = new unittest();

    strictEqual(unit.has('A'), true);
    strictEqual(unit.has('B'), true);
    strictEqual(unit.has('C'), false);
});

// Test init function
test('a.model.init', function() {
    var unittest = a.model('unittest-init', {
        testA: {
            init: 'ok'
        },
        testB: {
            init: 'something'
        },
        testC: {
            // Value will be erased on first loading
            value: 'notok'
        }
    });

    var unit = new unittest();

    // First init
    strictEqual(unit.get('testA'), 'ok', 'Test init1');
    strictEqual(unit.get('testB'), 'something', 'Test init2');
    strictEqual(unit.get('testC'), null, 'Test init3');

    // Change init
    unit.set('testA', 'another');
    unit.set('testB', 'stuff');
    unit.set('testC', 'great');

    strictEqual(unit.get('testA'), 'another', 'Test change init1');
    strictEqual(unit.get('testB'), 'stuff', 'Test change init2');
    strictEqual(unit.get('testC'), 'great', 'Test change init3');

    // Rollback init
    unit.init();

    // Second init
    strictEqual(unit.get('testA'), 'ok', 'Test rollback init1');
    strictEqual(unit.get('testB'), 'something', 'Test rollback init2');
    strictEqual(unit.get('testC'), null, 'Test rollback init3');
});

// Test jsons function
test('a.model.json', function() {
    var unittest = a.model('unittest-json', {
        testA: {
            init: 'something'
        },
        testB: {
            init: 'great'
        }
    });

    var unit = new unittest();
    unit.set('testA', 'another');
    var json = unit.toJSON();

    strictEqual(json, '{"testA":"another","testB":"great"}', 'Test JSON');

    var second = new unittest();
    second.fromJSON(json);

    var alternative = second.toJSON();

    strictEqual(alternative, '{"testA":"another","testB":"great"}', 'Test second');
});

// Test Object output
test('a.model.object', function() {
    var unittest = a.model('unittest-object', {
        testA: {
            init: 'something'
        },
        testB: {
            init: 'great'
        }
    });

    var unit = new unittest();
    unit.set('testA', 'another');
    var obj1 = unit.toObject();

    strictEqual(obj1.testA, 'another', 'Test first Object');
    strictEqual(obj1.testB, 'great', 'Test first Object');

    var second = new unittest();
    second.fromObject(obj1);

    var obj2 = second.toObject();

    strictEqual(obj2.testA, 'another', 'Test second Object');
    strictEqual(obj2.testB, 'great', 'Test second Object');
});

// Test snapshot function
test('a.model.snapshot', function() {
    var unittest = a.model('unittest-snapshot', {
        snap: {
            needed: true,
            init: 'ok'
        },
        nosnap: {
            init: 'notok'
        },
        so: {
            init: 'something'
        }
    });

    var unit = new unittest();
    // Taking snapshot
    unit.takeSnapshot();

    var firstSimpleSnapshot  = a.parser.json.stringify(
                    unit.differenceSnapshot(true)
        ),
        firstComplexSnapshot = a.parser.json.stringify(
                    unit.differenceSnapshot(false)
        );

    strictEqual(firstSimpleSnapshot, '{"snap":"ok"}');
    strictEqual(firstComplexSnapshot, '{"snap":{"value":"ok","old":"ok"}}')
});

// Test model manager
test('a.modelManager', function() {
    var model = a.model('modelmanagertest', {}, null);

    var instance1 = new model(),
        instance2 = new model();

    var storedInstance1 = a.modelManager.get(instance1.uid),
        storedInstance2 = a.modelManager.get(instance2.uid);

    strictEqual(storedInstance1.uid, instance1.uid);
    strictEqual(storedInstance2.uid, instance2.uid);

    var list = a.modelManager.getByName('modelmanagertest');

    // We test the list element before removing everything inside
    strictEqual(list.length, 2);
    if(list[0].uid == instance1.uid) {
        strictEqual(list[0].uid, instance1.uid);
        strictEqual(list[1].uid, instance2.uid);
    } else {
        strictEqual(list[1].uid, instance1.uid);
        strictEqual(list[0].uid, instance2.uid);
    }

    a.modelManager.remove(storedInstance1.uid);
    strictEqual(a.modelManager.get(instance1.uid), null);
    strictEqual(a.modelManager.get(instance2.uid).uid, instance2.uid);

    a.modelManager.remove(storedInstance2.uid);
});

// Unit test multiple model management
asyncTest('a.model.model-multiple', function() {
    expect(4);

    var unittest = a.model('unittest-multiple', {
        id: {
            init: 0,
            event: 'yatta'
        }
    });

    var unittest1 = new unittest(),
        unittest2 = new unittest();

    unittest1.bind('yatta', function(data) {
        strictEqual(data.value, 5, 'Testing data update 1');
        strictEqual(unittest1.get('id'), 5, 'Testing model update 1');
    });
    unittest2.bind('yatta', function(data) {
        strictEqual(data.value, 6, 'Testing data update 2');
        strictEqual(unittest2.get('id'), 6, 'Testing model update 2');
        start();
    });

    unittest1.set('id', 5);
    unittest2.set('id', 6);
});

test('a.model.validates', function() {
    ok(1==1);
});

test('a.model.requests', function() {
    ok(1==1);
});<commit_msg>Adding unit test for searchInstance element.<commit_after>// Unit test for a.model (plugin)

module('plugin/model.js', {
    setup: function() {

    },
    teardown: function() {
        a.modelManager.clear();
    }
});

// Test nullable properties
test('a.model.property-nullable', function() {
    var unittest = a.model('unittest-nullable', {
        testnullable: {
            nullable: true,
            init: 'ok'
        },
        testnotnullable: {
            nullable: false,
            init: 'ok'
        }
    });
    var unit = new unittest();

    // Test changing data for null
    unit.set('testnullable', null);
    unit.set('testnotnullable', null);

    strictEqual(unit.get('testnullable'), null, 'Test nullable');
    strictEqual(unit.get('testnotnullable'), 'ok', 'Test not nullable');
});

// Test init properties
test('a.model.property-init', function() {
    var unittest = a.model('unittest-prop-init', {
        testinit: {
            init: 'ok'
        }
    });

    var unit = new unittest();

    // Test changing data
    strictEqual(unit.get('testinit'), 'ok', 'Test init');

    unit.set('testinit', 'something');
    strictEqual(unit.get('testinit'), 'something', 'Test erase init');

    unit.init();

    strictEqual(unit.get('testinit'), 'ok', 'Test clear init');
});

// Test property needed
test('a.model.property-needed', function() {
    var unittest = a.model('unittest-needed', {
        need: {
            needed: true,
            init: 'ok'
        },
        notneeded: {
            needed: false,
            init: 'ok'
        }
    });

    var unit = new unittest();

    unit.takeSnapshot();
    var snapshot = unit.differenceSnapshot(true);

    // Test outputted value
    strictEqual(snapshot.needed, undefined);
    strictEqual(snapshot.need, 'ok');
});

// Test property check
test('a.model.property-check', function() {
    var unittest = a.model('unittest-check', {
        testcheck: {
            init: 'ok',
            check: 'String'
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testcheck'), 'ok', 'Test init value');

    unit.set('testcheck', 'get');
    strictEqual(unit.get('testcheck'), 'get', 'Test second value');

    unit.get('testcheck', 12);
    strictEqual(unit.get('testcheck'), 'get', 'Test thrid value not setted');
});

// Test property check, for a model (a model include a model)
test('a.model.property-check-model', function() {
    var child = a.model('unittest-check-child', {
        test: {
            init: 'ok',
            check: 'String',
            validate: function(value) {
                strictEqual(value, 'piou');
            }
        }
    });

    var parent = a.model('unittest-check-parent', {
        sub: {
            check: 'unittest-check-child'
        }
    });

    // We create a new parent, and check validation is raised on child
    // element
    var c = new parent(),
        d = new child();

    c.set('sub', d);

    // Set element raise the validate method
    c.get('sub').set('test', 'piou');
});

// Test property validate
test('a.model.property-validate', function() {
    var unittest = a.model('unittest-validate', {
        testvalidate: {
            init: 'ok',
            validate: function(value, old) {
                if(value == 'something') {
                    return true;
                }
            }
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testvalidate'), 'ok', 'Test init value');

    unit.set('testvalidate', 'another');
    strictEqual(unit.get('testvalidate'), 'ok', 'Test still init value');

    unit.set('testvalidate', 'something');
    strictEqual(unit.get('testvalidate'), 'something', 'Test accepted');
});

// Test property transform
test('a.model.property-transform', function() {
    var unittest = a.model('unittest-transform', {
        testtransform: {
            init: 'ok',
            transform: function piou(value, old) {
                return '' + old + value;
            }
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testtransform'), 'ok', 'Test init value');

    unit.set('testtransform', 'something');
    strictEqual(unit.get('testtransform'), 'oksomething', 'Test concat');

    unit.set('testtransform', 'another');
    strictEqual(unit.get('testtransform'), 'oksomethinganother', 'Second');
});

// Test property event
asyncTest('a.model.property-event', function() {
    expect(2);

    var unittest = a.model('unittest-event', {
        evt: {
            init: 'another',
            event: 'super'
        }
    });

    var unit = new unittest();

    function eventMatcher(data) {
        if(data.value == 'something') {
            strictEqual(data.value, 'something', 'Test something value');
        } else {
            strictEqual(data.value, 'ok', 'Test ok value');
            start();
        }
    };

    unit.bind('super', eventMatcher);

    unit.set('evt', 'something');

    setTimeout(function() {
        unit.set('evt', 'ok');
    }, 150);
});

// Test property apply
asyncTest('a.model.property-apply', function() {
    expect(1);

    var unittest = a.model('unittest-apply', {
        app: {
            init: 'another',
            apply: function(value, old) {
                strictEqual(value, 'ok');
                start();
            }
        }
    });

    var unit = new unittest();

    unit.set('app', 'ok');
});

// Test list function
test('a.model.list', function() {
    var unittest = a.model('unittest-list', {
        A: {
            init: 'ok'
        },
        B: {
            init: 'something'
        }
    });

    var unit = new unittest();
    var list = unit.list();

    strictEqual(list.join(','), 'A,B');
});

// Test has function
test('a.model.has', function() {
    var unittest = a.model('unittest-has', {
        A: {
            init: 'ok'
        },
        B: {
            init: 'something'
        }
    });

    var unit = new unittest();

    strictEqual(unit.has('A'), true);
    strictEqual(unit.has('B'), true);
    strictEqual(unit.has('C'), false);
});

// Test init function
test('a.model.init', function() {
    var unittest = a.model('unittest-init', {
        testA: {
            init: 'ok'
        },
        testB: {
            init: 'something'
        },
        testC: {
            // Value will be erased on first loading
            value: 'notok'
        }
    });

    var unit = new unittest();

    // First init
    strictEqual(unit.get('testA'), 'ok', 'Test init1');
    strictEqual(unit.get('testB'), 'something', 'Test init2');
    strictEqual(unit.get('testC'), null, 'Test init3');

    // Change init
    unit.set('testA', 'another');
    unit.set('testB', 'stuff');
    unit.set('testC', 'great');

    strictEqual(unit.get('testA'), 'another', 'Test change init1');
    strictEqual(unit.get('testB'), 'stuff', 'Test change init2');
    strictEqual(unit.get('testC'), 'great', 'Test change init3');

    // Rollback init
    unit.init();

    // Second init
    strictEqual(unit.get('testA'), 'ok', 'Test rollback init1');
    strictEqual(unit.get('testB'), 'something', 'Test rollback init2');
    strictEqual(unit.get('testC'), null, 'Test rollback init3');
});

// Test jsons function
test('a.model.json', function() {
    var unittest = a.model('unittest-json', {
        testA: {
            init: 'something'
        },
        testB: {
            init: 'great'
        }
    });

    var unit = new unittest();
    unit.set('testA', 'another');
    var json = unit.toJSON();

    strictEqual(json, '{"testA":"another","testB":"great"}', 'Test JSON');

    var second = new unittest();
    second.fromJSON(json);

    var alternative = second.toJSON();

    strictEqual(alternative, '{"testA":"another","testB":"great"}', 'Test second');
});

// Test Object output
test('a.model.object', function() {
    var unittest = a.model('unittest-object', {
        testA: {
            init: 'something'
        },
        testB: {
            init: 'great'
        }
    });

    var unit = new unittest();
    unit.set('testA', 'another');
    var obj1 = unit.toObject();

    strictEqual(obj1.testA, 'another', 'Test first Object');
    strictEqual(obj1.testB, 'great', 'Test first Object');

    var second = new unittest();
    second.fromObject(obj1);

    var obj2 = second.toObject();

    strictEqual(obj2.testA, 'another', 'Test second Object');
    strictEqual(obj2.testB, 'great', 'Test second Object');
});

// Test snapshot function
test('a.model.snapshot', function() {
    var unittest = a.model('unittest-snapshot', {
        snap: {
            needed: true,
            init: 'ok'
        },
        nosnap: {
            init: 'notok'
        },
        so: {
            init: 'something'
        }
    });

    var unit = new unittest();
    // Taking snapshot
    unit.takeSnapshot();

    var firstSimpleSnapshot  = a.parser.json.stringify(
                    unit.differenceSnapshot(true)
        ),
        firstComplexSnapshot = a.parser.json.stringify(
                    unit.differenceSnapshot(false)
        );

    strictEqual(firstSimpleSnapshot, '{"snap":"ok"}');
    strictEqual(firstComplexSnapshot, '{"snap":{"value":"ok","old":"ok"}}')
});

// Test model manager
test('a.modelManager', function() {
    var model = a.model('modelmanagertest', {}, null);

    var instance1 = new model(),
        instance2 = new model();

    var storedInstance1 = a.modelManager.get(instance1.uid),
        storedInstance2 = a.modelManager.get(instance2.uid);

    strictEqual(storedInstance1.uid, instance1.uid);
    strictEqual(storedInstance2.uid, instance2.uid);

    var list = a.modelManager.getByName('modelmanagertest');

    // We test the list element before removing everything inside
    strictEqual(list.length, 2);
    if(list[0].uid == instance1.uid) {
        strictEqual(list[0].uid, instance1.uid);
        strictEqual(list[1].uid, instance2.uid);
    } else {
        strictEqual(list[1].uid, instance1.uid);
        strictEqual(list[0].uid, instance2.uid);
    }

    a.modelManager.remove(storedInstance1.uid);
    strictEqual(a.modelManager.get(instance1.uid), null);
    strictEqual(a.modelManager.get(instance2.uid).uid, instance2.uid);

    a.modelManager.remove(storedInstance2.uid);
});

// Unit test multiple model management
asyncTest('a.model.model-multiple', function() {
    expect(4);

    var unittest = a.model('unittest-multiple', {
        id: {
            init: 0,
            event: 'yatta'
        }
    });

    var unittest1 = new unittest(),
        unittest2 = new unittest();

    unittest1.bind('yatta', function(data) {
        strictEqual(data.value, 5, 'Testing data update 1');
        strictEqual(unittest1.get('id'), 5, 'Testing model update 1');
    });
    unittest2.bind('yatta', function(data) {
        strictEqual(data.value, 6, 'Testing data update 2');
        strictEqual(unittest2.get('id'), 6, 'Testing model update 2');
        start();
    });

    unittest1.set('id', 5);
    unittest2.set('id', 6);
});

// Test modelManager searchInstance function
test('a.model.searchInstance', function() {
    var unittest = a.model('unittest-searchInstance', {
        id: {
            check: 'number'
        },
        name: {
            init: 'piou'
        },
        val: {
            init: 5
        }
    });

    var test1 = new unittest(),
        test2 = new unittest();

    test1.set('id', 3);
    test1.set('name', 'ok');

    test2.set('id', 20);
    test2.set('val', 12);
    test2.set('name', 'something');

    var getTest1 = a.model({
            model: 'unittest-searchInstance',
            name: 'ok'
        }),
        getTest2 = a.model({
            model: 'unittest-searchInstance',
            name: 'something',
            val: 12
        });

    strictEqual(getTest1.get('id'), 3);
    strictEqual(getTest2.get('id'), 20);
});

test('a.model.validates', function() {
    ok(1==1);
});

test('a.model.requests', function() {
    ok(1==1);
});<|endoftext|>