Ejemplo n.º 1
0
        public Task <IHtmlContent> ShapeExecuteAsync(object shape)
        {
            if (shape == null)
            {
                return(Task.FromResult <IHtmlContent>(HtmlString.Empty));
            }

            var context = new DisplayContext
            {
                DisplayAsync    = this,
                Value           = shape,
                ServiceProvider = _serviceProvider
            };

            return(_htmlDisplay.ExecuteAsync(context));
        }
Ejemplo n.º 2
0
        public Task <IHtmlContent> ShapeExecuteAsync(IShape shape)
        {
            // Check if the shape is null or empty.
            if (shape.IsNullOrEmpty())
            {
                return(Task.FromResult <IHtmlContent>(HtmlString.Empty));
            }

            // Check if the shape is pre-rendered.
            if (shape is IHtmlContent htmlContent)
            {
                return(Task.FromResult(htmlContent));
            }

            var context = new DisplayContext
            {
                DisplayHelper   = this,
                Value           = shape,
                ServiceProvider = _serviceProvider
            };

            return(_htmlDisplay.ExecuteAsync(context));
        }
        public async Task <IHtmlContent> ExecuteAsync(DisplayContext context)
        {
            var shape = context.Value as IShape;

            // non-shape arguments are returned as a no-op
            if (shape == null)
            {
                return(CoerceHtmlString(context.Value));
            }

            var shapeMetadata = shape.Metadata;

            // can't really cope with a shape that has no type information
            if (shapeMetadata == null || string.IsNullOrEmpty(shapeMetadata.Type))
            {
                return(CoerceHtmlString(context.Value));
            }

            var displayContext = new ShapeDisplayContext
            {
                Shape           = shape,
                ShapeMetadata   = shapeMetadata,
                DisplayContext  = context,
                ServiceProvider = _serviceProvider
            };

            try
            {
                var theme = await _themeManager.GetThemeAsync();

                var shapeTable = _shapeTableManager.GetShapeTable(theme?.Id);

                // Use the same prefix as the shape
                var originalHtmlFieldPrefix = context.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix;
                context.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = shapeMetadata.Prefix ?? "";

                // Evaluate global Shape Display Events
                await _shapeDisplayEvents.InvokeAsync(sde => sde.DisplayingAsync(displayContext), _logger);

                // Find base shape association using only the fundamental shape type.
                // Alternates that may already be registered do not affect the "displaying" event calls.
                ShapeBinding shapeBinding;
                if (TryGetDescriptorBinding(shapeMetadata.Type, Enumerable.Empty <string>(), shapeTable, out shapeBinding))
                {
                    await shapeBinding.ShapeDescriptor.DisplayingAsync.InvokeAsync(action => action(displayContext), _logger);

                    // copy all binding sources (all templates for this shape) in order to use them as Localization scopes
                    shapeMetadata.BindingSources = shapeBinding.ShapeDescriptor.BindingSources.Where(x => x != null).ToList();
                    if (!shapeMetadata.BindingSources.Any())
                    {
                        shapeMetadata.BindingSources.Add(shapeBinding.ShapeDescriptor.BindingSource);
                    }
                }

                // invoking ShapeMetadata displaying events
                shapeMetadata.Displaying.Invoke(action => action(displayContext), _logger);

                // use pre-fectched content if available (e.g. coming from specific cache implementation)
                if (displayContext.ChildContent != null)
                {
                    shape.Metadata.ChildContent = displayContext.ChildContent;
                }

                if (shape.Metadata.ChildContent == null)
                {
                    // There might be no shape binding for the main shape, and only for its alternates.
                    if (shapeBinding != null)
                    {
                        await shapeBinding.ShapeDescriptor.ProcessingAsync.InvokeAsync(action => action(displayContext), _logger);
                    }

                    // now find the actual binding to render, taking alternates into account
                    ShapeBinding actualBinding;
                    if (TryGetDescriptorBinding(shapeMetadata.Type, shapeMetadata.Alternates, shapeTable, out actualBinding))
                    {
                        // invoking ShapeMetadata processing events, this includes the Drivers results
                        await shapeMetadata.ProcessingAsync.InvokeAsync(processing => processing(displayContext.Shape), _logger);

                        shape.Metadata.ChildContent = await ProcessAsync(actualBinding, shape, context);
                    }
                    else
                    {
                        throw new Exception($"Shape type '{shapeMetadata.Type}' not found");
                    }
                }

                // Process wrappers
                if (shape.Metadata.Wrappers.Count > 0)
                {
                    foreach (var frameType in shape.Metadata.Wrappers)
                    {
                        ShapeBinding frameBinding;
                        if (TryGetDescriptorBinding(frameType, Enumerable.Empty <string>(), shapeTable, out frameBinding))
                        {
                            shape.Metadata.ChildContent = await ProcessAsync(frameBinding, shape, context);
                        }
                    }

                    // Clear wrappers to prevent the child content from rendering them again
                    shape.Metadata.Wrappers.Clear();
                }

                await _shapeDisplayEvents.InvokeAsync(async sde =>
                {
                    var prior = displayContext.ChildContent = displayContext.ShapeMetadata.ChildContent;
                    await sde.DisplayedAsync(displayContext);
                    // update the child content if the context variable has been reassigned
                    if (prior != displayContext.ChildContent)
                    {
                        displayContext.ShapeMetadata.ChildContent = displayContext.ChildContent;
                    }
                }, _logger);

                if (shapeBinding != null)
                {
                    await shapeBinding.ShapeDescriptor.DisplayedAsync.InvokeAsync(async action =>
                    {
                        var prior = displayContext.ChildContent = displayContext.ShapeMetadata.ChildContent;

                        await action(displayContext);

                        // update the child content if the context variable has been reassigned
                        if (prior != displayContext.ChildContent)
                        {
                            displayContext.ShapeMetadata.ChildContent = displayContext.ChildContent;
                        }
                    }, _logger);
                }

                // invoking ShapeMetadata displayed events
                shapeMetadata.Displayed.Invoke(action => action(displayContext), _logger);

                //restore original HtmlFieldPrefix
                context.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = originalHtmlFieldPrefix;
            }
            finally
            {
                await _shapeDisplayEvents.InvokeAsync(sde => sde.DisplayingFinalizedAsync(displayContext), _logger);
            }

            return(shape.Metadata.ChildContent);
        }
 static async Task <IHtmlContent> ProcessAsync(ShapeBinding shapeBinding, IShape shape, DisplayContext context)
 {
     if (shapeBinding == null || shapeBinding.BindingAsync == null)
     {
         // todo: create result from all child shapes
         return(shape.Metadata.ChildContent ?? HtmlString.Empty);
     }
     return(CoerceHtmlString(await shapeBinding.BindingAsync(context)));
 }
