derby
Version:
MVC framework making it easy to write realtime, collaborative applications that run in both Node.js and browsers.
839 lines (838 loc) • 35.6 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScopedModelExpression = exports.ViewParentExpression = exports.SequenceExpression = exports.OperatorExpression = exports.NewExpression = exports.FnExpression = exports.ObjectExpression = exports.ArrayExpression = exports.DeferRenderExpression = exports.BracketsExpression = exports.AttributePathExpression = exports.AliasPathExpression = exports.RelativePathExpression = exports.PathExpression = exports.LiteralExpression = exports.Expression = exports.ExpressionMeta = exports.renderObject = exports.renderArray = exports.renderTemplate = exports.renderValue = exports.pathSegments = exports.templateTruthy = exports.lookup = void 0;
var serializeObject = require("serialize-object");
var operatorFns = require("./operatorFns");
var templates_1 = require("./templates");
var util_1 = require("./util");
function lookup(segments, value) {
if (!segments)
return value;
for (var i = 0, len = segments.length; i < len; i++) {
if (value == null)
return value;
value = value[segments[i]];
}
return value;
}
exports.lookup = lookup;
// Unlike JS, `[]` is falsey. Otherwise, truthiness is the same as JS
function templateTruthy(value) {
return (Array.isArray(value)) ? value.length > 0 : !!value;
}
exports.templateTruthy = templateTruthy;
function pathSegments(segments) {
var result = [];
for (var i = 0; i < segments.length; i++) {
var segment = segments[i];
result[i] = (typeof segment === 'object') ? segment.item : segment;
}
return result;
}
exports.pathSegments = pathSegments;
function renderValue(value, context) {
return (typeof value !== 'object') ? value :
(value instanceof templates_1.Template) ? renderTemplate(value, context) :
(Array.isArray(value)) ? renderArray(value, context) :
renderObject(value, context);
}
exports.renderValue = renderValue;
function renderTemplate(template, context) {
var i = 1000;
var value = template;
while (value instanceof templates_1.Template) {
if (--i < 0)
throw new Error('Maximum template render passes exceeded');
value = value.get(context, true);
}
return value;
}
exports.renderTemplate = renderTemplate;
function renderArray(array, context) {
for (var i = 0; i < array.length; i++) {
if (hasTemplateProperty(array[i])) {
return renderArrayProperties(array, context);
}
}
return array;
}
exports.renderArray = renderArray;
function renderObject(object, context) {
return (hasTemplateProperty(object)) ?
renderObjectProperties(object, context) : object;
}
exports.renderObject = renderObject;
function hasTemplateProperty(object) {
if (!object)
return false;
if (object.constructor !== Object)
return false;
return Object.values(object).some(function (value) { return value instanceof templates_1.Template; });
}
function renderArrayProperties(array, context) {
var out = new Array(array.length);
for (var i = 0; i < array.length; i++) {
out[i] = renderValue(array[i], context);
}
return out;
}
function renderObjectProperties(object, context) {
var out = {};
for (var key in object) {
(0, util_1.checkKeyIsSafe)(key);
out[key] = renderValue(object[key], context);
}
return out;
}
var ExpressionMeta = /** @class */ (function () {
function ExpressionMeta(source, blockType, isEnd, as, keyAs, unescaped, bindType, valueType) {
this.module = 'expressions';
this.type = 'ExpressionMeta';
this.source = source;
this.blockType = blockType;
this.isEnd = isEnd;
this.as = as;
this.keyAs = keyAs;
this.unescaped = unescaped;
this.bindType = bindType;
this.valueType = valueType;
}
ExpressionMeta.prototype.serialize = function () {
return serializeObject.instance(this, this.source, this.blockType, this.isEnd, this.as, this.keyAs, this.unescaped, this.bindType, this.valueType);
};
return ExpressionMeta;
}());
exports.ExpressionMeta = ExpressionMeta;
var Expression = /** @class */ (function () {
function Expression(meta) {
this.module = 'expressions';
this.type = 'Expression';
this.meta = meta;
}
Expression.prototype.serialize = function () {
return serializeObject.instance(this, this.meta);
};
Expression.prototype.toString = function () {
return this.meta && this.meta.source;
};
Expression.prototype.truthy = function (context) {
var blockType = this.meta.blockType;
if (blockType === 'else')
return true;
var value = this.get(context, true);
var truthy = templateTruthy(value);
return (blockType === 'unless') ? !truthy : truthy;
};
Expression.prototype.get = function (_context, _flag) { return undefined; };
// Return the expression's segment list with context objects
Expression.prototype.resolve = function (_context) { return undefined; };
// Return a list of segment lists or null
Expression.prototype.dependencies = function (_context, _options) { return undefined; };
// Return the pathSegments that the expression currently resolves to or null
Expression.prototype.pathSegments = function (context) {
var segments = this.resolve(context);
return segments && pathSegments(segments);
};
Expression.prototype.set = function (context, value) {
var segments = this.pathSegments(context);
if (!segments)
throw new Error('Expression does not support setting');
context.controller.model._set(segments, value);
};
Expression.prototype._resolvePatch = function (context, segments) {
return (context && context.expression === this && context.item != null) ?
segments.concat(context) : segments;
};
Expression.prototype.isUnbound = function (context) {
// If the template being rendered has an explicit bindType keyword, such as:
// {{unbound #item.text}}
var bindType = this.meta && this.meta.bindType;
if (bindType === 'unbound')
return true;
if (bindType === 'bound')
return false;
// Otherwise, inherit from the context
return context.unbound;
};
Expression.prototype._lookupAndContextifyValue = function (value, context) {
if (this.segments && this.segments.length) {
// If expression has segments, e.g. `bar.baz` in `#foo.bar.baz`, then
// render the base value (e.g. `#foo`) if it's a template and look up the
// value at the indicated path.
value = renderTemplate(value, context);
value = lookup(this.segments, value);
}
if (value instanceof templates_1.Template && !(value instanceof templates_1.ContextClosure)) {
// If we're not immediately rendering the template, then create a ContextClosure
// so that the value renders with the correct context later.
value = new templates_1.ContextClosure(value, context);
}
return value;
};
return Expression;
}());
exports.Expression = Expression;
var LiteralExpression = /** @class */ (function (_super) {
__extends(LiteralExpression, _super);
function LiteralExpression(value, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'LiteralExpression';
_this.value = value;
return _this;
}
LiteralExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.value, this.meta);
};
LiteralExpression.prototype.get = function () {
return this.value;
};
return LiteralExpression;
}(Expression));
exports.LiteralExpression = LiteralExpression;
var PathExpression = /** @class */ (function (_super) {
__extends(PathExpression, _super);
function PathExpression(segments, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'PathExpression';
_this.segments = segments;
return _this;
}
PathExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.segments, this.meta);
};
PathExpression.prototype.get = function (context) {
// See View::dependencies. This is needed in order to handle the case of
// getting dependencies within a component template, in which case we cannot
// access model data separate from rendering.
if (!context.controller)
return;
return lookup(this.segments, context.controller.model.data);
};
PathExpression.prototype.resolve = function (context) {
// See View::dependencies. This is needed in order to handle the case of
// getting dependencies within a component template, in which case we cannot
// access model data separate from rendering.
if (!context.controller)
return;
var component = context.controller;
var segments = (0, util_1.concat)(component._scope, this.segments);
return this._resolvePatch(context, segments);
};
PathExpression.prototype.dependencies = function (context, options) {
// See View::dependencies. This is needed in order to handle the case of
// getting dependencies within a component template, in which case we cannot
// access model data separate from rendering.
if (!context.controller)
return;
var value = lookup(this.segments, context.controller.model.data);
var dependencies = getDependencies(value, context, options);
return appendDependency(dependencies, this, context);
};
return PathExpression;
}(Expression));
exports.PathExpression = PathExpression;
var RelativePathExpression = /** @class */ (function (_super) {
__extends(RelativePathExpression, _super);
function RelativePathExpression(segments, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'RelativePathExpression';
_this.segments = segments;
_this.meta = meta;
return _this;
}
RelativePathExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.segments, this.meta);
};
RelativePathExpression.prototype.get = function (context) {
var relativeContext = context.forRelative(this);
var value = relativeContext.get();
return this._lookupAndContextifyValue(value, relativeContext);
};
RelativePathExpression.prototype.resolve = function (context) {
var relativeContext = context.forRelative(this);
var base = (relativeContext.expression) ?
relativeContext.expression.resolve(relativeContext) :
[];
if (!base)
return;
var segments = base.concat(this.segments);
return this._resolvePatch(context, segments);
};
RelativePathExpression.prototype.dependencies = function (context, options) {
// Return inner dependencies from our ancestor
// (e.g., {{ with foo[bar] }} ... {{ this.x }} has 'bar' as a dependency.)
var relativeContext = context.forRelative(this);
var dependencies = relativeContext.expression &&
relativeContext.expression.dependencies(relativeContext, options);
return swapLastDependency(dependencies, this, context);
};
return RelativePathExpression;
}(Expression));
exports.RelativePathExpression = RelativePathExpression;
var AliasPathExpression = /** @class */ (function (_super) {
__extends(AliasPathExpression, _super);
function AliasPathExpression(alias, segments, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'AliasPathExpression';
_this.alias = alias;
_this.segments = segments;
_this.meta = meta;
return _this;
}
AliasPathExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.alias, this.segments, this.meta);
};
AliasPathExpression.prototype.get = function (context) {
var aliasContext = context.forAlias(this.alias);
if (!aliasContext)
return;
if (aliasContext.keyAlias === this.alias) {
return aliasContext.item;
}
var value = aliasContext.get();
return this._lookupAndContextifyValue(value, aliasContext);
};
AliasPathExpression.prototype.resolve = function (context) {
var aliasContext = context.forAlias(this.alias);
if (!aliasContext)
return;
if (aliasContext.keyAlias === this.alias)
return;
var base = aliasContext.expression.resolve(aliasContext);
if (!base)
return;
var segments = base.concat(this.segments);
return this._resolvePatch(context, segments);
};
AliasPathExpression.prototype.dependencies = function (context, options) {
var aliasContext = context.forAlias(this.alias);
if (!aliasContext)
return;
if (aliasContext.keyAlias === this.alias) {
// For keyAliases, use a dependency of the entire list, so that it will
// always update when the list itself changes. This is over-binding, but
// would otherwise be much more complex
var base = aliasContext.expression.resolve(aliasContext.parent);
if (!base)
return;
return [base];
}
var dependencies = aliasContext.expression.dependencies(aliasContext, options);
return swapLastDependency(dependencies, this, context);
};
return AliasPathExpression;
}(Expression));
exports.AliasPathExpression = AliasPathExpression;
var AttributePathExpression = /** @class */ (function (_super) {
__extends(AttributePathExpression, _super);
function AttributePathExpression(attribute, segments, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'AttributePathExpression';
_this.attribute = attribute;
_this.segments = segments;
return _this;
}
AttributePathExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.attribute, this.segments, this.meta);
};
AttributePathExpression.prototype.get = function (context) {
var attributeContext = context.forAttribute(this.attribute);
if (!attributeContext)
return;
var value = attributeContext.attributes[this.attribute];
if (value instanceof Expression) {
value = value.get(attributeContext);
}
return this._lookupAndContextifyValue(value, attributeContext);
};
AttributePathExpression.prototype.resolve = function (context) {
var attributeContext = context.forAttribute(this.attribute);
if (!attributeContext)
return;
// Attributes may be a template, an expression, or a literal value
var base;
var value = attributeContext.attributes[this.attribute];
if (value instanceof Expression || value instanceof templates_1.Template) {
base = value.resolve(attributeContext);
}
if (!base)
return;
var segments = base.concat(this.segments);
return this._resolvePatch(context, segments);
};
AttributePathExpression.prototype.dependencies = function (context, options) {
var attributeContext = context.forAttribute(this.attribute);
if (!attributeContext)
return;
// Attributes may be a template, an expression, or a literal value
var value = attributeContext.attributes[this.attribute];
var dependencies = getDependencies(value, attributeContext, options);
return swapLastDependency(dependencies, this, context);
};
return AttributePathExpression;
}(Expression));
exports.AttributePathExpression = AttributePathExpression;
var BracketsExpression = /** @class */ (function (_super) {
__extends(BracketsExpression, _super);
function BracketsExpression(before, inside, afterSegments, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'BracketsExpression';
_this.serialize = function () {
return serializeObject.instance(this, this.before, this.inside, this.afterSegments, this.meta);
};
_this.before = before;
_this.inside = inside;
_this.afterSegments = afterSegments;
_this.meta = meta;
return _this;
}
BracketsExpression.prototype.get = function (context) {
var inside = this.inside.get(context);
if (inside == null)
return;
var before = this.before.get(context);
if (!before)
return;
var base = before[inside];
return (this.afterSegments) ? lookup(this.afterSegments, base) : base;
};
BracketsExpression.prototype.resolve = function (context) {
// Get and split the current value of the expression inside the brackets
var inside = this.inside.get(context);
if (inside == null)
return;
// Concat the before, inside, and optional after segments
var base = this.before.resolve(context);
if (!base)
return;
var segments = (this.afterSegments) ?
base.concat(inside, this.afterSegments) :
base.concat(inside);
return this._resolvePatch(context, segments);
};
BracketsExpression.prototype.dependencies = function (context, options) {
var before = this.before.dependencies(context, options);
if (before)
before.pop();
var inner = this.inside.dependencies(context, options);
var dependencies = (0, util_1.concat)(before, inner);
return appendDependency(dependencies, this, context);
};
return BracketsExpression;
}(Expression));
exports.BracketsExpression = BracketsExpression;
// This Expression is used to wrap a template so that when its containing
// Expression--such as an ObjectExpression or ArrayExpression--is evaluated,
// it returns the template unrendered and wrapped in the current context.
// Separating evaluation of the containing expression from template rendering
// is used to support array attributes of views. This way, we can evaluate an
// array and iterate through it separately from rendering template content
var DeferRenderExpression = /** @class */ (function (_super) {
__extends(DeferRenderExpression, _super);
function DeferRenderExpression(template, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'DeferRenderExpression';
if (!(template instanceof templates_1.Template)) {
throw new Error('DeferRenderExpression requires a Template argument');
}
_this.template = template;
_this.meta = meta;
return _this;
}
DeferRenderExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.template, this.meta);
};
DeferRenderExpression.prototype.get = function (context) {
return new templates_1.ContextClosure(this.template, context);
};
return DeferRenderExpression;
}(Expression));
exports.DeferRenderExpression = DeferRenderExpression;
var ArrayExpression = /** @class */ (function (_super) {
__extends(ArrayExpression, _super);
function ArrayExpression(items, afterSegments, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'ArrayExpression';
_this.items = items;
_this.afterSegments = afterSegments;
_this.meta = meta;
return _this;
}
ArrayExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.items, this.afterSegments, this.meta);
};
ArrayExpression.prototype.get = function (context) {
var items = new Array(this.items.length);
for (var i = 0; i < this.items.length; i++) {
var value = this.items[i].get(context);
items[i] = value;
}
return (this.afterSegments) ? lookup(this.afterSegments, items) : items;
};
ArrayExpression.prototype.dependencies = function (context, options) {
if (!this.items)
return;
var dependencies;
for (var i = 0; i < this.items.length; i++) {
var itemDependencies = this.items[i].dependencies(context, options);
dependencies = (0, util_1.concat)(dependencies, itemDependencies);
}
return dependencies;
};
return ArrayExpression;
}(Expression));
exports.ArrayExpression = ArrayExpression;
var ObjectExpression = /** @class */ (function (_super) {
__extends(ObjectExpression, _super);
function ObjectExpression(properties, afterSegments, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'ObjectExpression';
_this.properties = properties;
_this.afterSegments = afterSegments;
return _this;
}
ObjectExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.properties, this.afterSegments, this.meta);
};
ObjectExpression.prototype.get = function (context) {
var object = {};
for (var key in this.properties) {
(0, util_1.checkKeyIsSafe)(key);
var value = this.properties[key].get(context);
object[key] = value;
}
return (this.afterSegments) ? lookup(this.afterSegments, object) : object;
};
ObjectExpression.prototype.dependencies = function (context, options) {
if (!this.properties)
return;
var dependencies;
for (var key in this.properties) {
var propertyDependencies = this.properties[key].dependencies(context, options);
dependencies = (0, util_1.concat)(dependencies, propertyDependencies);
}
return dependencies;
};
return ObjectExpression;
}(Expression));
exports.ObjectExpression = ObjectExpression;
var FnExpression = /** @class */ (function (_super) {
__extends(FnExpression, _super);
function FnExpression(segments, args, afterSegments, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'FnExpression';
_this.segments = segments;
_this.args = args;
_this.afterSegments = afterSegments;
_this.meta = meta;
var parentSegments = segments && segments.slice();
_this.lastSegment = parentSegments && parentSegments.pop();
_this.parentSegments = (parentSegments && parentSegments.length) ? parentSegments : null;
return _this;
}
FnExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.segments, this.args, this.afterSegments, this.meta);
};
FnExpression.prototype.get = function (context) {
var value = this.apply(context);
// Lookup property underneath computed value if needed
return (this.afterSegments) ? lookup(this.afterSegments, value) : value;
};
FnExpression.prototype.apply = function (context, extraInputs) {
// See View::dependencies. This is needed in order to handle the case of
// getting dependencies within a component template, in which case we cannot
// access model data separate from rendering.
if (!context.controller)
return;
var parent = this._lookupParent(context);
var fn = parent[this.lastSegment];
var getFn = fn.get || fn;
var out = this._applyFn(getFn, context, extraInputs, parent);
return out;
};
FnExpression.prototype._lookupParent = function (context) {
// Lookup function on current controller
var controller = context.controller;
var segments = this.parentSegments;
var parent = (segments) ? lookup(segments, controller) : controller;
if (parent && parent[this.lastSegment])
return parent;
// Otherwise lookup function on page
var page = controller.page;
if (controller !== page) {
parent = (segments) ? lookup(segments, page) : page;
if (parent && parent[this.lastSegment])
return parent;
}
// Otherwise lookup function on global
parent = (segments) ? lookup(segments, global) : global;
if (parent && parent[this.lastSegment])
return parent;
// Throw if not found
throw new Error('Function not found for: ' + this.segments.join('.'));
};
FnExpression.prototype._getInputs = function (context) {
var inputs = [];
for (var i = 0, len = this.args.length; i < len; i++) {
var value = this.args[i].get(context);
inputs.push(renderValue(value, context));
}
return inputs;
};
FnExpression.prototype._applyFn = function (fn, context, extraInputs, thisArg) {
// Apply if there are no path inputs
if (!this.args) {
return (extraInputs) ?
fn.apply(thisArg, extraInputs) :
fn.call(thisArg);
}
// Otherwise, get the current value for path inputs and apply
var inputs = this._getInputs(context);
if (extraInputs) {
for (var i = 0, len = extraInputs.length; i < len; i++) {
inputs.push(extraInputs[i]);
}
}
return fn.apply(thisArg, inputs);
};
FnExpression.prototype.dependencies = function (context, options) {
var dependencies = [];
if (!this.args)
return dependencies;
for (var i = 0, len = this.args.length; i < len; i++) {
var argDependencies = this.args[i].dependencies(context, options);
if (!argDependencies || argDependencies.length < 1)
continue;
var end = argDependencies.length - 1;
for (var j = 0; j < end; j++) {
dependencies.push(argDependencies[j]);
}
var last = argDependencies[end];
if (last[last.length - 1] !== '*') {
last = last.concat('*');
}
dependencies.push(last);
}
return dependencies;
};
FnExpression.prototype.set = function (context, value) {
var controller = context.controller;
var fn, parent;
while (controller) {
parent = (this.parentSegments) ?
lookup(this.parentSegments, controller) :
controller;
fn = parent && parent[this.lastSegment];
if (fn) {
break;
}
// controller could be a Component or a PageBase in practice,
// using `as Component` to avoid a runtime instanceof check.
controller = controller.parent;
}
var setFn = fn && fn.set;
if (!setFn)
throw new Error('No setter function for: ' + this.segments.join('.'));
var inputs = this._getInputs(context);
inputs.unshift(value);
var out = setFn.apply(parent, inputs);
for (var i in out) {
this.args[i].set(context, out[i]);
}
};
return FnExpression;
}(Expression));
exports.FnExpression = FnExpression;
var NewExpression = /** @class */ (function (_super) {
__extends(NewExpression, _super);
function NewExpression(segments, args, afterSegments, meta) {
var _this = _super.call(this, segments, args, afterSegments, meta) || this;
_this.type = 'NewExpression';
return _this;
}
NewExpression.prototype._applyFn = function (Fn, context) {
// Apply if there are no path inputs
if (!this.args)
return new Fn();
// Otherwise, get the current value for path inputs and apply
var inputs = this._getInputs(context);
inputs.unshift(null);
// eslint-disable-next-line prefer-spread
return new (Fn.bind.apply(Fn, inputs))();
};
return NewExpression;
}(FnExpression));
exports.NewExpression = NewExpression;
var OperatorExpression = /** @class */ (function (_super) {
__extends(OperatorExpression, _super);
function OperatorExpression(name, args, afterSegments, meta) {
var _this = _super.call(this, null, args, afterSegments, meta) || this;
_this.type = 'OperatorExpression';
_this.name = name;
_this.getFn = operatorFns.get[name];
_this.setFn = operatorFns.set[name];
return _this;
}
OperatorExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.name, this.args, this.afterSegments, this.meta);
};
OperatorExpression.prototype.apply = function (context) {
var inputs = this._getInputs(context);
return this.getFn.apply(null, inputs);
};
OperatorExpression.prototype.set = function (context, value) {
var inputs = this._getInputs(context);
inputs.unshift(value);
var out = this.setFn.apply(null, inputs);
for (var i in out) {
this.args[i].set(context, out[i]);
}
};
return OperatorExpression;
}(FnExpression));
exports.OperatorExpression = OperatorExpression;
var SequenceExpression = /** @class */ (function (_super) {
__extends(SequenceExpression, _super);
function SequenceExpression(args, afterSegments, meta) {
var _this = _super.call(this, ',', args, afterSegments, meta) || this;
_this.type = 'SequenceExpression';
_this.getFn = operatorFns.get[','];
_this.args = args;
_this.afterSegments = afterSegments;
_this.meta = meta;
return _this;
}
SequenceExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.args, this.afterSegments, this.meta);
};
SequenceExpression.prototype.resolve = function (context) {
var last = this.args[this.args.length - 1];
return last.resolve(context);
};
SequenceExpression.prototype.dependencies = function (context, options) {
var dependencies = [];
for (var i = 0, len = this.args.length; i < len; i++) {
var argDependencies = this.args[i].dependencies(context, options);
for (var j = 0, jLen = argDependencies.length; j < jLen; j++) {
dependencies.push(argDependencies[j]);
}
}
return dependencies;
};
return SequenceExpression;
}(OperatorExpression));
exports.SequenceExpression = SequenceExpression;
// For each method that takes a context argument, get the nearest parent view
// context, then delegate methods to the inner expression
var ViewParentExpression = /** @class */ (function (_super) {
__extends(ViewParentExpression, _super);
function ViewParentExpression(expression, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'ViewParentExpression';
_this.expression = expression;
return _this;
}
ViewParentExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.expression, this.meta);
};
ViewParentExpression.prototype.get = function (context) {
var parentContext = context.forViewParent();
return this.expression.get(parentContext);
};
ViewParentExpression.prototype.resolve = function (context) {
var parentContext = context.forViewParent();
return this.expression.resolve(parentContext);
};
ViewParentExpression.prototype.dependencies = function (context, options) {
var parentContext = context.forViewParent();
return this.expression.dependencies(parentContext, options);
};
ViewParentExpression.prototype.pathSegments = function (context) {
var parentContext = context.forViewParent();
return this.expression.pathSegments(parentContext);
};
ViewParentExpression.prototype.set = function (context, value) {
var parentContext = context.forViewParent();
return this.expression.set(parentContext, value);
};
return ViewParentExpression;
}(Expression));
exports.ViewParentExpression = ViewParentExpression;
var ScopedModelExpression = /** @class */ (function (_super) {
__extends(ScopedModelExpression, _super);
function ScopedModelExpression(expression, meta) {
var _this = _super.call(this, meta) || this;
_this.type = 'ScopedModelExpression';
_this.expression = expression;
_this.meta = meta;
return _this;
}
ScopedModelExpression.prototype.serialize = function () {
return serializeObject.instance(this, this.expression, this.meta);
};
// Return a scoped model instead of the value
ScopedModelExpression.prototype.get = function (context) {
var segments = this.pathSegments(context);
if (!segments)
return;
return context.controller.model.scope(segments.join('.'));
};
// Delegate other methods to the inner expression
ScopedModelExpression.prototype.resolve = function (context) {
return this.expression.resolve(context);
};
ScopedModelExpression.prototype.dependencies = function (context, options) {
return this.expression.dependencies(context, options);
};
ScopedModelExpression.prototype.pathSegments = function (context) {
return this.expression.pathSegments(context);
};
ScopedModelExpression.prototype.set = function (context, value) {
return this.expression.set(context, value);
};
return ScopedModelExpression;
}(Expression));
exports.ScopedModelExpression = ScopedModelExpression;
function getDependencies(value, context, options) {
if (value instanceof Expression || value instanceof templates_1.Template) {
return value.dependencies(context, options);
}
}
function appendDependency(dependencies, expression, context) {
var segments = expression.resolve(context);
if (!segments)
return dependencies;
if (dependencies) {
dependencies.push(segments);
return dependencies;
}
return [segments];
}
function swapLastDependency(dependencies, expression, context) {
if (!expression.segments.length) {
return dependencies;
}
var segments = expression.resolve(context);
if (!segments)
return dependencies;
if (dependencies) {
dependencies.pop();
dependencies.push(segments);
return dependencies;
}
return [segments];
}