Пример #1
0
        public override async Task WriteAsync(ScriptScopeContext scope, PageBlockFragment block, CancellationToken token)
        {
            var result = await block.Argument.GetJsExpressionAndEvaluateAsync(scope,
                                                                              ifNone : () => throw new NotSupportedException("'with' block does not have a valid expression"));

            if (result != null)
            {
                var resultAsMap = result.ToObjectDictionary();

                var withScope = scope.ScopeWithParams(resultAsMap);

                await WriteBodyAsync(withScope, block, token);
            }
            else
            {
                await WriteElseAsync(scope, block.ElseBlocks, token);
            }
        }
Пример #2
0
        public override async Task WriteAsync(ScriptScopeContext scope, PageBlockFragment block, CancellationToken token)
        {
            var         htmlAttrs          = block.Argument.GetJsExpressionAndEvaluate(scope) as Dictionary <string, object>;
            var         hasEach            = false;
            IEnumerable each               = null;
            var         binding            = "it";
            var         hasExplicitBinding = false;

            JsToken where = null;

            if (htmlAttrs != null)
            {
                if (htmlAttrs.TryGetValue("if", out var oIf))
                {
                    if (Script.DefaultScripts.isFalsy(oIf))
                    {
                        return;
                    }
                    htmlAttrs.Remove("if");
                }

                if (htmlAttrs.TryGetValue(nameof(where), out var oWhere))
                {
                    if (!(oWhere is string whereExpr))
                    {
                        throw new NotSupportedException($"'where' should be a string expression but instead found '{oWhere.GetType().Name}'");
                    }

                    where = whereExpr.GetCachedJsExpression(scope);
                    htmlAttrs.Remove(nameof(where));
                }

                if (htmlAttrs.TryGetValue(nameof(each), out var oEach))
                {
                    hasEach = true;
                    htmlAttrs.Remove(nameof(each));
                }
                each = oEach as IEnumerable;

                if (htmlAttrs.TryGetValue("it", out var oIt) && oIt is string it)
                {
                    binding            = it;
                    hasExplicitBinding = true;
                    htmlAttrs.Remove("it");
                }

                if (htmlAttrs.TryGetValue("class", out var oClass))
                {
                    var cls = scope.Context.HtmlMethods.htmlClassList(oClass);
                    if (string.IsNullOrEmpty(cls))
                    {
                        htmlAttrs.Remove("class");
                    }
                    else
                    {
                        htmlAttrs["class"] = cls;
                    }
                }
            }

            var attrString = scope.Context.HtmlMethods.htmlAttrsList(htmlAttrs);

            if (HtmlScripts.VoidElements.Contains(Tag)) //e.g. img, input, br, etc
            {
                await scope.OutputStream.WriteAsync($"<{Tag}{attrString}>{Suffix}", token);
            }
            else
            {
                if (hasEach)
                {
                    var hasElements = each != null && each.GetEnumerator().MoveNext();
                    if (hasElements)
                    {
                        await scope.OutputStream.WriteAsync($"<{Tag}{attrString}>{Suffix}", token);

                        var index      = 0;
                        var whereIndex = 0;
                        foreach (var element in each)
                        {
                            // Add all properties into scope if called without explicit in argument
                            var scopeArgs = !hasExplicitBinding && CanExportScopeArgs(element)
                                ? element.ToObjectDictionary()
                                : new Dictionary <string, object>();

                            scopeArgs[binding]       = element;
                            scopeArgs[nameof(index)] = AssertWithinMaxQuota(whereIndex++);
                            var itemScope = scope.ScopeWithParams(scopeArgs);

                            if (where != null)
                            {
                                var result = where.EvaluateToBool(itemScope);
                                if (!result)
                                {
                                    continue;
                                }
                            }

                            itemScope.ScopedParams[nameof(index)] = AssertWithinMaxQuota(index++);

                            await WriteBodyAsync(itemScope, block, token);
                        }

                        await scope.OutputStream.WriteAsync($"</{Tag}>{Suffix}", token);
                    }
                    else
                    {
                        await WriteElseAsync(scope, block.ElseBlocks, token);
                    }
                }
                else
                {
                    await scope.OutputStream.WriteAsync($"<{Tag}{attrString}>{Suffix}", token);
                    await WriteBodyAsync(scope, block, token);

                    await scope.OutputStream.WriteAsync($"</{Tag}>{Suffix}", token);
                }
            }
        }
 public static async Task WritePageAsync(this ScriptScopeContext scope, SharpPage page, SharpCodePage codePage, Dictionary <string, object> pageParams, CancellationToken token = default(CancellationToken))
 {
     await scope.PageResult.WritePageAsync(page, codePage, scope.ScopeWithParams(pageParams), token);
 }
