all files / montage/core/serialization/ alias.js

100% Statements 13/13
100% Branches 2/2
100% Functions 5/5
100% Lines 13/13
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113                                                                                                11×   11×                                                                                                      
/*global require, exports */
 
var Montage = require("../core").Montage;
 
/**
 * A component can expose internal components to external usage using aliases.
 * For example, a [Repetition]{@link Repetition} exposes
 * `@repetition:iteration` and a table might expose the current cell as
 * `@table:cell`, aliasing the internal `@cells:iteration`.
 *
 * An alias declaration in a component sheet (serialization) looks like:
 *
 *     {
 *         ":cell": {
 *             "alias": "repetition:iteration"
 *         }
 *     }
 *
 * An `Alias` is a representation of one of these declarations.
 * An alias can only point to another template property and can be optionally
 * followed by a path.
 *
 * @class Alias
 * @classdesc Models a label alias in a component sheet (serialization).
 * @extends Montage
 */
exports.Alias = Montage.specialize({ /** @lends Alias# */
 
    _value: {
        value: null
    },
 
    _aliasRegExp: {
        // $1: component name
        // $2: property name
        // alias = @$1:$2
        value: /@([_a-zA-Z$][0-9_a-zA-Z$]*):([_a-zA-Z$][0-9_a-zA-Z$]*)$/
    },
 
    /**
     * The alias string as found in the serialization.
     *
     * @name Alias#value
     * @type {string}
     */
    value: {
        get: function () {
            return this._value;
        },
 
        set: function (value) {
            var split = this._aliasRegExp.exec(value);
 
            if (!split) {
                throw new Error("Invalid alias syntax: " + value);
            }
 
            this._value = value;
 
            this._componentLabel = split[1];
            this._propertyName = split[2];
        }
    },
 
    _componentLabel: {
        value: null
    },
 
    /**
     * The component name part of the alias, this is the component where the
     * template property is located.
     * Derived from the alias.
     *
     * @name Alias#componentName
     * @type {string}
     * @readonly
     */
    componentLabel: {
        get: function () {
            return this._componentLabel;
        }
    },
 
    _propertyName: {
        value: null
    },
 
    /**
     * The property name of the template property. It's up to the component
     * template to define this property.
     * Derived from the alias.
     *
     * @name Alias#propertyName
     * @type {string}
     * @readonly
     */
    propertyName: {
        get: function () {
            return this._propertyName;
        }
    },
 
    init: {
        value: function (value) {
            this.value = value;
 
            return this;
        }
    }
 
});