Ejemplo n.º 5
0
        public async Task <IHtmlContent> ExecuteAsync(DisplayContext context)
        {
            var shape = context.Value as IShape;

            // non-shape arguments are returned as a no-op
            if (shape == null)
            {
                return(CoerceHtmlString(context.Value));
            }

            var shapeMetadata = shape.Metadata;

            // can't really cope with a shape that has no type information
            if (shapeMetadata == null || string.IsNullOrEmpty(shapeMetadata.Type))
            {
                return(CoerceHtmlString(context.Value));
            }

            // Copy the current context such that the rendering can customize it if necessary
            // For instance to change the HtmlFieldPrefix
            var localContext = new DisplayContext(context);

            localContext.HtmlFieldPrefix = shapeMetadata.Prefix ?? "";

            var displayContext = new ShapeDisplayContext
            {
                Shape           = shape,
                DisplayContext  = localContext,
                ServiceProvider = _serviceProvider
            };

            try
            {
                var theme = await _themeManager.GetThemeAsync();

                var shapeTable = _shapeTableManager.GetShapeTable(theme?.Id);

                // Evaluate global Shape Display Events
                await _shapeDisplayEvents.InvokeAsync((e, displayContext) => e.DisplayingAsync(displayContext), displayContext, _logger);

                // Find base shape association using only the fundamental shape type.
                // Alternates that may already be registered do not affect the "displaying" event calls.
                var shapeDescriptor = GetShapeDescriptor(shapeMetadata.Type, shapeTable);
                if (shapeDescriptor != null)
                {
                    await shapeDescriptor.DisplayingAsync.InvokeAsync((action, displayContext) => action(displayContext), displayContext, _logger);

                    // copy all binding sources (all templates for this shape) in order to use them as Localization scopes
                    shapeMetadata.BindingSources = shapeDescriptor.BindingSources.Where(x => x != null).ToList();
                    if (!shapeMetadata.BindingSources.Any())
                    {
                        shapeMetadata.BindingSources.Add(shapeDescriptor.BindingSource);
                    }
                }

                // invoking ShapeMetadata displaying events
                shapeMetadata.Displaying.Invoke(action => action(displayContext), _logger);

                // use pre-fetched content if available (e.g. coming from specific cache implementation)
                if (displayContext.ChildContent != null)
                {
                    shape.Metadata.ChildContent = displayContext.ChildContent;
                }

                if (shape.Metadata.ChildContent == null)
                {
                    // There might be no shape binding for the main shape, and only for its alternates.
                    if (shapeDescriptor != null)
                    {
                        await shapeDescriptor.ProcessingAsync.InvokeAsync((action, displayContext) => action(displayContext), displayContext, _logger);
                    }

                    // now find the actual binding to render, taking alternates into account
                    var actualBinding = await GetShapeBindingAsync(shapeMetadata.Type, shapeMetadata.Alternates, shapeTable);

                    if (actualBinding != null)
                    {
                        await shapeMetadata.ProcessingAsync.InvokeAsync((action, displayContext) => action(displayContext.Shape), displayContext, _logger);

                        shape.Metadata.ChildContent = await ProcessAsync(actualBinding, shape, localContext);
                    }
                    else
                    {
                        throw new Exception($"Shape type '{shapeMetadata.Type}' not found");
                    }
                }

                // Process wrappers
                if (shape.Metadata.Wrappers.Count > 0)
                {
                    foreach (var frameType in shape.Metadata.Wrappers)
                    {
                        var frameBinding = await GetShapeBindingAsync(frameType, AlternatesCollection.Empty, shapeTable);

                        if (frameBinding != null)
                        {
                            shape.Metadata.ChildContent = await ProcessAsync(frameBinding, shape, localContext);
                        }
                    }

                    // Clear wrappers to prevent the child content from rendering them again
                    shape.Metadata.Wrappers.Clear();
                }

                await _shapeDisplayEvents.InvokeAsync(async (e, displayContext) =>
                {
                    var prior = displayContext.ChildContent = displayContext.Shape.Metadata.ChildContent;

                    await e.DisplayedAsync(displayContext);

                    // update the child content if the context variable has been reassigned
                    if (prior != displayContext.ChildContent)
                    {
                        displayContext.Shape.Metadata.ChildContent = displayContext.ChildContent;
                    }
                }, displayContext, _logger);

                if (shapeDescriptor != null)
                {
                    await shapeDescriptor.DisplayedAsync.InvokeAsync(async (action, displayContext) =>
                    {
                        var prior = displayContext.ChildContent = displayContext.Shape.Metadata.ChildContent;

                        await action(displayContext);

                        // update the child content if the context variable has been reassigned
                        if (prior != displayContext.ChildContent)
                        {
                            displayContext.Shape.Metadata.ChildContent = displayContext.ChildContent;
                        }
                    }, displayContext, _logger);
                }

                // invoking ShapeMetadata displayed events
                shapeMetadata.Displayed.Invoke((action, displayContext) => action(displayContext), displayContext, _logger);
            }
            finally
            {
                await _shapeDisplayEvents.InvokeAsync((e, displayContext) => e.DisplayingFinalizedAsync(displayContext), displayContext, _logger);
            }

            return(shape.Metadata.ChildContent);
        }
Ejemplo n.º 6
0
        private static ValueTask <IHtmlContent> ProcessAsync(ShapeBinding shapeBinding, IShape shape, DisplayContext context)
        {
            async ValueTask <IHtmlContent> Awaited(Task <IHtmlContent> task)
            {
                return(CoerceHtmlString(await task));
            }

            if (shapeBinding?.BindingAsync == null)
            {
                // todo: create result from all child shapes
                return(new ValueTask <IHtmlContent>(shape.Metadata.ChildContent ?? HtmlString.Empty));
            }

            var task = shapeBinding.BindingAsync(context);

            if (!task.IsCompletedSuccessfully)
            {
                return(Awaited(task));
            }

            return(new ValueTask <IHtmlContent>(CoerceHtmlString(task.Result)));
        }
Ejemplo n.º 7
0
 private static ValueTask <IHtmlContent> ProcessAsync(ShapeBinding shapeBinding, IShape shape, DisplayContext context)
 {