Пример #4
0
        public override async Task WriteAsync(ScriptScopeContext scope, PageBlockFragment block, CancellationToken token)
        {
            if (block.Argument.IsNullOrEmpty())
            {
                throw new NotSupportedException("'each' block requires the collection to iterate");
            }

            var cache = (EachArg)scope.Context.Cache.GetOrAdd(block.ArgumentString, _ => ParseArgument(scope, block));

            var collection = cache.Source.Evaluate(scope, out var syncResult, out var asyncResult)
                ? (IEnumerable)syncResult
                : (IEnumerable)(await asyncResult.ConfigAwait());

            var index = 0;

            if (collection != null)
            {
                if (cache.Where != null || cache.OrderBy != null || cache.OrderByDescending != null ||
                    cache.Skip != null || cache.Take != null)
                {
                    var filteredResults = new List <Dictionary <string, object> >();
                    foreach (var element in collection)
                    {
                        // Add all properties into scope if called without explicit in argument
                        var scopeArgs = !cache.HasExplicitBinding && CanExportScopeArgs(element)
                            ? element.ToObjectDictionary()
                            : new Dictionary <string, object>();

                        scopeArgs[cache.Binding] = element;
                        scopeArgs[nameof(index)] = AssertWithinMaxQuota(index++);
                        var itemScope = scope.ScopeWithParams(scopeArgs);

                        if (cache.Where != null)
                        {
                            var result = await cache.Where.EvaluateToBoolAsync(itemScope).ConfigAwait();

                            if (!result)
                            {
                                continue;
                            }
                        }

                        filteredResults.Add(scopeArgs);
                    }

                    IEnumerable <Dictionary <string, object> > selectedResults = filteredResults;

                    var comparer = (IComparer <object>)Comparer <object> .Default;
                    if (cache.OrderBy != null)
                    {
                        var i = 0;
                        selectedResults = selectedResults.OrderBy(scopeArgs =>
                        {
                            scopeArgs[nameof(index)] = i++;
                            return(cache.OrderBy.Evaluate(scope.ScopeWithParams(scopeArgs)));
                        }, comparer);
                    }
                    else if (cache.OrderByDescending != null)
                    {
                        var i = 0;
                        selectedResults = selectedResults.OrderByDescending(scopeArgs =>
                        {
                            scopeArgs[nameof(index)] = i++;
                            return(cache.OrderByDescending.Evaluate(scope.ScopeWithParams(scopeArgs)));
                        }, comparer);
                    }

                    if (cache.Skip != null)
                    {
                        var skip = cache.Skip.Evaluate(scope).ConvertTo <int>();
                        selectedResults = selectedResults.Skip(skip);
                    }

                    if (cache.Take != null)
                    {
                        var take = cache.Take.Evaluate(scope).ConvertTo <int>();
                        selectedResults = selectedResults.Take(take);
                    }

                    index = 0;
                    foreach (var scopeArgs in selectedResults)
                    {
                        var itemScope = scope.ScopeWithParams(scopeArgs);
                        itemScope.ScopedParams[nameof(index)] = index++;
                        await WriteBodyAsync(itemScope, block, token).ConfigAwait();
                    }
                }
                else
                {
                    foreach (var element in collection)
                    {
                        // Add all properties into scope if called without explicit in argument
                        var scopeArgs = !cache.HasExplicitBinding && CanExportScopeArgs(element)
                            ? element.ToObjectDictionary()
                            : new Dictionary <string, object>();

                        scopeArgs[cache.Binding] = element;
                        scopeArgs[nameof(index)] = AssertWithinMaxQuota(index++);
                        var itemScope = scope.ScopeWithParams(scopeArgs);

                        await WriteBodyAsync(itemScope, block, token).ConfigAwait();
                    }
                }
            }

            if (index == 0)
            {
                await WriteElseAsync(scope, block.ElseBlocks, token).ConfigAwait();
            }
        }