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

Commit e2b8400

Browse files
author
NTaylorMullen
committed
Moved TagHelperOutput methods to extension methods.
1 parent 55d94d4 commit e2b8400

File tree

3 files changed

+112
-82
lines changed

3 files changed

+112
-82
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using Microsoft.AspNet.Mvc.Rendering;
8+
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
9+
10+
namespace Microsoft.AspNet.Mvc.TagHelpers
11+
{
12+
/// <summary>
13+
/// Utility related extensions for <see cref="TagHelperOutput"/>.
14+
/// </summary>
15+
public static class TagHelperOutputExtensions
16+
{
17+
/// <summary>
18+
/// Merges the given <paramref name="tagBuilder"/> into the <paramref name="tagHelperOutput"/>.
19+
/// </summary>
20+
/// <param name="tagHelperOutput">The <see cref="TagHelperOutput"/>.</param>
21+
/// <param name="tagBuilder">The <see cref="TagBuilder"/> to merge.</param>
22+
public static void Merge(this TagHelperOutput tagHelperOutput, TagBuilder tagBuilder)
23+
{
24+
tagHelperOutput.TagName = tagBuilder.TagName;
25+
tagHelperOutput.Content = tagBuilder.InnerHtml;
26+
27+
MergeAttributes(tagHelperOutput, tagBuilder);
28+
}
29+
30+
/// <summary>
31+
/// Merges the given <see cref="tagBuilder"/>'s <see cref="TagBuilder.Attributes"/> into the
32+
/// <paramref name="tagHelperOutput"/>.
33+
/// </summary>
34+
/// <param name="tagHelperOutput">The <see cref="TagHelperOutput"/>.</param>
35+
/// <param name="tagBuilder">The <see cref="TagBuilder"/> to merge attributes from.</param>
36+
public static void MergeAttributes(this TagHelperOutput tagHelperOutput, TagBuilder tagBuilder)
37+
{
38+
foreach (var attribute in tagBuilder.Attributes)
39+
{
40+
if (!tagHelperOutput.Attributes.ContainsKey(attribute.Key))
41+
{
42+
tagHelperOutput.Attributes.Add(attribute.Key, attribute.Value);
43+
}
44+
else if (attribute.Key.Equals("class", StringComparison.Ordinal))
45+
{
46+
tagHelperOutput.Attributes["class"] += " " + attribute.Value;
47+
}
48+
}
49+
}
50+
51+
/// <summary>
52+
/// Returns and removes all attributes from <paramref name="tagHelperOutput"/>'s
53+
/// <see cref="TagHelperOutput.Attributes"/> that have the given <paramref name="prefix"/>.
54+
/// </summary>
55+
/// <param name="tagHelperOutput">The <see cref="TagHelperOutput"/>.</param>
56+
/// <param name="prefix">The prefix to </param>
57+
/// <returns><see cref="KeyValuePair{string, string}"/>s whos <see cref="KeyValuePair{string, string}.Key"/>
58+
/// starts with the given <paramref name="prefix"/>.</returns>
59+
public static IEnumerable<KeyValuePair<string, string>> PullPrefixedAttributes(
60+
this TagHelperOutput tagHelperOutput, string prefix)
61+
{
62+
// TODO: We will not need this method once https://github.com/aspnet/Razor/issues/89 is completed.
63+
64+
var htmlAttributes = tagHelperOutput.Attributes;
65+
66+
// We're only interested in HTML attributes that have the desired prefix.
67+
var prefixedAttributes = htmlAttributes.Where(attribute =>
68+
attribute.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)).ToArray();
69+
70+
// Since we're "pulling" the prefixed attribute values, we need to remove them.
71+
foreach (var attribute in prefixedAttributes)
72+
{
73+
htmlAttributes.Remove(attribute.Key);
74+
}
75+
76+
return prefixedAttributes;
77+
}
78+
79+
/// <summary>
80+
/// Restores a user provided bound attribute to the given <paramref name="tagHelperOutput"/>.
81+
/// </summary>
82+
/// <param name="tagHelperOutput">The <see cref="TagHelperOutput"/>.</param>
83+
/// <param name="boundAttributeName">The name of the bound attribute.</param>
84+
/// <param name="context">The <see cref="TagHelperContext"/>.</param>
85+
public static void RestoreBoundHtmlAttribute(this TagHelperOutput tagHelperOutput,
86+
string boundAttributeName,
87+
TagHelperContext context)
88+
{
89+
// We look for the original attribute so we can restore the exact attribute name the user typed.
90+
var entry = context.AllAttributes.Single(attribute =>
91+
attribute.Key.Equals(boundAttributeName, StringComparison.OrdinalIgnoreCase));
92+
var originalAttribute = new KeyValuePair<string, string>(entry.Key, entry.Value.ToString());
93+
94+
tagHelperOutput.Attributes.Add(originalAttribute);
95+
}
96+
}
97+
}

