Skip to content
This repository was archived by the owner on Dec 19, 2018. It is now read-only.

Commit

Permalink
Add ContentBehaviorAttribute for TagHelpers.
Browse files Browse the repository at this point in the history
- Added detection of custom ContentBehaviors via the ContentBehaviorAttribute in the TagHelperDescriptorFactory.
- Updated some comments in the ContentBehavior enum.
- Add tests to validate custom content behavior resolution.

#122
  • Loading branch information
NTaylorMullen committed Oct 9, 2014
1 parent d080dc8 commit ec638b1
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using Microsoft.AspNet.Razor.TagHelpers;

namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
/// <summary>
/// Used to override <see cref="ITagHelper"/>'s behavior when its
/// <see cref="ITagHelper.ProcessAsync"/> is invoked.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class ContentBehaviorAttribute : Attribute
{
/// <summary>
/// Instantiates a new instance of the <see cref="ContentBehaviorAttribute"/> class.
/// </summary>
/// <param name="contentBehavior">The <see cref="Razor.TagHelpers.ContentBehavior"/> for the
/// <see cref="ITagHelper"/>.</param>
public ContentBehaviorAttribute(ContentBehavior contentBehavior)
{
ContentBehavior = contentBehavior;
}

/// <summary>
/// <see cref="Razor.TagHelpers.ContentBehavior"/> for the <see cref="ITagHelper"/>.
/// </summary>
public ContentBehavior ContentBehavior { get; private set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,14 @@ private static TagHelperAttributeDescriptor ToAttributeDescriptor(PropertyInfo p
return new TagHelperAttributeDescriptor(property.Name, property);
}

// TODO: Make the content behavior pull from a ContentBehaviorAttribute: https://github.com/aspnet/Razor/issues/122
private static ContentBehavior GetContentBehavior(Type type)
{
return ContentBehavior.None;
var typeInfo = type.GetTypeInfo();
var contentBehaviorAttribute = typeInfo.GetCustomAttribute<ContentBehaviorAttribute>(inherit: false);

return contentBehaviorAttribute != null ?
contentBehaviorAttribute.ContentBehavior :
ContentBehavior.None;
}

private static bool IsValidProperty(PropertyInfo property)
Expand Down
6 changes: 5 additions & 1 deletion src/Microsoft.AspNet.Razor.Runtime/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
},
"frameworks": {
"net45": { },
"aspnetcore50": { }
"aspnetcore50": {
"dependencies": {
"System.Reflection.Extensions": "4.0.0.0"
}
}
}
}
11 changes: 4 additions & 7 deletions src/Microsoft.AspNet.Razor/TagHelpers/ContentBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ namespace Microsoft.AspNet.Razor.TagHelpers
public enum ContentBehavior
{
/// <summary>
/// Indicates that the tag helper will not modify its inner HTML in any way. This is the default
/// Indicates that a tag helper will not modify its content in any way. This is the default
/// <see cref="ContentBehavior"/>.
/// </summary>
/// <remarks>Children of the current tag helper will execute after the current tag helper.</remarks>
None,

/// <summary>
/// Indicates that the tag helper wants anything within its tag builder's inner HTML to be
/// appended to content its children generate.
/// Indicates the tag helper's content should be appended to what its children generate.
/// </summary>
/// <remarks>Children of the current tag helper will execute before the current tag helper.</remarks>
Append,
Expand All @@ -30,15 +29,13 @@ public enum ContentBehavior
Modify,

/// <summary>
/// Indicates that the tag helper wants anything within its tag builder's inner HTML to be
/// prepended to the content its children generate.
/// Indicates the tag helper's content should be prepended to what its children generate.
/// </summary>
/// <remarks>Children of the current tag helper will execute after the current tag helper.</remarks>
Prepend,

/// <summary>
/// Indicates that the tag helper wants anything within its tag builder's inner HTML to
/// replace any HTML inside of it.
/// Indicates the tag helper's content should replace the HTML its children generate.
/// </summary>
/// <remarks>Children of the current tag helper will not execute.</remarks>
Replace,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public class TagHelperDescriptorFactoryTest
{
[Fact]
public void DescriptorFactory_BuildsDescriptorsFromSimpleTypes()
public void CreateDescriptor_BuildsDescriptorsFromSimpleTypes()
{
// Arrange
var expectedDescriptor = new TagHelperDescriptor("Object", "System.Object", ContentBehavior.None);
Expand All @@ -22,7 +22,7 @@ public void DescriptorFactory_BuildsDescriptorsFromSimpleTypes()
}

[Fact]
public void DescriptorFactory_BuildsDescriptorsWithConventionNames()
public void CreateDescriptor_BuildsDescriptorsWithConventionNames()
{
// Arrange
var intProperty = typeof(SingleAttributeTagHelper).GetProperty(nameof(SingleAttributeTagHelper.IntAttribute));
Expand All @@ -42,7 +42,7 @@ public void DescriptorFactory_BuildsDescriptorsWithConventionNames()
}

[Fact]
public void DescriptorFactory_OnlyAcceptsPropertiesWithGetAndSet()
public void CreateDescriptor_OnlyAcceptsPropertiesWithGetAndSet()
{
// Arrange
var validProperty = typeof(MissingAccessorTagHelper).GetProperty(
Expand All @@ -63,7 +63,7 @@ public void DescriptorFactory_OnlyAcceptsPropertiesWithGetAndSet()
}

[Fact]
public void DescriptorFactory_OnlyAcceptsPropertiesWithPublicGetAndSet()
public void CreateDescriptor_OnlyAcceptsPropertiesWithPublicGetAndSet()
{
// Arrange
var validProperty = typeof(PrivateAccessorTagHelper).GetProperty(
Expand All @@ -83,5 +83,48 @@ public void DescriptorFactory_OnlyAcceptsPropertiesWithPublicGetAndSet()
// Assert
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
}


[Fact]
public void CreateDescriptor_ResolvesCustomContentBehavior()
{
// Arrange
var expectedDescriptor = new TagHelperDescriptor(
"CustomContentBehavior",
typeof(CustomContentBehaviorTagHelper).FullName,
ContentBehavior.Append);

// Act
var descriptor = TagHelperDescriptorFactory.CreateDescriptor(typeof(CustomContentBehaviorTagHelper));

// Assert
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
}

[Fact]
public void CreateDescriptor_DoesNotResolveInheritedCustomContentBehavior()
{
// Arrange
var expectedDescriptor = new TagHelperDescriptor(
"InheritedCustomContentBehavior",
typeof(InheritedCustomContentBehaviorTagHelper).FullName,
ContentBehavior.None);

// Act
var descriptor = TagHelperDescriptorFactory.CreateDescriptor(
typeof(InheritedCustomContentBehaviorTagHelper));

// Assert
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
}

[ContentBehavior(ContentBehavior.Append)]
private class CustomContentBehaviorTagHelper
{
}

private class InheritedCustomContentBehaviorTagHelper : CustomContentBehaviorTagHelper
{
}
}
}

0 comments on commit ec638b1

Please sign in to comment.