Show: Inherited Protected Private Deprecated

# File `src/ui/react/src/oop/attribute.js`

                                (function() {
                                    'use strict';

                                    /**
                                     * Attribute implementation.
                                     *
                                     * @class Attribute
                                     * @constructor
                                    */
                                    function Attribute(config) {
                                        this.__config__ = config || {};
                                        this.__ATTRS__ = {};
                                    }

                                    Attribute.prototype = {
                                        constructor: Attribute,

                                        /**
                                         * Retrieves the value of an attribute.
                                         *
                                         * @method get
                                         * @param {String} attr The attribute which value should be retrieved.
                                         * @return {Any} The value of the attribute.
                                         */
                                        get: function(attr) {
                                            var currentAttr = this.constructor.ATTRS[attr];

                                            if (!currentAttr) {
                                                return;
                                            }

                                            if (!this._isInitialized(attr)) {
                                                this._init(attr);
                                            }

                                            var curValue = this.__ATTRS__[attr];

                                            if (currentAttr.getter) {
                                                curValue = this._callStringOrFunction(currentAttr.getter, curValue);
                                            }

                                            return curValue;
                                        },

                                        /**
                                         * Sets the value of an attribute.
                                         *
                                         * @method set
                                         * @param {String} attr The attribute which value should be set.
                                         * @param {Any} value The value which should be set to the attribute.
                                         */
                                        set: function(attr, value) {
                                            var currentAttr = this.constructor.ATTRS[attr];

                                            if (!currentAttr) {
                                                return;
                                            }

                                            if (!this._isInitialized(attr)) {
                                                this._init(attr);
                                            }

                                            if (currentAttr.readOnly) {
                                                return;
                                            }

                                            if (currentAttr.writeOnce && this._isInitialized(attr)) {
                                                return;
                                            }

                                            if (currentAttr.validator && !this._callStringOrFunction(currentAttr.validator, value)) {
                                                return;
                                            }

                                            if (currentAttr.setter) {
                                                value = this._callStringOrFunction(currentAttr.setter, value);
                                            }

                                            this.__ATTRS__[attr] = value;
                                        },

                                        /**
                                         * Calls the provided param as function with the supplied arguments.
                                         * If param provided as string, a corresponding function in this object will
                                         * be called. If provided param is a function, it will be directly called.
                                         *
                                         * @protected
                                         * @method _callStringOrFunction
                                         * @param  {String|Function} stringOrFunction The function which should be called
                                         * @param  {Any|Array} args The arguments which will be provided to the called function
                                         * @return {Any} The returned value from the called function
                                         */
                                        _callStringOrFunction: function(stringOrFunction, args) {
                                            var result = null;

                                            if (!AlloyEditor.Lang.isArray(args)) {
                                                args = [args];
                                            }

                                            if (AlloyEditor.Lang.isString(stringOrFunction) && AlloyEditor.Lang.isFunction(this[stringOrFunction])) {
                                                result = this[stringOrFunction].apply(this, args);
                                            } else if (AlloyEditor.Lang.isFunction(stringOrFunction)) {
                                                result = stringOrFunction.apply(this, args);
                                            }

                                            return result;
                                        },

                                        /**
                                         * Initializes an attribute. Sets its default value depending on the flags of the
                                         * attribute and the passed configuration object to the constructor.
                                         *
                                         * @protected
                                         * @method _init
                                         * @param {String} attr The name of the attribute which have to be initialized.
                                         */
                                        _init: function(attr) {
                                            var value;

                                            var currentAttr = this.constructor.ATTRS[attr];

                                            // Check if there is default value or passed one via configuration object
                                            var hasDefaultValue = Object.prototype.hasOwnProperty.call(currentAttr, 'value');
                                            var hasPassedValueViaConfig = Object.prototype.hasOwnProperty.call(this.__config__, attr);

                                            // If there is valueFn, set the value to be the result of invocation of this function
                                            if (currentAttr.valueFn) {
                                                value = this._callStringOrFunction(currentAttr.valueFn, value);

                                                this.__ATTRS__[attr] = value;
                                            }
                                            // else if the attribute has readOnly flag, set the default value from the attribute,
                                            // regardless if there is value or not
                                            else if (currentAttr.readOnly) {
                                                value = currentAttr.value;
                                            }
                                            // else if the attribute has writeOnce value, set it from the passed configuration or from the
                                            // default value, in this order. Otherwise, return miserable.
                                            else if (currentAttr.writeOnce) {
                                                if (hasPassedValueViaConfig) {
                                                    value = this.__config__[attr];
                                                } else if (hasDefaultValue) {
                                                    value = currentAttr.value;
                                                } else {
                                                    return;
                                                }
                                            }
                                            // These two cases below are easy - set the value to be from the passed config or
                                            // from the default value, in this order.
                                            else if (hasPassedValueViaConfig) {
                                                value = this.__config__[attr];
                                            } else if (hasDefaultValue) {
                                                value = currentAttr.value;
                                            }

                                            // If there is validator, and user passed config object - check the returned value.
                                            // If it is false, then set as initial value the default one.
                                            // However, if there is no default value, just return.
                                            if (currentAttr.validator && hasPassedValueViaConfig && !this._callStringOrFunction(currentAttr.validator, value)) {
                                                if (hasDefaultValue) {
                                                    value = currentAttr.value;
                                                } else {
                                                    return;
                                                }
                                            }

                                            // If there is setter and user passed config object - pass the value thought the setter.
                                            // The value might be one from defaultFn, default value or provided from the config.
                                            if (currentAttr.setter && hasPassedValueViaConfig) {
                                                value = this._callStringOrFunction(currentAttr.setter, value);
                                            }

                                            // Finally, set the value as initial value to the storage with values.
                                            this.__ATTRS__[attr] = value;
                                        },

                                        /**
                                         * Checks if an attribute is initialized. An attribute is considered as initialized
                                         * when there is an own property with this name in the local collection of attribute values
                                         * for the current instance.
                                         *
                                         * @protected
                                         * @method _isInitialized
                                         * @param {String} attr The attribute which should be checked if it is initialized.
                                         * @return {Boolean} Returns true if the attribute has been initialized, false otherwise.
                                         */
                                        _isInitialized: function(attr) {
                                            return Object.prototype.hasOwnProperty.call(this.__ATTRS__, attr);
                                        }
                                    };

                                    AlloyEditor.Attribute = Attribute;
                                }());