src/Microsoft.AspNet.Mvc.TagHelpers/TagHelperOutputHelper.cs

Lines changed: 0 additions & 68 deletions
This file was deleted.

test/Microsoft.AspNet.Mvc.TagHelpers.Test/TagHelperOutputHelperTest.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
using System.Collections.Generic;
55
using System.Linq;
66
using Microsoft.AspNet.Mvc.Rendering;
7-
using Microsoft.AspNet.Mvc.TagHelpers.Internal;
87
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
98
using Xunit;
109

1110
namespace Microsoft.AspNet.Mvc.TagHelpers
1211
{
13-
public class TagHelperOutputHelperTest
12+
public class tagHelperOutputTest
1413
{
1514
[Theory]
1615
[InlineData("hello", "world")]
@@ -30,7 +29,7 @@ public void RestoreBoundHtmlAttribute_RestoresOriginalAttributes(string attribut
3029
var expectedAttribute = new KeyValuePair<string, string>(attributeName, attributeValue);
3130

3231
// Act
33-
TagHelperOutputHelper.RestoreBoundHtmlAttribute("hello", tagHelperContext, tagHelperOutput);
32+
tagHelperOutput.RestoreBoundHtmlAttribute("hello", tagHelperContext);
3433

3534
// Assert
3635
var attribute = Assert.Single(tagHelperOutput.Attributes);
@@ -53,7 +52,7 @@ public void PullPrefixedAttributes_OnlyRemovesPrefixed_TagHelperOutputAttributeV
5352
tagHelperOutput.Attributes.Add(expectedAttribute);
5453

5554
// Act
56-
var pulledAttributes = TagHelperOutputHelper.PullPrefixedAttributes("route-", tagHelperOutput);
55+
var pulledAttributes = tagHelperOutput.PullPrefixedAttributes("route-");
5756

5857
// Assert
5958
var attribute = Assert.Single(tagHelperOutput.Attributes);
@@ -78,7 +77,7 @@ public void PullPrefixedAttributes_ReturnsEmpty_AttributeListIfNoAttributesPrefi
7877
content: string.Empty);
7978

8079
// Act
81-
var pulledAttributes = TagHelperOutputHelper.PullPrefixedAttributes("route-", tagHelperOutput);
80+
var pulledAttributes = tagHelperOutput.PullPrefixedAttributes("route-");
8281

8382
// Assert
8483
Assert.Empty(pulledAttributes);
@@ -103,7 +102,7 @@ public void MergeAttributes_DoesNotReplace_TagHelperOutputAttributeValues()
103102
tagBuilder.Attributes.Add("type", "hello");
104103

105104
// Act
106-
TagHelperOutputHelper.MergeAttributes(tagBuilder, tagHelperOutput);
105+
tagHelperOutput.MergeAttributes(tagBuilder);
107106

108107
// Assert
109108
var attribute = Assert.Single(tagHelperOutput.Attributes);
@@ -126,7 +125,7 @@ public void MergeAttributes_AppendsClass_TagHelperOutputAttributeValues()
126125
var expectedAttribute = new KeyValuePair<string, string>("class", "Hello btn");
127126

128127
// Act
129-
TagHelperOutputHelper.MergeAttributes(tagBuilder, tagHelperOutput);
128+
tagHelperOutput.MergeAttributes(tagBuilder);
130129

131130
// Assert
132131
var attribute = Assert.Single(tagHelperOutput.Attributes);
@@ -147,7 +146,7 @@ public void MergeAttributes_DoesNotEncode_TagHelperOutputAttributeValues()
147146
tagBuilder.Attributes.Add(expectedAttribute);
148147

149148
// Act
150-
TagHelperOutputHelper.MergeAttributes(tagBuilder, tagHelperOutput);
149+
tagHelperOutput.MergeAttributes(tagBuilder);
151150

152151
// Assert
153152
var attribute = Assert.Single(tagHelperOutput.Attributes);
@@ -170,7 +169,7 @@ public void MergeAttributes_CopiesMultiple_TagHelperOutputAttributeValues()
170169
tagBuilder.Attributes.Add(expectedAttribute2);
171170

172171
// Act
173-
TagHelperOutputHelper.MergeAttributes(tagBuilder, tagHelperOutput);
172+
tagHelperOutput.MergeAttributes(tagBuilder);
174173

175174
// Assert
176175
Assert.Equal(2, tagHelperOutput.Attributes.Count);
@@ -194,7 +193,7 @@ public void MergeAttributes_Maintains_TagHelperOutputAttributeValues()
194193
var tagBuilder = new TagBuilder("p");
195194

196195
// Act
197-
TagHelperOutputHelper.MergeAttributes(tagBuilder, tagHelperOutput);
196+
tagHelperOutput.MergeAttributes(tagBuilder);
198197

199198
// Assert
200199
var attribute = Assert.Single(tagHelperOutput.Attributes);
@@ -217,7 +216,7 @@ public void MergeAttributes_Combines_TagHelperOutputAttributeValues()
217216
tagBuilder.Attributes.Add(expectedBuilderAttribute);
218217

219218
// Act
220-
TagHelperOutputHelper.MergeAttributes(tagBuilder, tagHelperOutput);
219+
tagHelperOutput.MergeAttributes(tagBuilder);
221220

222221
// Assert
223222
Assert.Equal(tagHelperOutput.Attributes.Count, 2);
@@ -244,14 +243,16 @@ public void Merge_CombinesAllTagHelperOutputAndTagBuilderProperties()
244243
tagBuilder.InnerHtml = "Hello from tagBuilder.";
245244

246245
// Act
247-
TagHelperOutputHelper.Merge(tagBuilder, tagHelperOutput);
246+
tagHelperOutput.Merge(tagBuilder);
248247

249248
// Assert
250249
Assert.Equal("div", tagHelperOutput.TagName);
251250
Assert.Equal("Hello from tagBuilder.", tagHelperOutput.Content);
252251
Assert.Equal(tagHelperOutput.Attributes.Count, 2);
253-
Assert.Equal(expectedOutputAttribute, tagHelperOutput.Attributes.First());
254-
Assert.Equal(expectedBuilderAttribute, tagHelperOutput.Attributes.Last());
252+
var attribute = Assert.Single(tagHelperOutput.Attributes, kvp => kvp.Key.Equals("class"));
253+
Assert.Equal(expectedOutputAttribute.Value, attribute.Value);
254+
attribute = Assert.Single(tagHelperOutput.Attributes, kvp => kvp.Key.Equals("for"));
255+
Assert.Equal(expectedBuilderAttribute.Value, attribute.Value);
255256
}
256257
}
257258
}

0 commit comments

Comments
 (0)