MVC portion of aspnet/Razor#335
- set correct `MarkAsHtmlEncodedMethodName` value in `MvcRazorHost` - handle `HtmlString` values in `TagHelperOutput.Attributes` in `RazorPage` - special-case double-quotes in `HtmlString` values - add `static WriteTo()` method for use in tag helpers - handle non-`string` `output.Attributes` values in tag helpers - make `TagHelperContentWrapperTextWriter` a `public` class - provide a `TagHelperContent.Append(object, ...)` extension method - add `LinkTagHelper.Href` and `ScriptTagHelper.Src` properties - avoid Razor HTML-encoding these attribute values before their use - add `JavaScriptEncoder` properties in `LinkTagHelper` and `ScriptTagHelper` - allow encoding testing without unit testing the default encoder - handle MVC and Razor changes for this bug in existing tests - add functional tests of encodings - add test encoders to TestCommon project nits: - correct `InputTagHelper` to pass `type=""` through unchanged - set correct `TagHelperContentTypeName` value in `MvcRazorHost` - remove unnecessary `FormTagHelper.Method` and `OptionTagHelper.Selected` properties - remove complex ternaries and `ShouldAddFileVersion()` methods - add a few debug assertions - fix some odd wrapping - remove or `#if`-out unused `using`s - remove trailing whitespace
This commit is contained in:
parent
9402f1485c
commit
5882cdb03f
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if NET45
|
||||
using Microsoft.AspNet.FileProviders;
|
||||
#endif
|
||||
using Microsoft.AspNet.Mvc.Razor.Directives;
|
||||
using Microsoft.AspNet.Mvc.Razor.Internal;
|
||||
using Microsoft.AspNet.Razor;
|
||||
|
|
@ -18,6 +20,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
public class MvcRazorHost : RazorEngineHost, IMvcRazorHost
|
||||
{
|
||||
private const string BaseType = "Microsoft.AspNet.Mvc.Razor.RazorPage";
|
||||
private const string HtmlHelperPropertyName = "Html";
|
||||
|
||||
private static readonly string[] _defaultNamespaces = new[]
|
||||
{
|
||||
"System",
|
||||
|
|
@ -28,7 +32,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
};
|
||||
private static readonly Chunk[] _defaultInheritedChunks = new[]
|
||||
{
|
||||
new InjectChunk("Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<TModel>", "Html"),
|
||||
new InjectChunk("Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<TModel>", HtmlHelperPropertyName),
|
||||
new InjectChunk("Microsoft.AspNet.Mvc.IViewComponentHelper", "Component"),
|
||||
new InjectChunk("Microsoft.AspNet.Mvc.IUrlHelper", "Url"),
|
||||
};
|
||||
|
|
@ -76,6 +80,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
ScopeManagerBeginMethodName = nameof(TagHelperScopeManager.Begin),
|
||||
ScopeManagerEndMethodName = nameof(TagHelperScopeManager.End),
|
||||
|
||||
TagHelperContentTypeName = nameof(TagHelperContent),
|
||||
|
||||
// Can't use nameof because RazorPage is not accessible here.
|
||||
CreateTagHelperMethodName = "CreateTagHelper",
|
||||
StartTagHelperWritingScopeMethodName = "StartTagHelperWritingScope",
|
||||
|
|
@ -83,6 +89,9 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
WriteTagHelperAsyncMethodName = "WriteTagHelperAsync",
|
||||
WriteTagHelperToAsyncMethodName = "WriteTagHelperToAsync",
|
||||
|
||||
// Can't use nameof because IHtmlHelper is (also) not accessible here.
|
||||
MarkAsHtmlEncodedMethodName = HtmlHelperPropertyName + ".Raw",
|
||||
})
|
||||
{
|
||||
ResolveUrlMethodName = "Href",
|
||||
|
|
|
|||
|
|
@ -294,11 +294,10 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
foreach (var attribute in tagHelperOutput.Attributes)
|
||||
{
|
||||
var value = HtmlEncoder.HtmlEncode(attribute.Value);
|
||||
writer.Write(' ');
|
||||
writer.Write(attribute.Key);
|
||||
writer.Write("=\"");
|
||||
writer.Write(value);
|
||||
WriteTo(writer, HtmlEncoder, attribute.Value, escapeQuotes: true);
|
||||
writer.Write('"');
|
||||
}
|
||||
|
||||
|
|
@ -366,26 +365,67 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// </remarks>
|
||||
public virtual void WriteTo([NotNull] TextWriter writer, object value)
|
||||
{
|
||||
if (value != null && value != HtmlString.Empty)
|
||||
WriteTo(writer, HtmlEncoder, value, escapeQuotes: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified <paramref name="value"/> with HTML encoding to given <paramref name="writer"/>.
|
||||
/// </summary>
|
||||
/// <param name="writer">The <see cref="TextWriter"/> instance to write to.</param>
|
||||
/// <param name="encoder">The <see cref="IHtmlEncoder"/> to use when encoding <paramref name="value"/>.</param>
|
||||
/// <param name="value">The <see cref="object"/> to write.</param>
|
||||
/// <param name="escapeQuotes">
|
||||
/// If <c>true</c> escapes double quotes in a <paramref name="value"/> of type <see cref="HtmlString"/>.
|
||||
/// Otherwise writes <see cref="HtmlString"/> values as-is.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// <paramref name="value"/>s of type <see cref="HtmlString"/> are written without encoding and the
|
||||
/// <see cref="HelperResult.WriteTo(TextWriter)"/> is invoked for <see cref="HelperResult"/> types.
|
||||
/// For all other types, the encoded result of <see cref="object.ToString"/> is written to the
|
||||
/// <paramref name="writer"/>.
|
||||
/// </remarks>
|
||||
public static void WriteTo(
|
||||
[NotNull] TextWriter writer,
|
||||
[NotNull] IHtmlEncoder encoder,
|
||||
object value,
|
||||
bool escapeQuotes)
|
||||
{
|
||||
if (value == null || value == HtmlString.Empty)
|
||||
{
|
||||
var helperResult = value as HelperResult;
|
||||
if (helperResult != null)
|
||||
{
|
||||
helperResult.WriteTo(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
var htmlString = value as HtmlString;
|
||||
if (htmlString != null)
|
||||
{
|
||||
writer.Write(htmlString);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteTo(writer, value.ToString());
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var helperResult = value as HelperResult;
|
||||
if (helperResult != null)
|
||||
{
|
||||
helperResult.WriteTo(writer);
|
||||
return;
|
||||
}
|
||||
|
||||
var htmlString = value as HtmlString;
|
||||
if (htmlString != null)
|
||||
{
|
||||
if (escapeQuotes)
|
||||
{
|
||||
// In this case the text likely came directly from the Razor source. Since the original string is
|
||||
// an attribute value that may have been quoted with single quotes, must handle any double quotes
|
||||
// in the value. Writing the value out surrounded by double quotes.
|
||||
//
|
||||
// Do not combine following condition with check of escapeQuotes; htmlString.ToString() can be
|
||||
// expensive when the HtmlString is created with a StringCollectionTextWriter.
|
||||
var stringValue = htmlString.ToString();
|
||||
if (stringValue.Contains("\""))
|
||||
{
|
||||
writer.Write(stringValue.Replace("\"", """));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
htmlString.WriteTo(writer);
|
||||
return;
|
||||
}
|
||||
|
||||
WriteTo(writer, encoder, value.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -394,10 +434,15 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// <param name="writer">The <see cref="TextWriter"/> instance to write to.</param>
|
||||
/// <param name="value">The <see cref="string"/> to write.</param>
|
||||
public virtual void WriteTo([NotNull] TextWriter writer, string value)
|
||||
{
|
||||
WriteTo(writer, HtmlEncoder, value);
|
||||
}
|
||||
|
||||
private static void WriteTo(TextWriter writer, IHtmlEncoder encoder, string value)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
HtmlEncoder.HtmlEncode(value, writer);
|
||||
encoder.HtmlEncode(value, writer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -766,33 +811,5 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
throw new InvalidOperationException(Resources.FormatRazorPage_MethodCannotBeCalled(methodName));
|
||||
}
|
||||
}
|
||||
|
||||
private class TagHelperContentWrapperTextWriter : TextWriter
|
||||
{
|
||||
public TagHelperContentWrapperTextWriter(Encoding encoding)
|
||||
{
|
||||
Content = new DefaultTagHelperContent();
|
||||
Encoding = encoding;
|
||||
}
|
||||
|
||||
public TagHelperContent Content { get; }
|
||||
|
||||
public override Encoding Encoding { get; }
|
||||
|
||||
public override void Write(string value)
|
||||
{
|
||||
Content.Append(value);
|
||||
}
|
||||
|
||||
public override void Write(char value)
|
||||
{
|
||||
Content.Append(value.ToString());
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Content.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// 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.IO;
|
||||
using System.Text;
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="TextWriter"/> implementation which writes to a <see cref="TagHelperContent"/> instance.
|
||||
/// </summary>
|
||||
public class TagHelperContentWrapperTextWriter : TextWriter
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TagHelperContentWrapperTextWriter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="encoding">The <see cref="Encoding"/> in which output is written.</param>
|
||||
public TagHelperContentWrapperTextWriter([NotNull] Encoding encoding)
|
||||
: this(encoding, new DefaultTagHelperContent())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TagHelperContentWrapperTextWriter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="encoding">The <see cref="Encoding"/> in which output is written.</param>
|
||||
/// <param name="content">The <see cref="TagHelperContent"/> to write to.</param>
|
||||
public TagHelperContentWrapperTextWriter([NotNull] Encoding encoding, [NotNull] TagHelperContent content)
|
||||
{
|
||||
Content = content;
|
||||
Encoding = encoding;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="TagHelperContent"/> this <see cref="TagHelperContentWrapperTextWriter"/> writes to.
|
||||
/// </summary>
|
||||
public TagHelperContent Content { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Encoding Encoding { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Write(string value)
|
||||
{
|
||||
Content.Append(value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Write(char value)
|
||||
{
|
||||
Content.Append(value.ToString());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return Content.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -153,7 +153,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
// TODO: https://github.com/aspnet/Razor/issues/89 - We will not need this method once #89 is completed.
|
||||
private static Dictionary<string, object> GetRouteValues(
|
||||
TagHelperOutput output, IEnumerable<KeyValuePair<string, string>> routePrefixedAttributes)
|
||||
TagHelperOutput output,
|
||||
IEnumerable<KeyValuePair<string, object>> routePrefixedAttributes)
|
||||
{
|
||||
Dictionary<string, object> routeValues = null;
|
||||
if (routePrefixedAttributes.Any())
|
||||
|
|
@ -161,10 +162,11 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Prefixed values should be treated as bound attributes, remove them from the output.
|
||||
output.RemoveRange(routePrefixedAttributes);
|
||||
|
||||
// Generator.GenerateForm does not accept a Dictionary<string, string> for route values.
|
||||
// Remove prefix from keys and convert all values to strings. HtmlString and similar classes are not
|
||||
// meaningful to routing.
|
||||
routeValues = routePrefixedAttributes.ToDictionary(
|
||||
attribute => attribute.Key.Substring(RouteAttributePrefix.Length),
|
||||
attribute => (object)attribute.Value);
|
||||
attribute => (object)attribute.Value.ToString());
|
||||
}
|
||||
|
||||
return routeValues;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Protected to ensure subclasses are correctly activated. Internal for ease of use when testing.
|
||||
[Activate]
|
||||
protected internal IHtmlGenerator Generator { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The name of the action method.
|
||||
/// </summary>
|
||||
|
|
@ -41,12 +41,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
public string Controller { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP method for processing the form, either GET or POST.
|
||||
/// </summary>
|
||||
public string Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the anti-forgery token should be generated.
|
||||
/// Whether the anti-forgery token should be generated.
|
||||
/// </summary>
|
||||
/// <value>Defaults to <c>false</c> if user provides an <c>action</c> attribute; <c>true</c> otherwise.</value>
|
||||
[HtmlAttributeName(AntiForgeryAttributeName)]
|
||||
|
|
@ -84,12 +79,6 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// User is using the FormTagHelper like a normal <form> tag. Anti-forgery default should be false to
|
||||
// not force the anti-forgery token on the user.
|
||||
antiForgeryDefault = false;
|
||||
|
||||
// Restore method attribute.
|
||||
if (Method != null)
|
||||
{
|
||||
output.CopyHtmlAttribute(nameof(Method), context);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -98,7 +87,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Action,
|
||||
Controller,
|
||||
routeValues,
|
||||
Method,
|
||||
method: null,
|
||||
htmlAttributes: null);
|
||||
|
||||
if (tagBuilder != null)
|
||||
|
|
@ -120,7 +109,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
// TODO: https://github.com/aspnet/Razor/issues/89 - We will not need this method once #89 is completed.
|
||||
private static Dictionary<string, object> GetRouteValues(
|
||||
TagHelperOutput output, IEnumerable<KeyValuePair<string, string>> routePrefixedAttributes)
|
||||
TagHelperOutput output,
|
||||
IEnumerable<KeyValuePair<string, object>> routePrefixedAttributes)
|
||||
{
|
||||
Dictionary<string, object> routeValues = null;
|
||||
if (routePrefixedAttributes.Any())
|
||||
|
|
@ -128,10 +118,11 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Prefixed values should be treated as bound attributes, remove them from the output.
|
||||
output.RemoveRange(routePrefixedAttributes);
|
||||
|
||||
// Generator.GenerateForm does not accept a Dictionary<string, string> for route values.
|
||||
// Remove prefix from keys and convert all values to strings. HtmlString and similar classes are not
|
||||
// meaningful to routing.
|
||||
routeValues = routePrefixedAttributes.ToDictionary(
|
||||
attribute => attribute.Key.Substring(RouteAttributePrefix.Length),
|
||||
attribute => (object)attribute.Value);
|
||||
attribute => (object)attribute.Value.ToString());
|
||||
}
|
||||
|
||||
return routeValues;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ using System.Linq;
|
|||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.TagHelpers
|
||||
{
|
||||
|
|
@ -112,7 +111,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
{
|
||||
// Pass through attributes that are also well-known HTML attributes. Must be done prior to any copying
|
||||
// from a TagBuilder.
|
||||
if (!string.IsNullOrEmpty(InputTypeName))
|
||||
if (InputTypeName != null)
|
||||
{
|
||||
output.CopyHtmlAttribute("type", context);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Hosting;
|
||||
|
|
@ -10,7 +11,6 @@ using Microsoft.AspNet.Mvc.TagHelpers.Internal;
|
|||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.Framework.Caching.Memory;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.Runtime;
|
||||
using Microsoft.Framework.WebEncoders;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.TagHelpers
|
||||
|
|
@ -98,6 +98,15 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Fallback = 2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Address of the linked resource.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Passed through to the generated HTML in all cases.
|
||||
/// </remarks>
|
||||
[HtmlAttributeName(HrefAttributeName)]
|
||||
public string Href { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A comma separated list of globbed file patterns of CSS stylesheets to load.
|
||||
/// The glob patterns are assessed relative to the application's 'webroot' setting.
|
||||
|
|
@ -189,12 +198,21 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
[Activate]
|
||||
protected internal IHtmlEncoder HtmlEncoder { get; set; }
|
||||
|
||||
[Activate]
|
||||
protected internal IJavaScriptStringEncoder JavaScriptEncoder { get; set; }
|
||||
|
||||
// Internal for ease of use when testing.
|
||||
protected internal GlobbingUrlBuilder GlobbingUrlBuilder { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
// Pass through attribute that is also a well-known HTML attribute.
|
||||
if (Href != null)
|
||||
{
|
||||
output.CopyHtmlAttribute(HrefAttributeName, context);
|
||||
}
|
||||
|
||||
var modeResult = AttributeMatcher.DetermineMode(context, ModeDetails);
|
||||
|
||||
var logger = Logger ?? LoggerFactory.CreateLogger<LinkTagHelper>();
|
||||
|
|
@ -210,8 +228,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Get the highest matched mode
|
||||
var mode = modeResult.FullMatches.Select(match => match.Mode).Max();
|
||||
|
||||
// NOTE: Values in TagHelperOutput.Attributes are already HtmlEncoded
|
||||
var attributes = new Dictionary<string, string>(output.Attributes);
|
||||
// NOTE: Values in TagHelperOutput.Attributes may already be HTML-encoded.
|
||||
var attributes = new Dictionary<string, object>(output.Attributes);
|
||||
|
||||
var builder = new DefaultTagHelperContent();
|
||||
|
||||
|
|
@ -236,17 +254,17 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
output.Content.SetContent(builder);
|
||||
}
|
||||
|
||||
private void BuildGlobbedLinkTags(IDictionary<string, string> attributes, TagHelperContent builder)
|
||||
private void BuildGlobbedLinkTags(IDictionary<string, object> attributes, TagHelperContent builder)
|
||||
{
|
||||
// Build a <link /> tag for each matched href as well as the original one in the source file
|
||||
string staticHref;
|
||||
attributes.TryGetValue(HrefAttributeName, out staticHref);
|
||||
|
||||
EnsureGlobbingUrlBuilder();
|
||||
var urls = GlobbingUrlBuilder.BuildUrlList(staticHref, HrefInclude, HrefExclude);
|
||||
|
||||
// Build a <link /> tag for each matched href as well as the original one in the source file
|
||||
var urls = GlobbingUrlBuilder.BuildUrlList(Href, HrefInclude, HrefExclude);
|
||||
foreach (var url in urls)
|
||||
{
|
||||
// "url" values come from bound attributes and globbing. Must always be non-null.
|
||||
Debug.Assert(url != null);
|
||||
|
||||
attributes[HrefAttributeName] = url;
|
||||
BuildLinkTag(attributes, builder);
|
||||
}
|
||||
|
|
@ -260,10 +278,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
if (fallbackHrefs.Length > 0)
|
||||
{
|
||||
if (ShouldAddFileVersion())
|
||||
if (FileVersion == true)
|
||||
{
|
||||
for (var i=0; i < fallbackHrefs.Length; i++)
|
||||
{
|
||||
// fallbackHrefs come from bound attributes and globbing. Must always be non-null.
|
||||
Debug.Assert(fallbackHrefs[i] != null);
|
||||
|
||||
fallbackHrefs[i] = _fileVersionProvider.AddFileVersionToPath(fallbackHrefs[i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -279,13 +300,15 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Build the <script /> tag that checks the effective style of <meta /> tag above and renders the extra
|
||||
// <link /> tag to load the fallback stylesheet if the test CSS property value is found to be false,
|
||||
// indicating that the primary stylesheet failed to load.
|
||||
builder.Append("<script>")
|
||||
.Append(string.Format(CultureInfo.InvariantCulture,
|
||||
JavaScriptResources.GetEmbeddedJavaScript(FallbackJavaScriptResourceName),
|
||||
JavaScriptStringEncoder.Default.JavaScriptStringEncode(FallbackTestProperty),
|
||||
JavaScriptStringEncoder.Default.JavaScriptStringEncode(FallbackTestValue),
|
||||
JavaScriptStringArrayEncoder.Encode(JavaScriptStringEncoder.Default, fallbackHrefs)))
|
||||
.Append("</script>");
|
||||
builder
|
||||
.Append("<script>")
|
||||
.Append(string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
JavaScriptResources.GetEmbeddedJavaScript(FallbackJavaScriptResourceName),
|
||||
JavaScriptEncoder.JavaScriptStringEncode(FallbackTestProperty),
|
||||
JavaScriptEncoder.JavaScriptStringEncode(FallbackTestValue),
|
||||
JavaScriptStringArrayEncoder.Encode(JavaScriptEncoder, fallbackHrefs)))
|
||||
.Append("</script>");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -311,7 +334,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
}
|
||||
}
|
||||
|
||||
private void BuildLinkTag(IDictionary<string, string> attributes, TagHelperContent builder)
|
||||
private void BuildLinkTag(IDictionary<string, object> attributes, TagHelperContent builder)
|
||||
{
|
||||
EnsureFileVersionProvider();
|
||||
builder.Append("<link ");
|
||||
|
|
@ -319,27 +342,27 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
foreach (var attribute in attributes)
|
||||
{
|
||||
var attributeValue = attribute.Value;
|
||||
if (string.Equals(attribute.Key, HrefAttributeName, StringComparison.OrdinalIgnoreCase))
|
||||
if (FileVersion == true &&
|
||||
string.Equals(attribute.Key, HrefAttributeName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
attributeValue = HtmlEncoder.HtmlEncode(
|
||||
ShouldAddFileVersion() ?
|
||||
_fileVersionProvider.AddFileVersionToPath(attributeValue) :
|
||||
attributeValue);
|
||||
// "href" values come from bound attributes and globbing. So anything but a non-null string is
|
||||
// unexpected but could happen if another helper targeting the same element does something odd.
|
||||
// Pass through existing value in that case.
|
||||
var attributeStringValue = attributeValue as string;
|
||||
if (attributeStringValue != null)
|
||||
{
|
||||
attributeValue = _fileVersionProvider.AddFileVersionToPath(attributeStringValue);
|
||||
}
|
||||
}
|
||||
|
||||
builder
|
||||
.Append(attribute.Key)
|
||||
.Append("=\"")
|
||||
.Append(attributeValue)
|
||||
.Append(HtmlEncoder, ViewContext.Writer.Encoding, attributeValue)
|
||||
.Append("\" ");
|
||||
}
|
||||
|
||||
builder.Append("/>");
|
||||
}
|
||||
|
||||
private bool ShouldAddFileVersion()
|
||||
{
|
||||
return FileVersion ?? false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.TagHelpers
|
||||
{
|
||||
|
|
@ -28,14 +27,6 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
[Activate]
|
||||
protected internal ViewContext ViewContext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that this <option> is pre-selected.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Passed through to the generated HTML in all cases.
|
||||
/// </remarks>
|
||||
public string Selected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies a value for the <option> element.
|
||||
/// </summary>
|
||||
|
|
@ -59,12 +50,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
output.CopyHtmlAttribute(nameof(Value), context);
|
||||
}
|
||||
|
||||
if (Selected != null)
|
||||
{
|
||||
// This <option/> will always be selected.
|
||||
output.CopyHtmlAttribute(nameof(Selected), context);
|
||||
}
|
||||
else
|
||||
// Nothing to do if this <option/> is already selected.
|
||||
if (!output.Attributes.ContainsKey("selected"))
|
||||
{
|
||||
// Is this <option/> element a child of a <select/> element the SelectTagHelper targeted?
|
||||
object formDataEntry;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Hosting;
|
||||
|
|
@ -10,7 +11,6 @@ using Microsoft.AspNet.Mvc.TagHelpers.Internal;
|
|||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.Framework.Caching.Memory;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.Runtime;
|
||||
using Microsoft.Framework.WebEncoders;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.TagHelpers
|
||||
|
|
@ -87,6 +87,15 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Fallback = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Address of the external script to use.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Passed through to the generated HTML in all cases.
|
||||
/// </remarks>
|
||||
[HtmlAttributeName(SrcAttributeName)]
|
||||
public string Src { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A comma separated list of globbed file patterns of JavaScript scripts to load.
|
||||
/// The glob patterns are assessed relative to the application's 'webroot' setting.
|
||||
|
|
@ -159,12 +168,21 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
[Activate]
|
||||
protected internal IHtmlEncoder HtmlEncoder { get; set; }
|
||||
|
||||
[Activate]
|
||||
protected internal IJavaScriptStringEncoder JavaScriptEncoder { get; set; }
|
||||
|
||||
// Internal for ease of use when testing.
|
||||
protected internal GlobbingUrlBuilder GlobbingUrlBuilder { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
// Pass through attribute that is also a well-known HTML attribute.
|
||||
if (Src != null)
|
||||
{
|
||||
output.CopyHtmlAttribute(SrcAttributeName, context);
|
||||
}
|
||||
|
||||
var modeResult = AttributeMatcher.DetermineMode(context, ModeDetails);
|
||||
|
||||
var logger = Logger ?? LoggerFactory.CreateLogger<ScriptTagHelper>();
|
||||
|
|
@ -180,9 +198,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Get the highest matched mode
|
||||
var mode = modeResult.FullMatches.Select(match => match.Mode).Max();
|
||||
|
||||
// NOTE: Values in TagHelperOutput.Attributes are already HtmlEncoded
|
||||
var attributes = new Dictionary<string, string>(output.Attributes);
|
||||
|
||||
// NOTE: Values in TagHelperOutput.Attributes may already be HTML-encoded.
|
||||
var attributes = new Dictionary<string, object>(output.Attributes);
|
||||
|
||||
var builder = new DefaultTagHelperContent();
|
||||
var originalContent = await context.GetChildContentAsync();
|
||||
|
||||
|
|
@ -209,32 +227,36 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
private void BuildGlobbedScriptTags(
|
||||
TagHelperContent originalContent,
|
||||
IDictionary<string, string> attributes,
|
||||
IDictionary<string, object> attributes,
|
||||
TagHelperContent builder)
|
||||
{
|
||||
// Build a <script> tag for each matched src as well as the original one in the source file
|
||||
string staticSrc;
|
||||
attributes.TryGetValue(SrcAttributeName, out staticSrc);
|
||||
|
||||
EnsureGlobbingUrlBuilder();
|
||||
var urls = GlobbingUrlBuilder.BuildUrlList(staticSrc, SrcInclude, SrcExclude);
|
||||
|
||||
// Build a <script> tag for each matched src as well as the original one in the source file
|
||||
var urls = GlobbingUrlBuilder.BuildUrlList(Src, SrcInclude, SrcExclude);
|
||||
foreach (var url in urls)
|
||||
{
|
||||
// "url" values come from bound attributes and globbing. Must always be non-null.
|
||||
Debug.Assert(url != null);
|
||||
|
||||
var content = originalContent;
|
||||
if (!string.Equals(url, Src, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Do not copy content into added <script/> elements.
|
||||
content = null;
|
||||
}
|
||||
|
||||
attributes[SrcAttributeName] = url;
|
||||
var content =
|
||||
string.Equals(url, staticSrc, StringComparison.OrdinalIgnoreCase) ? originalContent : null;
|
||||
BuildScriptTag(content, attributes, builder);
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildFallbackBlock(IDictionary<string, string> attributes, DefaultTagHelperContent builder)
|
||||
private void BuildFallbackBlock(IDictionary<string, object> attributes, DefaultTagHelperContent builder)
|
||||
{
|
||||
EnsureGlobbingUrlBuilder();
|
||||
EnsureFileVersionProvider();
|
||||
|
||||
var fallbackSrcs = GlobbingUrlBuilder.BuildUrlList(FallbackSrc, FallbackSrcInclude, FallbackSrcExclude);
|
||||
|
||||
if (fallbackSrcs.Any())
|
||||
{
|
||||
// Build the <script> tag that checks the test method and if it fails, renders the extra script.
|
||||
|
|
@ -243,36 +265,43 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
.Append(FallbackTestExpression)
|
||||
.Append("||document.write(\"");
|
||||
|
||||
// May have no "src" attribute in the dictionary e.g. if Src and SrcInclude were not bound.
|
||||
if (!attributes.ContainsKey(SrcAttributeName))
|
||||
{
|
||||
// Need this entry to place each fallback source.
|
||||
attributes.Add(SrcAttributeName, null);
|
||||
}
|
||||
|
||||
foreach (var src in fallbackSrcs)
|
||||
{
|
||||
builder.Append("<script");
|
||||
// Fallback "src" values come from bound attributes and globbing. Must always be non-null.
|
||||
Debug.Assert(src != null);
|
||||
|
||||
if (!attributes.ContainsKey(SrcAttributeName))
|
||||
{
|
||||
AppendAttribute(
|
||||
builder,
|
||||
SrcAttributeName,
|
||||
HtmlEncoder.HtmlEncode(ShouldAddFileVersion() ? _fileVersionProvider.AddFileVersionToPath(src) : src),
|
||||
escapteQuotes: true);
|
||||
}
|
||||
builder.Append("<script");
|
||||
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
if (!attribute.Key.Equals(SrcAttributeName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var encodedKey = JavaScriptStringEncoder.Default.JavaScriptStringEncode(attribute.Key);
|
||||
var encodedValue = JavaScriptStringEncoder.Default.JavaScriptStringEncode(attribute.Value);
|
||||
var encodedKey = JavaScriptEncoder.JavaScriptStringEncode(attribute.Key);
|
||||
var attributeValue = attribute.Value.ToString();
|
||||
var encodedValue = JavaScriptEncoder.JavaScriptStringEncode(attributeValue);
|
||||
|
||||
AppendAttribute(builder, encodedKey, encodedValue, escapteQuotes: true);
|
||||
AppendAttribute(builder, encodedKey, encodedValue, escapeQuotes: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendAttribute(
|
||||
builder,
|
||||
attribute.Key,
|
||||
HtmlEncoder.HtmlEncode(
|
||||
ShouldAddFileVersion() ? _fileVersionProvider.AddFileVersionToPath(src) : src),
|
||||
escapteQuotes: true);
|
||||
// Ignore attribute.Value; use src instead.
|
||||
var attributeValue = src;
|
||||
if (FileVersion == true)
|
||||
{
|
||||
attributeValue = _fileVersionProvider.AddFileVersionToPath(attributeValue);
|
||||
}
|
||||
|
||||
// attribute.Key ("src") does not need to be JavaScript-encoded.
|
||||
var encodedValue = JavaScriptEncoder.JavaScriptStringEncode(attributeValue);
|
||||
|
||||
AppendAttribute(builder, attribute.Key, encodedValue, escapeQuotes: true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +336,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
private void BuildScriptTag(
|
||||
TagHelperContent content,
|
||||
IDictionary<string, string> attributes,
|
||||
IDictionary<string, object> attributes,
|
||||
TagHelperContent builder)
|
||||
{
|
||||
EnsureFileVersionProvider();
|
||||
|
|
@ -315,16 +344,21 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
string attributeValue = attribute.Value;
|
||||
if (string.Equals(attribute.Key, SrcAttributeName, StringComparison.OrdinalIgnoreCase))
|
||||
var attributeValue = attribute.Value;
|
||||
if (FileVersion == true &&
|
||||
string.Equals(attribute.Key, SrcAttributeName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
attributeValue = HtmlEncoder.HtmlEncode(
|
||||
ShouldAddFileVersion() ?
|
||||
_fileVersionProvider.AddFileVersionToPath(attribute.Value) :
|
||||
attributeValue);
|
||||
// "src" values come from bound attributes and globbing. So anything but a non-null string is
|
||||
// unexpected but could happen if another helper targeting the same element does something odd.
|
||||
// Pass through existing value in that case.
|
||||
var attributeStringValue = attributeValue as string;
|
||||
if (attributeStringValue != null)
|
||||
{
|
||||
attributeValue = _fileVersionProvider.AddFileVersionToPath(attributeStringValue);
|
||||
}
|
||||
}
|
||||
|
||||
AppendAttribute(builder, attribute.Key, attributeValue, escapteQuotes: false);
|
||||
AppendAttribute(builder, attribute.Key, attributeValue, escapeQuotes: false);
|
||||
}
|
||||
|
||||
builder.Append(">")
|
||||
|
|
@ -332,20 +366,27 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
.Append("</script>");
|
||||
}
|
||||
|
||||
private bool ShouldAddFileVersion()
|
||||
{
|
||||
return FileVersion ?? false;
|
||||
}
|
||||
|
||||
private void AppendAttribute(TagHelperContent content, string key, string value, bool escapteQuotes)
|
||||
private void AppendAttribute(TagHelperContent content, string key, object value, bool escapeQuotes)
|
||||
{
|
||||
content
|
||||
.Append(" ")
|
||||
.Append(key)
|
||||
.Append(escapteQuotes ? "=\\\"" : "=\"")
|
||||
.Append(value)
|
||||
.Append(escapteQuotes ? "\\\"" : "\"");
|
||||
.Append(key);
|
||||
if (escapeQuotes)
|
||||
{
|
||||
// Passed only JavaScript-encoded strings in this case. Do not perform HTML-encoding as well.
|
||||
content
|
||||
.Append("=\\\"")
|
||||
.Append((string)value)
|
||||
.Append("\\\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
// HTML-encoded the given value if necessary.
|
||||
content
|
||||
.Append("=\"")
|
||||
.Append(HtmlEncoder, ViewContext.Writer.Encoding, value)
|
||||
.Append("\"");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
// 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.Text;
|
||||
using Microsoft.AspNet.Mvc.Razor;
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.Framework.Internal;
|
||||
using Microsoft.Framework.WebEncoders;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="TagHelperContent"/>.
|
||||
/// </summary>
|
||||
public static class TagHelperContentExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes the specified <paramref name="value"/> with HTML encoding to given <paramref name="content"/>.
|
||||
/// </summary>
|
||||
/// <param name="content">The <see cref="TagHelperContent"/> to write to.</param>
|
||||
/// <param name="encoder">The <see cref="IHtmlEncoder"/> to use when encoding <paramref name="value"/>.</param>
|
||||
/// <param name="encoding">The character encoding in which the <paramref name="value"/> is written.</param>
|
||||
/// <param name="value">The <see cref="object"/> to write.</param>
|
||||
/// <returns><paramref name="content"/> after the write operation has completed.</returns>
|
||||
/// <remarks>
|
||||
/// <paramref name="value"/>s of type <see cref="Rendering.HtmlString"/> are written without encoding and
|
||||
/// <see cref="HelperResult.WriteTo"/> is invoked for <see cref="HelperResult"/> types. For all other types,
|
||||
/// the encoded result of <see cref="object.ToString"/> is written to the <paramref name="content"/>.
|
||||
/// </remarks>
|
||||
public static TagHelperContent Append(
|
||||
[NotNull] this TagHelperContent content,
|
||||
[NotNull] IHtmlEncoder encoder,
|
||||
[NotNull] Encoding encoding,
|
||||
object value)
|
||||
{
|
||||
using (var writer = new TagHelperContentWrapperTextWriter(encoding, content))
|
||||
{
|
||||
RazorPage.WriteTo(writer, encoder, value, escapeQuotes: true);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.TagHelpers
|
||||
{
|
||||
|
|
@ -24,18 +25,19 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
/// <param name="context">The <see cref="TagHelperContext"/>.</param>
|
||||
/// <remarks>Only copies the attribute if <paramref name="tagHelperOutput"/>'s
|
||||
/// <see cref="TagHelperOutput.Attributes"/> does not contain an attribute with the given
|
||||
/// <paramref name="attributeName"/></remarks>
|
||||
public static void CopyHtmlAttribute(this TagHelperOutput tagHelperOutput,
|
||||
string attributeName,
|
||||
TagHelperContext context)
|
||||
/// <paramref name="attributeName"/>.</remarks>
|
||||
public static void CopyHtmlAttribute(
|
||||
[NotNull] this TagHelperOutput tagHelperOutput,
|
||||
[NotNull] string attributeName,
|
||||
[NotNull] TagHelperContext context)
|
||||
{
|
||||
// We look for the original attribute so we can restore the exact attribute name the user typed.
|
||||
var entry = context.AllAttributes.First(attribute =>
|
||||
attribute.Key.Equals(attributeName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (!tagHelperOutput.Attributes.ContainsKey(entry.Key))
|
||||
if (!tagHelperOutput.Attributes.ContainsKey(attributeName))
|
||||
{
|
||||
tagHelperOutput.Attributes.Add(entry.Key, entry.Value.ToString());
|
||||
// We look for the original attribute so we can restore the exact attribute name the user typed.
|
||||
// Approach also ignores changes made to tagHelperOutput[attributeName].
|
||||
var entry = context.AllAttributes.First(
|
||||
attribute => attribute.Key.Equals(attributeName, StringComparison.OrdinalIgnoreCase));
|
||||
tagHelperOutput.Attributes.Add(entry.Key, entry.Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,8 +49,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
/// <param name="prefix">A prefix to look for.</param>
|
||||
/// <returns><see cref="KeyValuePair{string, string}"/>s with <see cref="KeyValuePair{string, string}.Key"/>
|
||||
/// starting with the given <paramref name="prefix"/>.</returns>
|
||||
public static IEnumerable<KeyValuePair<string, string>> FindPrefixedAttributes(
|
||||
this TagHelperOutput tagHelperOutput, string prefix)
|
||||
public static IEnumerable<KeyValuePair<string, object>> FindPrefixedAttributes(
|
||||
[NotNull] this TagHelperOutput tagHelperOutput,
|
||||
[NotNull] string prefix)
|
||||
{
|
||||
// TODO: https://github.com/aspnet/Razor/issues/89 - We will not need this method once #89 is completed.
|
||||
|
||||
|
|
@ -68,7 +71,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
/// <param name="tagBuilder">The <see cref="TagBuilder"/> to merge attributes from.</param>
|
||||
/// <remarks>Existing <see cref="TagHelperOutput.Attributes"/> on the given <paramref name="tagHelperOutput"/>
|
||||
/// are not overridden; "class" attributes are merged with spaces.</remarks>
|
||||
public static void MergeAttributes(this TagHelperOutput tagHelperOutput, TagBuilder tagBuilder)
|
||||
public static void MergeAttributes(
|
||||
[NotNull] this TagHelperOutput tagHelperOutput,
|
||||
[NotNull] TagBuilder tagBuilder)
|
||||
{
|
||||
foreach (var attribute in tagBuilder.Attributes)
|
||||
{
|
||||
|
|
@ -90,7 +95,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
/// <param name="tagHelperOutput">The <see cref="TagHelperOutput"/> this method extends.</param>
|
||||
/// <param name="attributes">Attributes to remove.</param>
|
||||
public static void RemoveRange(
|
||||
this TagHelperOutput tagHelperOutput, IEnumerable<KeyValuePair<string, string>> attributes)
|
||||
[NotNull] this TagHelperOutput tagHelperOutput,
|
||||
[NotNull] IEnumerable<KeyValuePair<string, object>> attributes)
|
||||
{
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
{
|
||||
return RetrieveAntiForgeryTokens(
|
||||
htmlContent,
|
||||
attribute => attribute.Value.EndsWith(actionUrl, StringComparison.OrdinalIgnoreCase))
|
||||
attribute => attribute.Value.EndsWith(actionUrl, StringComparison.OrdinalIgnoreCase) ||
|
||||
attribute.Value.EndsWith($"HtmlEncode[[{ actionUrl }]]", StringComparison.OrdinalIgnoreCase))
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
|
|
@ -40,8 +41,10 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
{
|
||||
if (input.Attribute("name") != null &&
|
||||
input.Attribute("type") != null &&
|
||||
input.Attribute("name").Value == "__RequestVerificationToken" &&
|
||||
input.Attribute("type").Value == "hidden")
|
||||
(input.Attribute("name").Value == "__RequestVerificationToken" &&
|
||||
input.Attribute("type").Value == "hidden" ||
|
||||
input.Attribute("name").Value == "HtmlEncode[[__RequestVerificationToken]]" &&
|
||||
input.Attribute("type").Value == "HtmlEncode[[hidden]]"))
|
||||
{
|
||||
yield return input.Attributes("value").First().Value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@
|
|||
<html>
|
||||
<body>
|
||||
<div>
|
||||
<a href="">Product Index</a>
|
||||
<a title="<the title>" href="">Product Index</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="">Product List</a>
|
||||
<a title=""the" title" href="">Product List</a>
|
||||
</div>
|
||||
<div>
|
||||
<a id="MvcTagHelperTestIndex" href="/">MvcTagHelperTest Index</a>
|
||||
|
|
|
|||
|
|
@ -7,19 +7,19 @@
|
|||
<title>Link</title>
|
||||
|
||||
<!-- Plain link tag -->
|
||||
<link href="/site.css" rel="stylesheet" />
|
||||
<link href="/site.css" rel="stylesheet" title="<the title>" />
|
||||
|
||||
<!-- Globbed link tag with existing file -->
|
||||
<link rel="stylesheet" href="/site.css" />
|
||||
<link rel="stylesheet" title="<the title>" href="/site.css" />
|
||||
|
||||
<!-- Globbed link tag with existing file and exclude -->
|
||||
<link rel="stylesheet" href="/site.css" /><link rel="stylesheet" href="/sub/site2.css" />
|
||||
<link rel="stylesheet" title=""the" title" href="/site.css" /><link rel="stylesheet" title=""the" title" href="/sub/site2.css" />
|
||||
|
||||
<!-- Globbed link tag missing include -->
|
||||
<link rel="stylesheet" />
|
||||
|
||||
<!-- Globbed link tag missing include but with static href -->
|
||||
<link href="/site.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/site.css" />
|
||||
|
||||
<!-- Globbed link tag with missing file -->
|
||||
|
||||
|
|
@ -31,14 +31,14 @@
|
|||
|
||||
|
||||
<!-- Globbed link tag with existing file and static href -->
|
||||
<link href="/site.css" rel="stylesheet" /><link href="/sub/site2.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/site.css" /><link rel="stylesheet" href="/sub/site2.css" />
|
||||
|
||||
<!-- Globbed link tag with existing file and static href should dedupe -->
|
||||
<link href="/site.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/site.css" />
|
||||
|
||||
<!-- Fallback to static href -->
|
||||
<link href="/site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css"]);</script>
|
||||
<link rel="stylesheet" data-extra="test" title=""the" title" href="/site.min.css?a=b&c=d" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css?a=b\u0026c=d"]);</script>
|
||||
|
||||
<!-- Fallback from globbed href to static href -->
|
||||
|
||||
|
|
@ -49,11 +49,11 @@
|
|||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css"]);</script>
|
||||
|
||||
<!-- Fallback from globbed and static href to static href -->
|
||||
<link href="site.min.css" rel="stylesheet" data-extra="test" /><link href="/site.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="site.min.css" /><link rel="stylesheet" data-extra="test" href="/site.css" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css"]);</script>
|
||||
|
||||
<!-- Fallback from globbed and static href with exclude to static href -->
|
||||
<link href="site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="site.min.css" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css"]);</script>
|
||||
|
||||
<!-- Fallback to static href with no primary href -->
|
||||
|
|
@ -61,19 +61,19 @@
|
|||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css"]);</script>
|
||||
|
||||
<!-- Fallback to globbed href -->
|
||||
<link href="/site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="/site.min.css" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css"]);</script>
|
||||
|
||||
<!-- Fallback to static and globbed href -->
|
||||
<link href="/site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="/site.min.css" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css","\/sub\/site2.css"]);</script>
|
||||
|
||||
<!-- Fallback to static and globbed href should dedupe -->
|
||||
<link href="/site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="/site.min.css" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css"]);</script>
|
||||
|
||||
<!-- Fallback to static and globbed href with exclude -->
|
||||
<link href="/site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="/site.min.css" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css","\/sub\/site2.css"]);</script>
|
||||
|
||||
<!-- Fallback from globbed href to glbobed href -->
|
||||
|
|
@ -85,44 +85,44 @@
|
|||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css"]);</script>
|
||||
|
||||
<!-- Fallback from globbed and static href to globbed href -->
|
||||
<link href="site.min.css" rel="stylesheet" data-extra="test" /><link href="/site.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="site.min.css" /><link rel="stylesheet" data-extra="test" href="/site.css" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css"]);</script>
|
||||
|
||||
<!-- Fallback from globbed and static href with exclude to globbed href -->
|
||||
<link href="site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="site.min.css" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css"]);</script>
|
||||
|
||||
<!-- Kitchen sink, all the attributes -->
|
||||
<link href="site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="site.min.css" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css","\/sub\/site2.css"]);</script>
|
||||
|
||||
<!-- Fallback to globbed href that doesn't exist -->
|
||||
<link href="/site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="/site.min.css" />
|
||||
|
||||
<!-- Fallback to globbed href outside webroot -->
|
||||
<link href="/site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="/site.min.css" />
|
||||
|
||||
<!-- Fallback with missing attribute -->
|
||||
<link href="/site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="/site.min.css" />
|
||||
|
||||
<!-- Fallback with missing attribute -->
|
||||
<link href="/site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="/site.min.css" />
|
||||
|
||||
<!-- Fallback with missing attribute -->
|
||||
<link href="/site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="/site.min.css" />
|
||||
|
||||
<!-- Plain link tag with file version -->
|
||||
<link href="/site.css?v=XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh-pQc" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/site.css?v=XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh-pQc" />
|
||||
|
||||
<!-- Globbed link tag with existing file and file version -->
|
||||
<link rel="stylesheet" href="/site.css?v=XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh-pQc" />
|
||||
|
||||
<!-- Fallback with file version -->
|
||||
<link href="/site.min.css" rel="stylesheet" data-extra="test" />
|
||||
<link rel="stylesheet" data-extra="test" href="/site.min.css" />
|
||||
<meta name="x-stylesheet-fallback-test" class="hidden" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("visibility","hidden",["\/site.css?v=XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh-pQc"]);</script>
|
||||
|
||||
<!-- Globbed link tag with existing file, static href and file version -->
|
||||
<link href="/site.css?v=XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh-pQc" rel="stylesheet" /><link href="/sub/site2.css?v=30cxPex0tA9xEatW7f1Qhnn8tVLAHgE6xwIZhESq0y0" rel="stylesheet" /><link href="/sub/site3.css?v=fSxxOr1Q4Dq2uPuzlju5UYGuK0SKABI-ghvaIGEsZDc" rel="stylesheet" /><link href="/sub/site3.min.css?v=s8JMmAZxBn0dzuhRtQ0wgOvNBK4XRJRWEC2wfzsVF9M" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/site.css?v=XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh-pQc" /><link rel="stylesheet" href="/sub/site2.css?v=30cxPex0tA9xEatW7f1Qhnn8tVLAHgE6xwIZhESq0y0" /><link rel="stylesheet" href="/sub/site3.css?v=fSxxOr1Q4Dq2uPuzlju5UYGuK0SKABI-ghvaIGEsZDc" /><link rel="stylesheet" href="/sub/site3.min.css?v=s8JMmAZxBn0dzuhRtQ0wgOvNBK4XRJRWEC2wfzsVF9M" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,34 +7,34 @@
|
|||
</head>
|
||||
<body>
|
||||
<h2>Script tag helper test</h2>
|
||||
<script src="/site.js" data-foo="foo-data1">
|
||||
<script src="/site.js" data-foo="foo-data1" title="<the title>">
|
||||
// Regular script with comment in body, and extra properties.
|
||||
</script>
|
||||
|
||||
<script src="/blank.js" data-foo="foo-data2">
|
||||
<script data-foo="foo-data2" title="<the title>" src="/blank.js?a=b&c=d">
|
||||
// TagHelper script with comment in body, and extra properties.
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"/site.js\" data-foo=\"foo-data2\"><\/script>"));</script>
|
||||
<script>(false||document.write("<script data-foo=\"foo-data2\" title=\"\u0026lt;the title\u003E\" src=\"\/site.js?a=b\u0026c=d\"><\/script>"));</script>
|
||||
|
||||
<script src="/blank.js">
|
||||
<script title=""the" title" src="/blank.js">
|
||||
// Fallback to globbed src
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"/site.js\"><\/script>"));</script>
|
||||
<script>(false||document.write("<script title=\"\u0022the\u0022 title\" src=\"\/site.js\"><\/script>"));</script>
|
||||
|
||||
<script src="/blank.js">
|
||||
// Fallback to globbed src with exclude
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"/site.js\"><\/script><script src=\"/sub/site2.js\"><\/script>"));</script>
|
||||
<script>(false||document.write("<script src=\"\/site.js\"><\/script><script src=\"\/sub\/site2.js\"><\/script>"));</script>
|
||||
|
||||
<script src="/blank.js">
|
||||
// Fallback to globbed and static src
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"/site.js\"><\/script><script src=\"/sub/site2.js\"><\/script>"));</script>
|
||||
<script>(false||document.write("<script src=\"\/site.js\"><\/script><script src=\"\/sub\/site2.js\"><\/script>"));</script>
|
||||
|
||||
<script src="/blank.js">
|
||||
// Fallback to globbed and static src should de-dupe
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"/site.js\"><\/script>"));</script>
|
||||
<script>(false||document.write("<script src=\"\/site.js\"><\/script>"));</script>
|
||||
|
||||
<script src="/blank.js">
|
||||
// Fallback to globbed src with missing include
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
<script src="/blank.js">
|
||||
// Fallback to static and globbed src with missing include
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"/site.js\"><\/script>"));</script>
|
||||
<script>(false||document.write("<script src=\"\/site.js\"><\/script>"));</script>
|
||||
|
||||
<script src="/blank.js">
|
||||
// Fallback to globbed src outside of webroot
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
<script data-foo="foo-data3">
|
||||
// Valid TagHelper (although no src is provided) script with comment in body, and extra properties.
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"/site.js\" data-foo=\"foo-data3\"><\/script>"));</script>
|
||||
<script>(false||document.write("<script data-foo=\"foo-data3\" src=\"\/site.js\"><\/script>"));</script>
|
||||
|
||||
<script src="/blank.js">
|
||||
// Invalid TagHelper script with comment in body.
|
||||
|
|
@ -96,12 +96,12 @@
|
|||
<script src="/blank.js">
|
||||
// TagHelper script with comment in body, and file version.
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I\"><\/script>"));</script>
|
||||
<script>(false||document.write("<script src=\"\/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I\"><\/script>"));</script>
|
||||
|
||||
<script src="/blank.js">
|
||||
// Fallback to globbed src with file version.
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I\"><\/script>"));</script>
|
||||
<script>(false||document.write("<script src=\"\/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I\"><\/script>"));</script>
|
||||
|
||||
<script src="/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I">
|
||||
// Regular script with comment in body, and file version.
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Mvc.TagHelpers;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.WebEncoders;
|
||||
using MvcTagHelpersWebSite;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -76,6 +77,50 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
Assert.Equal(expectedContent.Trim(), responseContent.Trim());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("EditWarehouse", null)]
|
||||
[InlineData("Index", null)]
|
||||
[InlineData("Link", null)]
|
||||
[InlineData("Order", "/MvcTagHelper_Order/Submit")]
|
||||
[InlineData("OrderUsingHtmlHelpers", "/MvcTagHelper_Order/Submit")]
|
||||
[InlineData("Product", null)]
|
||||
[InlineData("Script", null)]
|
||||
public async Task MvcTagHelpers_GenerateEncodedResults(string action, string antiForgeryPath)
|
||||
{
|
||||
// Arrange
|
||||
var server = TestHelper.CreateServer(_app, SiteName, services =>
|
||||
{
|
||||
_configureServices(services);
|
||||
services.AddTransient<IHtmlEncoder, TestHtmlEncoder>();
|
||||
services.AddTransient<IJavaScriptStringEncoder, TestJavaScriptEncoder>();
|
||||
services.AddTransient<IUrlEncoder, TestUrlEncoder>();
|
||||
});
|
||||
var client = server.CreateClient();
|
||||
var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
|
||||
|
||||
// The K runtime compiles every file under compiler/resources as a resource at runtime with the same name
|
||||
// as the file name, in order to update a baseline you just need to change the file in that folder.
|
||||
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||
"compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Home." + action + ".Encoded.html");
|
||||
|
||||
// Act
|
||||
// The host is not important as everything runs in memory and tests are isolated from each other.
|
||||
var response = await client.GetAsync("http://localhost/MvcTagHelper_Home/" + action);
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
|
||||
|
||||
if (antiForgeryPath != null)
|
||||
{
|
||||
var forgeryToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(responseContent, antiForgeryPath);
|
||||
expectedContent = string.Format(expectedContent, forgeryToken);
|
||||
}
|
||||
|
||||
Assert.Equal(expectedContent.Trim(), responseContent.Trim());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ValidationTagHelpers_GeneratesExpectedSpansAndDivs()
|
||||
{
|
||||
|
|
@ -347,7 +392,7 @@ Products: Laptops (3)";
|
|||
// Arrange
|
||||
var newServices = new ServiceCollection();
|
||||
newServices.InitializeTagHelper<FormTagHelper>((helper, _) => helper.AntiForgery = optionsAntiForgery);
|
||||
var server = TestHelper.CreateServer(_app, SiteName,
|
||||
var server = TestHelper.CreateServer(_app, SiteName,
|
||||
services =>
|
||||
{
|
||||
services.Add(newServices);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<form action="HtmlEncode[[/MvcTagHelper_Home/EditWarehouse]]" method="HtmlEncode[[post]]">
|
||||
<div>
|
||||
HtmlEncode[[City_1]]
|
||||
<input type="HtmlEncode[[text]]" data-val="HtmlEncode[[true]]" data-val-minlength="HtmlEncode[[The field City must be a string or array type with a minimum length of '2'.]]" data-val-minlength-min="HtmlEncode[[2]]" id="HtmlEncode[[City]]" name="HtmlEncode[[City]]" value="HtmlEncode[[City_1]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label>HtmlEncode[[Address]]</label>
|
||||
<textarea id="HtmlEncode[[Employee_Address]]" name="HtmlEncode[[Employee.Address]]">
|
||||
HtmlEncode[[Address_1]]</textarea>;
|
||||
</div>
|
||||
<div>
|
||||
<label for="HtmlEncode[[Employee_Password]]">HtmlEncode[[Password]]</label>
|
||||
<input data-val="HtmlEncode[[true]]" data-val-required="HtmlEncode[[The Password field is required.]]" id="HtmlEncode[[Employee_Password]]" name="HtmlEncode[[Employee.Password]]" type="HtmlEncode[[password]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label>HtmlEncode[[PhoneNumber]]</label>
|
||||
<input id="HtmlEncode[[Employee_PhoneNumber]]" name="HtmlEncode[[Employee.PhoneNumber]]" type="HtmlEncode[[text]]" value="HtmlEncode[[PhoneNumber_1]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="HtmlEncode[[Employee_Name]]">HtmlEncode[[Employee.Name]]</label>
|
||||
<input type="HtmlEncode[[text]]" id="HtmlEncode[[Employee_Name]]" name="HtmlEncode[[Employee.Name]]" value="HtmlEncode[[EmployeeName_1]]" />
|
||||
<span class="HtmlEncode[[field-validation-valid]]" data-valmsg-for="HtmlEncode[[Employee.Name]]" data-valmsg-replace="HtmlEncode[[true]]"></span>
|
||||
</div>
|
||||
<div>
|
||||
<label for="HtmlEncode[[Employee_Gender]]">HtmlEncode[[Gender]]</label>
|
||||
<input checked="HtmlEncode[[checked]]" id="HtmlEncode[[Employee_Gender]]" name="HtmlEncode[[Employee.Gender]]" type="HtmlEncode[[radio]]" value="HtmlEncode[[Female]]" /> Female
|
||||
<input id="HtmlEncode[[Employee_Gender]]" name="HtmlEncode[[Employee.Gender]]" type="HtmlEncode[[radio]]" value="HtmlEncode[[Male]]" /> Male
|
||||
</div>
|
||||
<div>
|
||||
<label for="HtmlEncode[[Employee_OfficeNumber]]">HtmlEncode[[OfficeNumber]]</label>
|
||||
|
||||
<select id="HtmlEncode[[Employee_OfficeNumber]]" name="HtmlEncode[[Employee.OfficeNumber]]"><option>HtmlEncode[[1001]]</option>
|
||||
<option>HtmlEncode[[1002]]</option>
|
||||
</select>
|
||||
</div>
|
||||
<input data-val="HtmlEncode[[true]]" data-val-range="HtmlEncode[[The field Number must be between 1 and 100.]]" data-val-range-max="HtmlEncode[[100]]" data-val-range-min="HtmlEncode[[1]]" id="HtmlEncode[[Employee_Number]]" name="HtmlEncode[[Employee.Number]]" type="HtmlEncode[[hidden]]" value="HtmlEncode[[1]]" />
|
||||
<div class="HtmlEncode[[validation-summary-valid]]" data-valmsg-summary="HtmlEncode[[true]]"><ul><li style="display:none"></li>
|
||||
</ul></div>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<div>
|
||||
<a title="<the title>" href="">Product Index</a>
|
||||
</div>
|
||||
<div>
|
||||
<a title=""the" title" href="">Product List</a>
|
||||
</div>
|
||||
<div>
|
||||
<a id="MvcTagHelperTestIndex" href="HtmlEncode[[/]]">MvcTagHelperTest Index</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="HtmlEncode[[/]]">Default Controller</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="">Product Index Fragment</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="">Produt Submit Fragment</a>
|
||||
</div>
|
||||
<div>
|
||||
<a id="MvcTagHelperTestIndexFragment" href="HtmlEncode[[/#fragment]]">
|
||||
MvcTagHelperTest Index Fragment
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="HtmlEncode[[ftp://localhost/#fragment]]">
|
||||
FTP MvcTagHelperTest Index Fragment
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="">
|
||||
Unknown Protocol Product List
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a id="MvcTagHelperTestIndexProtocol" href="HtmlEncode[[/]]">
|
||||
Empty Protocol MvcTagHelperTest Index
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="">Customer Area Customer Index</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/Order/List">Href Order List</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="">Non-existent Controller</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="">
|
||||
Non-existent Controller Fragment
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="">Non-existent Action</a>
|
||||
</div>
|
||||
<div>
|
||||
<a id="Id" href="HtmlEncode[[http://somewhere/]]">Some Where</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="">
|
||||
Unknown Protocol Non-existent Controller Fragment
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="">Product Route Non-existent Area Parameter</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="">Non-existent Area</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Link</title>
|
||||
|
||||
<!-- Plain link tag -->
|
||||
<link href="HtmlEncode[[/site.css]]" rel="stylesheet" title="<the title>" />
|
||||
|
||||
<!-- Globbed link tag with existing file -->
|
||||
<link rel="stylesheet" title="<the title>" href="HtmlEncode[[/site.css]]" />
|
||||
|
||||
<!-- Globbed link tag with existing file and exclude -->
|
||||
<link rel="stylesheet" title=""the" title" href="HtmlEncode[[/site.css]]" /><link rel="stylesheet" title=""the" title" href="HtmlEncode[[/sub/site2.css]]" />
|
||||
|
||||
<!-- Globbed link tag missing include -->
|
||||
<link rel="stylesheet" />
|
||||
|
||||
<!-- Globbed link tag missing include but with static href -->
|
||||
<link rel="stylesheet" href="HtmlEncode[[/site.css]]" />
|
||||
|
||||
<!-- Globbed link tag with missing file -->
|
||||
|
||||
|
||||
<!-- Globbed link tag with file outside of webroot -->
|
||||
|
||||
|
||||
<!-- Globbed link tag with file outside of webroot -->
|
||||
|
||||
|
||||
<!-- Globbed link tag with existing file and static href -->
|
||||
<link rel="stylesheet" href="HtmlEncode[[/site.css]]" /><link rel="stylesheet" href="HtmlEncode[[/sub/site2.css]]" />
|
||||
|
||||
<!-- Globbed link tag with existing file and static href should dedupe -->
|
||||
<link rel="stylesheet" href="HtmlEncode[[/site.css]]" />
|
||||
|
||||
<!-- Fallback to static href -->
|
||||
<link rel="stylesheet" data-extra="test" title=""the" title" href="HtmlEncode[[/site.min.css?a=b&c=d]]" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css?a=b&c=d]]"]);</script>
|
||||
|
||||
<!-- Fallback from globbed href to static href -->
|
||||
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]"]);</script>
|
||||
|
||||
<!-- Fallback from globbed href with exclude to static href -->
|
||||
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]"]);</script>
|
||||
|
||||
<!-- Fallback from globbed and static href to static href -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[site.min.css]]" /><link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.css]]" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]"]);</script>
|
||||
|
||||
<!-- Fallback from globbed and static href with exclude to static href -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[site.min.css]]" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]"]);</script>
|
||||
|
||||
<!-- Fallback to static href with no primary href -->
|
||||
<link rel="stylesheet" data-extra="test" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]"]);</script>
|
||||
|
||||
<!-- Fallback to globbed href -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.min.css]]" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]"]);</script>
|
||||
|
||||
<!-- Fallback to static and globbed href -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.min.css]]" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]","JavaScriptEncode[[/sub/site2.css]]"]);</script>
|
||||
|
||||
<!-- Fallback to static and globbed href should dedupe -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.min.css]]" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]"]);</script>
|
||||
|
||||
<!-- Fallback to static and globbed href with exclude -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.min.css]]" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]","JavaScriptEncode[[/sub/site2.css]]"]);</script>
|
||||
|
||||
<!-- Fallback from globbed href to glbobed href -->
|
||||
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]"]);</script>
|
||||
|
||||
<!-- Fallback from globbed href with exclude to globbed href -->
|
||||
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]"]);</script>
|
||||
|
||||
<!-- Fallback from globbed and static href to globbed href -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[site.min.css]]" /><link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.css]]" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]"]);</script>
|
||||
|
||||
<!-- Fallback from globbed and static href with exclude to globbed href -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[site.min.css]]" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]"]);</script>
|
||||
|
||||
<!-- Kitchen sink, all the attributes -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[site.min.css]]" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css]]","JavaScriptEncode[[/sub/site2.css]]"]);</script>
|
||||
|
||||
<!-- Fallback to globbed href that doesn't exist -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.min.css]]" />
|
||||
|
||||
<!-- Fallback to globbed href outside webroot -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.min.css]]" />
|
||||
|
||||
<!-- Fallback with missing attribute -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.min.css]]" />
|
||||
|
||||
<!-- Fallback with missing attribute -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.min.css]]" />
|
||||
|
||||
<!-- Fallback with missing attribute -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.min.css]]" />
|
||||
|
||||
<!-- Plain link tag with file version -->
|
||||
<link rel="stylesheet" href="HtmlEncode[[/site.css?v=XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh-pQc]]" />
|
||||
|
||||
<!-- Globbed link tag with existing file and file version -->
|
||||
<link rel="stylesheet" href="HtmlEncode[[/site.css?v=XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh-pQc]]" />
|
||||
|
||||
<!-- Fallback with file version -->
|
||||
<link rel="stylesheet" data-extra="test" href="HtmlEncode[[/site.min.css]]" />
|
||||
<meta name="x-stylesheet-fallback-test" class="HtmlEncode[[hidden]]" /><script>!function(a,b,c){var d,e=document,f=e.getElementsByTagName("SCRIPT"),g=f[f.length-1].previousElementSibling,h=e.defaultView&&e.defaultView.getComputedStyle?e.defaultView.getComputedStyle(g):g.currentStyle;if(h&&h[a]!==b)for(d=0;d<c.length;d++)e.write('<link rel="stylesheet" href="'+c[d]+'"/>')}("JavaScriptEncode[[visibility]]","JavaScriptEncode[[hidden]]",["JavaScriptEncode[[/site.css?v=XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh-pQc]]"]);</script>
|
||||
|
||||
<!-- Globbed link tag with existing file, static href and file version -->
|
||||
<link rel="stylesheet" href="HtmlEncode[[/site.css?v=XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh-pQc]]" /><link rel="stylesheet" href="HtmlEncode[[/sub/site2.css?v=30cxPex0tA9xEatW7f1Qhnn8tVLAHgE6xwIZhESq0y0]]" /><link rel="stylesheet" href="HtmlEncode[[/sub/site3.css?v=fSxxOr1Q4Dq2uPuzlju5UYGuK0SKABI-ghvaIGEsZDc]]" /><link rel="stylesheet" href="HtmlEncode[[/sub/site3.min.css?v=s8JMmAZxBn0dzuhRtQ0wgOvNBK4XRJRWEC2wfzsVF9M]]" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Link Tag Helper Test</h2>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="HtmlEncode[[/MvcTagHelper_Order/Submit]]" method="HtmlEncode[[post]]">
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[Shipping]]">HtmlEncode[[Shipping]]</label>
|
||||
<input size="50" type="HtmlEncode[[text]]" id="HtmlEncode[[Shipping]]" name="HtmlEncode[[Shipping]]" value="HtmlEncode[[Your shipping method is UPSP]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[ShippingDateTime]]">HtmlEncode[[ShippingDateTime]]</label>
|
||||
<input type="HtmlEncode[[datetime-local]]" id="HtmlEncode[[ShippingDateTime]]" name="HtmlEncode[[ShippingDateTime]]" value="HtmlEncode[[01/01/0001 00:00:00]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[Products]]">HtmlEncode[[Products]]</label>
|
||||
|
||||
<select multiple="HtmlEncode[[multiple]]" id="HtmlEncode[[Products]]" name="HtmlEncode[[Products]]"><option selected="HtmlEncode[[selected]]" value="HtmlEncode[[0]]">HtmlEncode[[Product_0]]</option>
|
||||
<option selected="HtmlEncode[[selected]]" value="HtmlEncode[[1]]">HtmlEncode[[Product_1]]</option>
|
||||
<option value="HtmlEncode[[2]]">HtmlEncode[[Product_2]]</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[SubstituteProducts]]">HtmlEncode[[SubstituteProducts]]</label>
|
||||
|
||||
<select id="HtmlEncode[[SubstituteProducts]]" multiple="HtmlEncode[[multiple]]" name="HtmlEncode[[SubstituteProducts]]"><option value="HtmlEncode[[0]]">HtmlEncode[[Product_0]]</option>
|
||||
<option value="HtmlEncode[[1]]">HtmlEncode[[Product_1]]</option>
|
||||
<option selected="HtmlEncode[[selected]]" value="HtmlEncode[[2]]">HtmlEncode[[Product_2]]</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[OrderDate]]">HtmlEncode[[OrderDate]]</label>
|
||||
<input type="HtmlEncode[[datetime]]" id="HtmlEncode[[OrderDate]]" name="HtmlEncode[[OrderDate]]" value="HtmlEncode[[0001/01/01/ A.D.]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[NeedSpecialHandle]]">HtmlEncode[[NeedSpecialHandle]]</label>
|
||||
<input checked="HtmlEncode[[checked]]" id="HtmlEncode[[NeedSpecialHandle]]" name="HtmlEncode[[NeedSpecialHandle]]" type="HtmlEncode[[checkbox]]" value="HtmlEncode[[true]]" /><input name="HtmlEncode[[NeedSpecialHandle]]" type="HtmlEncode[[hidden]]" value="HtmlEncode[[false]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[PaymentMethod]]">HtmlEncode[[PaymentMethod]]</label>
|
||||
<select id="HtmlEncode[[PaymentMethod]]" multiple="HtmlEncode[[multiple]]" name="HtmlEncode[[PaymentMethod]]">
|
||||
<option value="HtmlEncode[[Credit]]">Credit</option>
|
||||
<option value="HtmlEncode[[Check]]" selected="HtmlEncode[[selected]]">Check</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[Customer_Number]]">HtmlEncode[[Number]]</label>
|
||||
<input class="form-control" type="HtmlEncode[[number]]" data-val="HtmlEncode[[true]]" data-val-range="HtmlEncode[[The field Number must be between 1 and 100.]]" data-val-range-max="HtmlEncode[[100]]" data-val-range-min="HtmlEncode[[1]]" id="HtmlEncode[[Customer_Number]]" name="HtmlEncode[[Customer.Number]]" value="HtmlEncode[[1]]" />
|
||||
<span class="HtmlEncode[[field-validation-valid]]" data-valmsg-for="HtmlEncode[[Customer.Number]]" data-valmsg-replace="HtmlEncode[[true]]"></span>
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[Customer_Name]]">HtmlEncode[[Name]]</label>
|
||||
<input type="HtmlEncode[[text]]" id="HtmlEncode[[Customer_Name]]" name="HtmlEncode[[Customer.Name]]" value="HtmlEncode[[NameStringValue]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[Customer_Email]]">HtmlEncode[[Email]]</label>
|
||||
<input type="HtmlEncode[[email]]" id="HtmlEncode[[Customer_Email]]" name="HtmlEncode[[Customer.Email]]" value="" />
|
||||
<span class="HtmlEncode[[field-validation-valid]]" data-valmsg-for="HtmlEncode[[Customer.Email]]" data-valmsg-replace="HtmlEncode[[true]]"></span>
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[Customer_PhoneNumber]]">HtmlEncode[[PhoneNumber]]</label>
|
||||
<input type="HtmlEncode[[tel]]" id="HtmlEncode[[Customer_PhoneNumber]]" name="HtmlEncode[[Customer.PhoneNumber]]" value="" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[Customer_Password]]">HtmlEncode[[Password]]</label>
|
||||
<input class="form-control" type="HtmlEncode[[password]]" data-val="HtmlEncode[[true]]" data-val-required="HtmlEncode[[The Password field is required.]]" id="HtmlEncode[[Customer_Password]]" name="HtmlEncode[[Customer.Password]]" />
|
||||
<span class="HtmlEncode[[field-validation-valid]]" data-valmsg-for="HtmlEncode[[Customer.Password]]" data-valmsg-replace="HtmlEncode[[true]]"></span>
|
||||
</div>
|
||||
<div>
|
||||
<label class="order" for="HtmlEncode[[Customer_Gender]]">HtmlEncode[[Gender]]</label>
|
||||
<input type="HtmlEncode[[radio]]" value="HtmlEncode[[Male]]" id="HtmlEncode[[Customer_Gender]]" name="HtmlEncode[[Customer.Gender]]" /> Male
|
||||
<input type="HtmlEncode[[radio]]" value="HtmlEncode[[Female]]" checked="HtmlEncode[[checked]]" id="HtmlEncode[[Customer_Gender]]" name="HtmlEncode[[Customer.Gender]]" /> Female
|
||||
<span class="HtmlEncode[[field-validation-valid]]" data-valmsg-for="HtmlEncode[[Customer.Gender]]" data-valmsg-replace="HtmlEncode[[true]]"></span>
|
||||
</div>
|
||||
<div class="HtmlEncode[[order validation-summary-valid]]" data-valmsg-summary="HtmlEncode[[true]]"><ul><li style="display:none"></li>
|
||||
</ul></div>
|
||||
<input type="HtmlEncode[[hidden]]" id="HtmlEncode[[Customer_Key]]" name="HtmlEncode[[Customer.Key]]" value="HtmlEncode[[KeyA]]" />
|
||||
<input type="submit" />
|
||||
<input name="HtmlEncode[[__RequestVerificationToken]]" type="HtmlEncode[[hidden]]" value="{0}" /></form>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="HtmlEncode[[/MvcTagHelper_Order/Submit]]" method="HtmlEncode[[post]]">
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[Shipping]]">HtmlEncode[[Shipping]]</label>
|
||||
<input id="HtmlEncode[[Shipping]]" name="HtmlEncode[[Shipping]]" size="HtmlEncode[[50]]" type="HtmlEncode[[text]]" value="HtmlEncode[[Your shipping method is UPSP]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[ShippingDateTime]]">HtmlEncode[[ShippingDateTime]]</label>
|
||||
<input id="HtmlEncode[[ShippingDateTime]]" name="HtmlEncode[[ShippingDateTime]]" type="HtmlEncode[[datetime-local]]" value="HtmlEncode[[01/01/0001 00:00:00]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[Products]]">HtmlEncode[[Products]]</label>
|
||||
|
||||
<select id="HtmlEncode[[Products]]" multiple="HtmlEncode[[multiple]]" name="HtmlEncode[[Products]]"><option selected="HtmlEncode[[selected]]" value="HtmlEncode[[0]]">HtmlEncode[[Product_0]]</option>
|
||||
<option selected="HtmlEncode[[selected]]" value="HtmlEncode[[1]]">HtmlEncode[[Product_1]]</option>
|
||||
<option value="HtmlEncode[[2]]">HtmlEncode[[Product_2]]</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[SubstituteProducts]]">HtmlEncode[[SubstituteProducts]]</label>
|
||||
|
||||
<select id="HtmlEncode[[SubstituteProducts]]" multiple="HtmlEncode[[multiple]]" name="HtmlEncode[[SubstituteProducts]]"><option value="HtmlEncode[[0]]">HtmlEncode[[Product_0]]</option>
|
||||
<option value="HtmlEncode[[1]]">HtmlEncode[[Product_1]]</option>
|
||||
<option selected="HtmlEncode[[selected]]" value="HtmlEncode[[2]]">HtmlEncode[[Product_2]]</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[OrderDate]]">HtmlEncode[[OrderDate]]</label>
|
||||
<input id="HtmlEncode[[OrderDate]]" name="HtmlEncode[[OrderDate]]" type="HtmlEncode[[datetime]]" value="HtmlEncode[[0001/01/01/ A.D.]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[NeedSpecialHandle]]">HtmlEncode[[NeedSpecialHandle]]</label>
|
||||
<input checked="HtmlEncode[[checked]]" id="HtmlEncode[[NeedSpecialHandle]]" name="HtmlEncode[[NeedSpecialHandle]]" type="HtmlEncode[[checkbox]]" value="HtmlEncode[[true]]" /><input name="HtmlEncode[[NeedSpecialHandle]]" type="HtmlEncode[[hidden]]" value="HtmlEncode[[false]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[PaymentMethod]]">HtmlEncode[[PaymentMethod]]</label>
|
||||
<select id="HtmlEncode[[PaymentMethod]]" multiple="HtmlEncode[[multiple]]" name="HtmlEncode[[PaymentMethod]]"><option value="HtmlEncode[[Credit]]">HtmlEncode[[Credit]]</option>
|
||||
<option selected="HtmlEncode[[selected]]" value="HtmlEncode[[Check]]">HtmlEncode[[Check]]</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[Customer_Number]]">HtmlEncode[[Number]]</label>
|
||||
<input class="HtmlEncode[[form-control]]" data-val="HtmlEncode[[true]]" data-val-range="HtmlEncode[[The field Number must be between 1 and 100.]]" data-val-range-max="HtmlEncode[[100]]" data-val-range-min="HtmlEncode[[1]]" id="HtmlEncode[[Customer_Number]]" name="HtmlEncode[[Customer.Number]]" type="HtmlEncode[[number]]" value="HtmlEncode[[1]]" />
|
||||
<span class="HtmlEncode[[field-validation-valid]]" data-valmsg-for="HtmlEncode[[Customer.Number]]" data-valmsg-replace="HtmlEncode[[true]]"></span>
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[Customer_Name]]">HtmlEncode[[Name]]</label>
|
||||
<input id="HtmlEncode[[Customer_Name]]" name="HtmlEncode[[Customer.Name]]" type="HtmlEncode[[text]]" value="HtmlEncode[[NameStringValue]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[Customer_Email]]">HtmlEncode[[Email]]</label>
|
||||
<input id="HtmlEncode[[Customer_Email]]" name="HtmlEncode[[Customer.Email]]" type="HtmlEncode[[email]]" value="" />
|
||||
<span class="HtmlEncode[[field-validation-valid]]" data-valmsg-for="HtmlEncode[[Customer.Email]]" data-valmsg-replace="HtmlEncode[[true]]"></span>
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[Customer_PhoneNumber]]">HtmlEncode[[PhoneNumber]]</label>
|
||||
<input id="HtmlEncode[[Customer_PhoneNumber]]" name="HtmlEncode[[Customer.PhoneNumber]]" type="HtmlEncode[[tel]]" value="" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[Customer_Password]]">HtmlEncode[[Password]]</label>
|
||||
<input class="HtmlEncode[[form-control]]" data-val="HtmlEncode[[true]]" data-val-required="HtmlEncode[[The Password field is required.]]" id="HtmlEncode[[Customer_Password]]" name="HtmlEncode[[Customer.Password]]" type="HtmlEncode[[password]]" />
|
||||
<span class="HtmlEncode[[field-validation-valid]]" data-valmsg-for="HtmlEncode[[Customer.Password]]" data-valmsg-replace="HtmlEncode[[true]]"></span>
|
||||
</div>
|
||||
<div>
|
||||
<label class="HtmlEncode[[order]]" for="HtmlEncode[[Customer_Gender]]">HtmlEncode[[Gender]]</label>
|
||||
<input id="HtmlEncode[[Customer_Gender]]" name="HtmlEncode[[Customer.Gender]]" type="HtmlEncode[[radio]]" value="HtmlEncode[[Male]]" /> Male
|
||||
<input checked="HtmlEncode[[checked]]" id="HtmlEncode[[Customer_Gender]]" name="HtmlEncode[[Customer.Gender]]" type="HtmlEncode[[radio]]" value="HtmlEncode[[Female]]" /> Female
|
||||
<span class="HtmlEncode[[field-validation-valid]]" data-valmsg-for="HtmlEncode[[Customer.Gender]]" data-valmsg-replace="HtmlEncode[[true]]"></span>
|
||||
</div>
|
||||
<div class="HtmlEncode[[validation-summary-valid order]]" data-valmsg-summary="HtmlEncode[[true]]"><ul><li style="display:none"></li>
|
||||
</ul></div>
|
||||
<input id="HtmlEncode[[Customer_Key]]" name="HtmlEncode[[Customer.Key]]" type="HtmlEncode[[hidden]]" value="HtmlEncode[[KeyA]]" />
|
||||
<input type="submit"/>
|
||||
<input name="HtmlEncode[[__RequestVerificationToken]]" type="HtmlEncode[[hidden]]" value="{0}" /></form>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="HtmlEncode[[/MvcTagHelper_Home/ProductSubmit]]" method="get">
|
||||
<div>
|
||||
<label class="product" for="HtmlEncode[[HomePage]]">HtmlEncode[[HomePage]]</label>
|
||||
<input size="50" type="HtmlEncode[[url]]" id="HtmlEncode[[HomePage]]" name="HtmlEncode[[HomePage]]" value="HtmlEncode[[http://www.contoso.com/]]" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="product" for="HtmlEncode[[Description]]">HtmlEncode[[Description]]</label>
|
||||
<textarea rows="4" cols="50" class="product" id="HtmlEncode[[Description]]" name="HtmlEncode[[Description]]">
|
||||
HtmlEncode[[Type the product description]]</textarea>
|
||||
</div>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Script</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Script tag helper test</h2>
|
||||
<script src="HtmlEncode[[/site.js]]" data-foo="foo-data1" title="<the title>">
|
||||
// Regular script with comment in body, and extra properties.
|
||||
</script>
|
||||
|
||||
<script data-foo="foo-data2" title="<the title>" src="HtmlEncode[[/blank.js?a=b&c=d]]">
|
||||
// TagHelper script with comment in body, and extra properties.
|
||||
</script>
|
||||
<script>(false||document.write("<script JavaScriptEncode[[data-foo]]=\"JavaScriptEncode[[foo-data2]]\" JavaScriptEncode[[title]]=\"JavaScriptEncode[[<the title>]]\" src=\"JavaScriptEncode[[/site.js?a=b&c=d]]\"><\/script>"));</script>
|
||||
|
||||
<script title=""the" title" src="HtmlEncode[[/blank.js]]">
|
||||
// Fallback to globbed src
|
||||
</script>
|
||||
<script>(false||document.write("<script JavaScriptEncode[[title]]=\"JavaScriptEncode[["the" title]]\" src=\"JavaScriptEncode[[/site.js]]\"><\/script>"));</script>
|
||||
|
||||
<script src="HtmlEncode[[/blank.js]]">
|
||||
// Fallback to globbed src with exclude
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"JavaScriptEncode[[/site.js]]\"><\/script><script src=\"JavaScriptEncode[[/sub/site2.js]]\"><\/script>"));</script>
|
||||
|
||||
<script src="HtmlEncode[[/blank.js]]">
|
||||
// Fallback to globbed and static src
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"JavaScriptEncode[[/site.js]]\"><\/script><script src=\"JavaScriptEncode[[/sub/site2.js]]\"><\/script>"));</script>
|
||||
|
||||
<script src="HtmlEncode[[/blank.js]]">
|
||||
// Fallback to globbed and static src should de-dupe
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"JavaScriptEncode[[/site.js]]\"><\/script>"));</script>
|
||||
|
||||
<script src="HtmlEncode[[/blank.js]]">
|
||||
// Fallback to globbed src with missing include
|
||||
</script>
|
||||
|
||||
<script src="HtmlEncode[[/blank.js]]">
|
||||
// Fallback to static and globbed src with missing include
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"JavaScriptEncode[[/site.js]]\"><\/script>"));</script>
|
||||
|
||||
<script src="HtmlEncode[[/blank.js]]">
|
||||
// Fallback to globbed src outside of webroot
|
||||
</script>
|
||||
|
||||
<script src="HtmlEncode[[/blank.js]]">
|
||||
// Fallback to globbed src outside of webroot
|
||||
</script>
|
||||
|
||||
<script data-foo="foo-data3">
|
||||
// Valid TagHelper (although no src is provided) script with comment in body, and extra properties.
|
||||
</script>
|
||||
<script>(false||document.write("<script JavaScriptEncode[[data-foo]]=\"JavaScriptEncode[[foo-data3]]\" src=\"JavaScriptEncode[[/site.js]]\"><\/script>"));</script>
|
||||
|
||||
<script src="HtmlEncode[[/blank.js]]">
|
||||
// Invalid TagHelper script with comment in body.
|
||||
</script>
|
||||
|
||||
<!-- Globbed script tag with existing file -->
|
||||
<script src="HtmlEncode[[/site.js]]"></script>
|
||||
|
||||
<!-- Globbed script tag with existing file and exclude -->
|
||||
<script src="HtmlEncode[[/site.js]]"></script><script src="HtmlEncode[[/sub/site2.js]]"></script>
|
||||
|
||||
<script>
|
||||
// Globbed script tag missing include
|
||||
</script>
|
||||
|
||||
<script src="HtmlEncode[[/site.js]]">
|
||||
// Globbed script tag missing include but with static src
|
||||
</script>
|
||||
|
||||
<!-- Globbed script tag with missing file -->
|
||||
|
||||
|
||||
<!-- Globbed script tag with file outside of webroot -->
|
||||
|
||||
|
||||
<!-- Globbed script tag with file outside of webroot -->
|
||||
|
||||
|
||||
<script src="HtmlEncode[[/site.js]]">
|
||||
// Globbed script tag with existing file and static src
|
||||
</script><script src="HtmlEncode[[/sub/site2.js]]"></script>
|
||||
|
||||
<script src="HtmlEncode[[/site.js]]">
|
||||
// Globbed script tag with existing file and static src should dedupe
|
||||
</script>
|
||||
|
||||
<script src="HtmlEncode[[/blank.js]]">
|
||||
// TagHelper script with comment in body, and file version.
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"JavaScriptEncode[[/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I]]\"><\/script>"));</script>
|
||||
|
||||
<script src="HtmlEncode[[/blank.js]]">
|
||||
// Fallback to globbed src with file version.
|
||||
</script>
|
||||
<script>(false||document.write("<script src=\"JavaScriptEncode[[/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I]]\"><\/script>"));</script>
|
||||
|
||||
<script src="HtmlEncode[[/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I]]">
|
||||
// Regular script with comment in body, and file version.
|
||||
</script>
|
||||
|
||||
<!-- Globbed script tag with existing files and version -->
|
||||
<script src="HtmlEncode[[/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I]]"></script><script src="HtmlEncode[[/sub/site2.js?v=pwJaxaQxnb-rPAdF2JlAp4xiPNq1XuJFd6TyOOfNF-0]]"></script><script src="HtmlEncode[[/sub/site3.js?v=lmeAMiqm76lnGyqHhu6PIBHAC0Vt46mgVB_KaG_gGdA]]"></script>
|
||||
|
||||
<!-- Globbed script tag with existing file, exclude and version -->
|
||||
<script src="HtmlEncode[[/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I]]"></script><script src="HtmlEncode[[/sub/site2.js?v=pwJaxaQxnb-rPAdF2JlAp4xiPNq1XuJFd6TyOOfNF-0]]"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -32,6 +32,7 @@
|
|||
"LoggingWebSite": "1.0.0",
|
||||
"LowercaseUrlsWebSite": "1.0.0-*",
|
||||
"Microsoft.AspNet.Mvc": "6.0.0-*",
|
||||
"Microsoft.AspNet.Mvc.TestCommon": { "version": "6.0.0-*", "type": "build" },
|
||||
"Microsoft.AspNet.Mvc.TestConfiguration": "1.0.0",
|
||||
"Microsoft.AspNet.Mvc.Xml": "6.0.0-*",
|
||||
"Microsoft.AspNet.TestHost": "1.0.0-*",
|
||||
|
|
|
|||
|
|
@ -658,9 +658,10 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
// Assert
|
||||
var buffer = writer.BufferedWriter.Buffer;
|
||||
Assert.Equal(2, buffer.BufferEntries.Count);
|
||||
Assert.Equal(3, buffer.BufferEntries.Count);
|
||||
Assert.Equal("Hello world", buffer.BufferEntries[0]);
|
||||
Assert.Same(stringCollectionWriter.Buffer.BufferEntries, buffer.BufferEntries[1]);
|
||||
Assert.Equal("text1", buffer.BufferEntries[1]);
|
||||
Assert.Equal("text2", buffer.BufferEntries[2]);
|
||||
}
|
||||
|
||||
public static TheoryData<TagHelperOutput, string> WriteTagHelper_InputData
|
||||
|
|
@ -672,21 +673,21 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
{
|
||||
// parameters: TagName, Attributes, SelfClosing, PreContent, Content, PostContent
|
||||
GetTagHelperOutput("div", new Dictionary<string, string>(), false, null, "Hello World!", null),
|
||||
GetTagHelperOutput("div", new Dictionary<string, object>(), false, null, "Hello World!", null),
|
||||
"<div>Hello World!</div>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(null, new Dictionary<string, string>(), false, null, "Hello World!", null),
|
||||
GetTagHelperOutput(null, new Dictionary<string, object>(), false, null, "Hello World!", null),
|
||||
"Hello World!"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(" ", new Dictionary<string, string>(), false, null, "Hello World!", null),
|
||||
GetTagHelperOutput(" ", new Dictionary<string, object>(), false, null, "Hello World!", null),
|
||||
"Hello World!"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
"p",
|
||||
new Dictionary<string, string>() { { "test", "testVal" } },
|
||||
new Dictionary<string, object>() { { "test", "testVal" } },
|
||||
false,
|
||||
null,
|
||||
"Hello World!",
|
||||
|
|
@ -696,7 +697,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
GetTagHelperOutput(
|
||||
"p",
|
||||
new Dictionary<string, string>() { { "test", "testVal" }, { "something", " spaced " } },
|
||||
new Dictionary<string, object>() { { "test", "testVal" }, { "something", " spaced " } },
|
||||
false,
|
||||
null,
|
||||
"Hello World!",
|
||||
|
|
@ -706,7 +707,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
GetTagHelperOutput(
|
||||
"p",
|
||||
new Dictionary<string, string>() { { "test", "testVal" } },
|
||||
new Dictionary<string, object>() { { "test", "testVal" } },
|
||||
true,
|
||||
null,
|
||||
"Hello World!",
|
||||
|
|
@ -716,7 +717,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
GetTagHelperOutput(
|
||||
"p",
|
||||
new Dictionary<string, string>() { { "test", "testVal" }, { "something", " spaced " } },
|
||||
new Dictionary<string, object>() { { "test", "testVal" }, { "something", " spaced " } },
|
||||
true,
|
||||
null,
|
||||
"Hello World!",
|
||||
|
|
@ -724,31 +725,31 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
"<p test=\"testVal\" something=\" spaced \" />"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput("p", new Dictionary<string, string>(), false, "Hello World!", null, null),
|
||||
GetTagHelperOutput("p", new Dictionary<string, object>(), false, "Hello World!", null, null),
|
||||
"<p>Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput("p", new Dictionary<string, string>(), false, null, "Hello World!", null),
|
||||
GetTagHelperOutput("p", new Dictionary<string, object>(), false, null, "Hello World!", null),
|
||||
"<p>Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput("p", new Dictionary<string, string>(), false, null, null, "Hello World!"),
|
||||
GetTagHelperOutput("p", new Dictionary<string, object>(), false, null, null, "Hello World!"),
|
||||
"<p>Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput("p", new Dictionary<string, string>(), false, "Hello", "Test", "World!"),
|
||||
GetTagHelperOutput("p", new Dictionary<string, object>(), false, "Hello", "Test", "World!"),
|
||||
"<p>HelloTestWorld!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput("p", new Dictionary<string, string>(), true, "Hello", "Test", "World!"),
|
||||
GetTagHelperOutput("p", new Dictionary<string, object>(), true, "Hello", "Test", "World!"),
|
||||
"<p />"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput("custom", new Dictionary<string, string>(), false, "Hello", "Test", "World!"),
|
||||
GetTagHelperOutput("custom", new Dictionary<string, object>(), false, "Hello", "Test", "World!"),
|
||||
"<custom>HelloTestWorld!</custom>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput("random", new Dictionary<string, string>(), true, "Hello", "Test", "World!"),
|
||||
GetTagHelperOutput("random", new Dictionary<string, object>(), true, "Hello", "Test", "World!"),
|
||||
"<random />"
|
||||
}
|
||||
};
|
||||
|
|
@ -807,8 +808,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
},
|
||||
startTagHelperWritingScope: () => { },
|
||||
endTagHelperWritingScope: () => defaultTagHelperContent);
|
||||
tagHelperExecutionContext.Output =
|
||||
new TagHelperOutput("p", new Dictionary<string, string>());
|
||||
tagHelperExecutionContext.Output = new TagHelperOutput("p", new Dictionary<string, object>());
|
||||
if (childContentRetrieved)
|
||||
{
|
||||
await tagHelperExecutionContext.GetChildContentAsync();
|
||||
|
|
@ -840,8 +840,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
executeChildContentAsync: () => { return Task.FromResult(result: true); },
|
||||
startTagHelperWritingScope: () => { },
|
||||
endTagHelperWritingScope: () => new DefaultTagHelperContent());
|
||||
tagHelperExecutionContext.Output =
|
||||
new TagHelperOutput("p", new Dictionary<string, string>());
|
||||
tagHelperExecutionContext.Output = new TagHelperOutput("p", new Dictionary<string, object>());
|
||||
tagHelperExecutionContext.Output.Content.SetContent("Hello World!");
|
||||
|
||||
// Act
|
||||
|
|
@ -886,7 +885,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
private static TagHelperOutput GetTagHelperOutput(
|
||||
string tagName,
|
||||
IDictionary<string, string> attributes,
|
||||
IDictionary<string, object> attributes,
|
||||
bool selfClosing,
|
||||
string preContent,
|
||||
string content,
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
var output = new TagHelperOutput(
|
||||
expectedTagName,
|
||||
attributes: new Dictionary<string, string>
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
{ "id", "myanchor" },
|
||||
{ "asp-route-foo", "bar" },
|
||||
|
|
@ -97,7 +97,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
var output = new TagHelperOutput(
|
||||
"a",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
output.Content.SetContent(string.Empty);
|
||||
|
||||
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
||||
|
|
@ -139,7 +139,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
var output = new TagHelperOutput(
|
||||
"a",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
output.Content.SetContent(string.Empty);
|
||||
|
||||
var generator = new Mock<IHtmlGenerator>();
|
||||
|
|
@ -180,7 +180,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var anchorTagHelper = new AnchorTagHelper();
|
||||
var output = new TagHelperOutput(
|
||||
"a",
|
||||
attributes: new Dictionary<string, string>()
|
||||
attributes: new Dictionary<string, object>()
|
||||
{
|
||||
{ "href", "http://www.contoso.com" }
|
||||
});
|
||||
|
|
@ -218,7 +218,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
typeof(AnchorTagHelper).GetProperty(propertyName).SetValue(anchorTagHelper, "Home");
|
||||
var output = new TagHelperOutput(
|
||||
"a",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
var expectedErrorMessage = "Cannot determine an 'href' attribute for <a>. An <a> with a specified " +
|
||||
"'asp-route' must not have an 'asp-action' or 'asp-controller' attribute.";
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ using Microsoft.AspNet.Routing;
|
|||
using Microsoft.Framework.Caching.Memory;
|
||||
using Microsoft.Framework.Caching.Memory.Infrastructure;
|
||||
using Microsoft.Framework.Expiration.Interfaces;
|
||||
using Microsoft.Framework.WebEncoders;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -245,7 +244,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var childContent = "original-child-content";
|
||||
var cache = new MemoryCache(new MemoryCacheOptions());
|
||||
var tagHelperContext1 = GetTagHelperContext(id, childContent);
|
||||
var tagHelperOutput1 = new TagHelperOutput("cache", new Dictionary<string, string>());
|
||||
var tagHelperOutput1 = new TagHelperOutput("cache", new Dictionary<string, object>());
|
||||
var cacheTagHelper1 = new CacheTagHelper
|
||||
{
|
||||
VaryByQuery = "key1,key2",
|
||||
|
|
@ -266,7 +265,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
// Arrange - 2
|
||||
var tagHelperContext2 = GetTagHelperContext(id, "different-content");
|
||||
var tagHelperOutput2 = new TagHelperOutput("cache", new Dictionary<string, string>());
|
||||
var tagHelperOutput2 = new TagHelperOutput("cache", new Dictionary<string, object>());
|
||||
var cacheTagHelper2 = new CacheTagHelper
|
||||
{
|
||||
VaryByQuery = "key1,key2",
|
||||
|
|
@ -295,7 +294,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var cache = new MemoryCache(new MemoryCacheOptions());
|
||||
var tagHelperContext1 = GetTagHelperContext(id, childContent1);
|
||||
var tagHelperOutput1 = new TagHelperOutput("cache",
|
||||
new Dictionary<string, string> { { "attr", "value" } });
|
||||
new Dictionary<string, object> { { "attr", "value" } });
|
||||
tagHelperOutput1.PreContent.Append("<cache>");
|
||||
tagHelperOutput1.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper1 = new CacheTagHelper
|
||||
|
|
@ -320,7 +319,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var tagHelperContext2 = GetTagHelperContext(id, childContent2);
|
||||
var tagHelperOutput2 = new TagHelperOutput(
|
||||
"cache",
|
||||
new Dictionary<string, string> { { "attr", "value" } });
|
||||
new Dictionary<string, object> { { "attr", "value" } });
|
||||
tagHelperOutput2.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput2.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper2 = new CacheTagHelper
|
||||
|
|
@ -530,7 +529,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var cache = new MemoryCache(new MemoryCacheOptions { Clock = clock.Object });
|
||||
var tagHelperContext1 = GetTagHelperContext(id, childContent1);
|
||||
var tagHelperOutput1 = new TagHelperOutput("cache",
|
||||
new Dictionary<string, string> { { "attr", "value" } });
|
||||
new Dictionary<string, object> { { "attr", "value" } });
|
||||
tagHelperOutput1.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput1.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper1 = new CacheTagHelper
|
||||
|
|
@ -553,7 +552,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var childContent2 = "different-content";
|
||||
var tagHelperContext2 = GetTagHelperContext(id, childContent2);
|
||||
var tagHelperOutput2 = new TagHelperOutput("cache",
|
||||
new Dictionary<string, string> { { "attr", "value" } });
|
||||
new Dictionary<string, object> { { "attr", "value" } });
|
||||
tagHelperOutput2.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput2.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper2 = new CacheTagHelper
|
||||
|
|
@ -587,7 +586,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var cache = new MemoryCache(new MemoryCacheOptions { Clock = clock.Object });
|
||||
var tagHelperContext1 = GetTagHelperContext(id, childContent1);
|
||||
var tagHelperOutput1 = new TagHelperOutput("cache",
|
||||
new Dictionary<string, string> { { "attr", "value" } });
|
||||
new Dictionary<string, object> { { "attr", "value" } });
|
||||
tagHelperOutput1.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput1.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper1 = new CacheTagHelper
|
||||
|
|
@ -611,7 +610,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var childContent2 = "different-content";
|
||||
var tagHelperContext2 = GetTagHelperContext(id, childContent2);
|
||||
var tagHelperOutput2 = new TagHelperOutput("cache",
|
||||
new Dictionary<string, string> { { "attr", "value" } });
|
||||
new Dictionary<string, object> { { "attr", "value" } });
|
||||
tagHelperOutput2.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput2.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper2 = new CacheTagHelper
|
||||
|
|
@ -644,7 +643,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var cache = new MemoryCache(new MemoryCacheOptions { Clock = clock.Object });
|
||||
var tagHelperContext1 = GetTagHelperContext(id, childContent1);
|
||||
var tagHelperOutput1 = new TagHelperOutput("cache",
|
||||
new Dictionary<string, string> { { "attr", "value" } });
|
||||
new Dictionary<string, object> { { "attr", "value" } });
|
||||
tagHelperOutput1.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput1.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper1 = new CacheTagHelper
|
||||
|
|
@ -668,7 +667,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var childContent2 = "different-content";
|
||||
var tagHelperContext2 = GetTagHelperContext(id, childContent2);
|
||||
var tagHelperOutput2 = new TagHelperOutput("cache",
|
||||
new Dictionary<string, string> { { "attr", "value" } });
|
||||
new Dictionary<string, object> { { "attr", "value" } });
|
||||
tagHelperOutput2.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput2.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper2 = new CacheTagHelper
|
||||
|
|
@ -712,7 +711,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
return Task.FromResult<TagHelperContent>(expectedContent);
|
||||
});
|
||||
var tagHelperOutput = new TagHelperOutput("cache",
|
||||
new Dictionary<string, string> { { "attr", "value" } });
|
||||
new Dictionary<string, object> { { "attr", "value" } });
|
||||
tagHelperOutput.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper = new CacheTagHelper
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Hosting;
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.Framework.WebEncoders;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -147,9 +146,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers.Test
|
|||
});
|
||||
}
|
||||
|
||||
private TagHelperOutput MakeTagHelperOutput(string tagName, IDictionary<string, string> attributes = null)
|
||||
private TagHelperOutput MakeTagHelperOutput(string tagName, IDictionary<string, object> attributes = null)
|
||||
{
|
||||
attributes = attributes ?? new Dictionary<string, string>();
|
||||
attributes = attributes ?? new Dictionary<string, object>();
|
||||
|
||||
return new TagHelperOutput(tagName, attributes);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ using Microsoft.AspNet.Mvc.ModelBinding;
|
|||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Microsoft.Framework.WebEncoders;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
@ -45,7 +44,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
var output = new TagHelperOutput(
|
||||
expectedTagName,
|
||||
attributes: new Dictionary<string, string>
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
{ "id", "myform" },
|
||||
{ "asp-route-foo", "bar" },
|
||||
|
|
@ -67,7 +66,6 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
AntiForgery = true,
|
||||
Controller = "home",
|
||||
Generator = htmlGenerator,
|
||||
Method = "post",
|
||||
ViewContext = viewContext,
|
||||
};
|
||||
|
||||
|
|
@ -110,7 +108,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
var output = new TagHelperOutput(
|
||||
"form",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
||||
generator
|
||||
.Setup(mock => mock.GenerateForm(
|
||||
|
|
@ -159,10 +157,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
var expectedAttribute = new KeyValuePair<string, string>("asp-ROUTEE-NotRoute", "something");
|
||||
var expectedAttribute = new KeyValuePair<string, object>("asp-ROUTEE-NotRoute", "something");
|
||||
var output = new TagHelperOutput(
|
||||
"form",
|
||||
attributes: new Dictionary<string, string>()
|
||||
attributes: new Dictionary<string, object>()
|
||||
{
|
||||
{ "asp-route-val", "hello" },
|
||||
{ "asp-roUte--Foo", "bar" }
|
||||
|
|
@ -232,10 +230,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
var output = new TagHelperOutput(
|
||||
"form",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
||||
generator
|
||||
.Setup(mock => mock.GenerateForm(viewContext, "Index", "Home", null, "POST", null))
|
||||
.Setup(mock => mock.GenerateForm(viewContext, "Index", "Home", null, null, null))
|
||||
.Returns(new TagBuilder("form", new HtmlEncoder()))
|
||||
.Verifiable();
|
||||
var formTagHelper = new FormTagHelper
|
||||
|
|
@ -244,7 +242,6 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
AntiForgery = false,
|
||||
Controller = "Home",
|
||||
Generator = generator.Object,
|
||||
Method = "POST",
|
||||
ViewContext = viewContext,
|
||||
};
|
||||
|
||||
|
|
@ -260,52 +257,6 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Assert.Empty(output.PostContent.GetContent());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("my-action")]
|
||||
[InlineData("http://www.contoso.com")]
|
||||
[InlineData("my/action")]
|
||||
public async Task ProcessAsync_RestoresBoundAttributesIfActionIsSpecified(string htmlAction)
|
||||
{
|
||||
// Arrange
|
||||
var formTagHelper = new FormTagHelper
|
||||
{
|
||||
Method = "POST"
|
||||
};
|
||||
var output = new TagHelperOutput("form",
|
||||
attributes: new Dictionary<string, string>
|
||||
{
|
||||
{ "aCTiON", htmlAction },
|
||||
});
|
||||
|
||||
var context = new TagHelperContext(
|
||||
allAttributes: new Dictionary<string, object>()
|
||||
{
|
||||
{ "METhod", "POST" }
|
||||
},
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test",
|
||||
getChildContentAsync: () =>
|
||||
{
|
||||
var tagHelperContent = new DefaultTagHelperContent();
|
||||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
|
||||
// Act
|
||||
await formTagHelper.ProcessAsync(context, output);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("form", output.TagName);
|
||||
Assert.Equal(2, output.Attributes.Count);
|
||||
var attribute = Assert.Single(output.Attributes, kvp => kvp.Key.Equals("aCTiON"));
|
||||
Assert.Equal(htmlAction, attribute.Value);
|
||||
attribute = Assert.Single(output.Attributes, kvp => kvp.Key.Equals("METhod"));
|
||||
Assert.Equal("POST", attribute.Value);
|
||||
Assert.Empty(output.PreContent.GetContent());
|
||||
Assert.True(output.Content.IsEmpty);
|
||||
Assert.Empty(output.PostContent.GetContent());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, "<input />")]
|
||||
[InlineData(false, "")]
|
||||
|
|
@ -328,7 +279,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
};
|
||||
|
||||
var output = new TagHelperOutput("form",
|
||||
attributes: new Dictionary<string, string>
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
{ "aCTiON", "my-action" },
|
||||
});
|
||||
|
|
@ -351,7 +302,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Assert.Equal("form", output.TagName);
|
||||
Assert.False(output.SelfClosing);
|
||||
var attribute = Assert.Single(output.Attributes);
|
||||
Assert.Equal(new KeyValuePair<string, string>("aCTiON", "my-action"), attribute);
|
||||
Assert.Equal(new KeyValuePair<string, object>("aCTiON", "my-action"), attribute);
|
||||
Assert.Empty(output.PreContent.GetContent());
|
||||
Assert.True(output.Content.IsEmpty);
|
||||
Assert.Equal(expectedPostContent, output.PostContent.GetContent());
|
||||
|
|
@ -364,13 +315,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
public async Task ProcessAsync_ThrowsIfActionConflictsWithBoundAttributes(string propertyName)
|
||||
{
|
||||
// Arrange
|
||||
var formTagHelper = new FormTagHelper
|
||||
{
|
||||
Method = "POST"
|
||||
};
|
||||
var formTagHelper = new FormTagHelper();
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"form",
|
||||
attributes: new Dictionary<string, string>
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
{ "action", "my-action" },
|
||||
});
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string expectedValue)
|
||||
{
|
||||
// Arrange
|
||||
var expectedAttributes = new Dictionary<string, string>
|
||||
var expectedAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
{ "type", "text" },
|
||||
|
|
@ -105,7 +105,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
};
|
||||
|
|
@ -166,7 +166,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
};
|
||||
|
|
@ -242,7 +242,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
contextAttributes["type"] = inputTypeName; // Support restoration of type attribute, if any.
|
||||
}
|
||||
|
||||
var expectedAttributes = new Dictionary<string, string>
|
||||
var expectedAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control hidden-control" },
|
||||
{ "type", inputTypeName ?? "hidden" }, // Generator restores type attribute; adds "hidden" if none.
|
||||
|
|
@ -262,7 +262,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
};
|
||||
|
|
@ -341,7 +341,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
contextAttributes["type"] = inputTypeName; // Support restoration of type attribute, if any.
|
||||
}
|
||||
|
||||
var expectedAttributes = new Dictionary<string, string>
|
||||
var expectedAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control password-control" },
|
||||
{ "type", inputTypeName ?? "password" }, // Generator restores type attribute; adds "password" if none.
|
||||
|
|
@ -361,7 +361,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
};
|
||||
|
|
@ -436,7 +436,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
contextAttributes["type"] = inputTypeName; // Support restoration of type attribute, if any.
|
||||
}
|
||||
|
||||
var expectedAttributes = new Dictionary<string, string>
|
||||
var expectedAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control radio-control" },
|
||||
{ "type", inputTypeName ?? "radio" }, // Generator restores type attribute; adds "radio" if none.
|
||||
|
|
@ -457,7 +457,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
};
|
||||
|
|
@ -542,7 +542,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
contextAttributes["type"] = inputTypeName; // Support restoration of type attribute, if any.
|
||||
}
|
||||
|
||||
var expectedAttributes = new Dictionary<string, string>
|
||||
var expectedAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control text-control" },
|
||||
{ "type", inputTypeName ?? "text" }, // Generator restores type attribute; adds "text" if none.
|
||||
|
|
@ -562,7 +562,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.Framework.WebEncoders;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.TagHelpers
|
||||
|
|
@ -165,7 +164,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var expectedTagName = "not-label";
|
||||
var expectedAttributes = new Dictionary<string, string>
|
||||
var expectedAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
{ "for", tagHelperOutputContent.ExpectedId }
|
||||
|
|
@ -196,7 +195,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
tagHelperContent.SetContent(tagHelperOutputContent.OriginalChildContent);
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
var htmlAttributes = new Dictionary<string, string>
|
||||
var htmlAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var helper = new LinkTagHelper
|
||||
{
|
||||
HtmlEncoder = new HtmlEncoder(),
|
||||
JavaScriptEncoder = new JavaScriptStringEncoder(),
|
||||
Logger = logger.Object,
|
||||
HostingEnvironment = hostingEnvironment,
|
||||
ViewContext = viewContext,
|
||||
|
|
@ -202,8 +203,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var context = MakeTagHelperContext(
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
["rel"] = "stylesheet",
|
||||
["data-extra"] = "something",
|
||||
["rel"] = new HtmlString("stylesheet"),
|
||||
["data-extra"] = new HtmlString("something"),
|
||||
["href"] = "test.css",
|
||||
["asp-fallback-href"] = "test.css",
|
||||
["asp-fallback-test-class"] = "hidden",
|
||||
|
|
@ -211,11 +212,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
["asp-fallback-test-value"] = "hidden"
|
||||
});
|
||||
var output = MakeTagHelperOutput("link",
|
||||
attributes: new Dictionary<string, string>
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
["rel"] = "stylesheet",
|
||||
["data-extra"] = "something",
|
||||
["href"] = "test.css"
|
||||
["rel"] = new HtmlString("stylesheet"),
|
||||
["data-extra"] = new HtmlString("something"),
|
||||
});
|
||||
var logger = new Mock<ILogger<LinkTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
|
|
@ -223,6 +223,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var helper = new LinkTagHelper
|
||||
{
|
||||
HtmlEncoder = new HtmlEncoder(),
|
||||
JavaScriptEncoder = new JavaScriptStringEncoder(),
|
||||
Logger = logger.Object,
|
||||
HostingEnvironment = hostingEnvironment,
|
||||
ViewContext = viewContext,
|
||||
|
|
@ -230,6 +231,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
FallbackTestClass = "hidden",
|
||||
FallbackTestProperty = "visibility",
|
||||
FallbackTestValue = "hidden",
|
||||
Href = "test.css",
|
||||
Cache = MakeCache(),
|
||||
};
|
||||
|
||||
|
|
@ -374,14 +376,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var context = MakeTagHelperContext(
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
["rel"] = new HtmlString("stylesheet"),
|
||||
["href"] = "/css/site.css",
|
||||
["rel"] = "stylesheet",
|
||||
["asp-href-include"] = "**/*.css"
|
||||
});
|
||||
var output = MakeTagHelperOutput("link", attributes: new Dictionary<string, string>
|
||||
var output = MakeTagHelperOutput("link", attributes: new Dictionary<string, object>
|
||||
{
|
||||
["href"] = "/css/site.css",
|
||||
["rel"] = "stylesheet"
|
||||
["rel"] = new HtmlString("stylesheet"),
|
||||
});
|
||||
var logger = new Mock<ILogger<LinkTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
|
|
@ -396,6 +397,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Logger = logger.Object,
|
||||
HostingEnvironment = hostingEnvironment,
|
||||
ViewContext = viewContext,
|
||||
Href = "/css/site.css",
|
||||
HrefInclude = "**/*.css",
|
||||
Cache = MakeCache(),
|
||||
};
|
||||
|
|
@ -404,8 +406,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
helper.Process(context, output);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("<link href=\"/css/site.css\" rel=\"stylesheet\" />" +
|
||||
"<link href=\"/base.css\" rel=\"stylesheet\" />", output.Content.GetContent());
|
||||
Assert.Equal(
|
||||
"<link rel=\"stylesheet\" href=\"/css/site.css\" />" +
|
||||
"<link rel=\"stylesheet\" href=\"/base.css\" />",
|
||||
output.Content.GetContent());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -415,14 +419,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var context = MakeTagHelperContext(
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
["href"] = "/css/site.css",
|
||||
["rel"] = "stylesheet",
|
||||
["href"] = "/css/site.css",
|
||||
["asp-href-include"] = "**/*.css"
|
||||
});
|
||||
var output = MakeTagHelperOutput("link", attributes: new Dictionary<string, string>
|
||||
var output = MakeTagHelperOutput("link", attributes: new Dictionary<string, object>
|
||||
{
|
||||
["href"] = "/css/site.css",
|
||||
["rel"] = "stylesheet"
|
||||
["rel"] = "stylesheet",
|
||||
});
|
||||
var logger = new Mock<ILogger<LinkTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
|
|
@ -437,6 +440,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Logger = logger.Object,
|
||||
HostingEnvironment = hostingEnvironment,
|
||||
ViewContext = viewContext,
|
||||
Href = "/css/site.css",
|
||||
HrefInclude = "**/*.css",
|
||||
Cache = MakeCache(),
|
||||
};
|
||||
|
|
@ -445,8 +449,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
helper.Process(context, output);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("<link href=\"HtmlEncode[[/css/site.css]]\" rel=\"stylesheet\" />" +
|
||||
"<link href=\"HtmlEncode[[/base.css]]\" rel=\"stylesheet\" />", output.Content.GetContent());
|
||||
Assert.Equal(
|
||||
"<link rel=\"HtmlEncode[[stylesheet]]\" href=\"HtmlEncode[[/css/site.css]]\" />" +
|
||||
"<link rel=\"HtmlEncode[[stylesheet]]\" href=\"HtmlEncode[[/base.css]]\" />",
|
||||
output.Content.GetContent());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -456,14 +462,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var context = MakeTagHelperContext(
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
["rel"] = new HtmlString("stylesheet"),
|
||||
["href"] = "/css/site.css",
|
||||
["rel"] = "stylesheet",
|
||||
["asp-file-version"] = "true"
|
||||
});
|
||||
var output = MakeTagHelperOutput("link", attributes: new Dictionary<string, string>
|
||||
var output = MakeTagHelperOutput("link", attributes: new Dictionary<string, object>
|
||||
{
|
||||
["href"] = "/css/site.css",
|
||||
["rel"] = "stylesheet"
|
||||
["rel"] = new HtmlString("stylesheet"),
|
||||
});
|
||||
var logger = new Mock<ILogger<LinkTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
|
|
@ -474,6 +479,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Logger = logger.Object,
|
||||
HostingEnvironment = hostingEnvironment,
|
||||
ViewContext = viewContext,
|
||||
Href = "/css/site.css",
|
||||
HrefInclude = "**/*.css",
|
||||
FileVersion = true,
|
||||
Cache = MakeCache(),
|
||||
|
|
@ -483,8 +489,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
helper.Process(context, output);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("<link href=\"HtmlEncode[[/css/site.css?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk]]\"" +
|
||||
" rel=\"stylesheet\" />", output.Content.GetContent());
|
||||
Assert.Equal(
|
||||
"<link rel=\"stylesheet\" href=\"HtmlEncode[[/css/site.css?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk]]\" />",
|
||||
output.Content.GetContent());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -494,14 +501,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var context = MakeTagHelperContext(
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
["rel"] = new HtmlString("stylesheet"),
|
||||
["href"] = "/bar/css/site.css",
|
||||
["rel"] = "stylesheet",
|
||||
["asp-file-version"] = "true"
|
||||
});
|
||||
var output = MakeTagHelperOutput("link", attributes: new Dictionary<string, string>
|
||||
var output = MakeTagHelperOutput("link", attributes: new Dictionary<string, object>
|
||||
{
|
||||
["href"] = "/bar/css/site.css",
|
||||
["rel"] = "stylesheet"
|
||||
["rel"] = new HtmlString("stylesheet"),
|
||||
});
|
||||
var logger = new Mock<ILogger<LinkTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
|
|
@ -512,6 +518,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Logger = logger.Object,
|
||||
HostingEnvironment = hostingEnvironment,
|
||||
ViewContext = viewContext,
|
||||
Href = "/bar/css/site.css",
|
||||
HrefInclude = "**/*.css",
|
||||
FileVersion = true,
|
||||
Cache = MakeCache(),
|
||||
|
|
@ -521,8 +528,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
helper.Process(context, output);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("<link href=\"HtmlEncode[[/bar/css/site.css?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-" +
|
||||
"j1ncoSt3SABJtkGk]]\" rel=\"stylesheet\" />", output.Content.GetContent());
|
||||
Assert.Equal(
|
||||
"<link rel=\"stylesheet\" href=\"HtmlEncode[[/bar/css/site.css?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk]]\" />",
|
||||
output.Content.GetContent());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -532,15 +540,14 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var context = MakeTagHelperContext(
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
["rel"] = new HtmlString("stylesheet"),
|
||||
["href"] = "/css/site.css",
|
||||
["rel"] = "stylesheet",
|
||||
["asp-href-include"] = "**/*.css",
|
||||
["asp-file-version"] = "true"
|
||||
});
|
||||
var output = MakeTagHelperOutput("link", attributes: new Dictionary<string, string>
|
||||
var output = MakeTagHelperOutput("link", attributes: new Dictionary<string, object>
|
||||
{
|
||||
["href"] = "/css/site.css",
|
||||
["rel"] = "stylesheet"
|
||||
["rel"] = new HtmlString("stylesheet"),
|
||||
});
|
||||
var logger = new Mock<ILogger<LinkTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
|
|
@ -555,6 +562,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Logger = logger.Object,
|
||||
HostingEnvironment = hostingEnvironment,
|
||||
ViewContext = viewContext,
|
||||
Href = "/css/site.css",
|
||||
HrefInclude = "**/*.css",
|
||||
FileVersion = true,
|
||||
Cache = MakeCache(),
|
||||
|
|
@ -562,11 +570,12 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
// Act
|
||||
helper.Process(context, output);
|
||||
|
||||
|
||||
// Assert
|
||||
Assert.Equal("<link href=\"HtmlEncode[[/css/site.css?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk]]\"" +
|
||||
" rel=\"stylesheet\" /><link href=\"HtmlEncode[[/base.css" +
|
||||
"?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk]]\" rel=\"stylesheet\" />", output.Content.GetContent());
|
||||
Assert.Equal(
|
||||
"<link rel=\"stylesheet\" href=\"HtmlEncode[[/css/site.css?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk]]\" />" +
|
||||
"<link rel=\"stylesheet\" href=\"HtmlEncode[[/base.css?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk]]\" />",
|
||||
output.Content.GetContent());
|
||||
}
|
||||
|
||||
private static ViewContext MakeViewContext(string requestPathBase = null)
|
||||
|
|
@ -607,9 +616,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
}
|
||||
|
||||
private static TagHelperOutput MakeTagHelperOutput(string tagName, IDictionary<string, string> attributes = null)
|
||||
private static TagHelperOutput MakeTagHelperOutput(string tagName, IDictionary<string, object> attributes = null)
|
||||
{
|
||||
attributes = attributes ?? new Dictionary<string, string>();
|
||||
attributes = attributes ?? new Dictionary<string, object>();
|
||||
|
||||
return new TagHelperOutput(tagName, attributes);
|
||||
}
|
||||
|
|
@ -671,27 +680,5 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
return cache.Object;
|
||||
}
|
||||
|
||||
private class TestHtmlEncoder : IHtmlEncoder
|
||||
{
|
||||
public string HtmlEncode(string value)
|
||||
{
|
||||
return "HtmlEncode[[" + value + "]]";
|
||||
}
|
||||
|
||||
public void HtmlEncode(string value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write("HtmlEncode[[");
|
||||
output.Write(value.Substring(startIndex, charCount));
|
||||
output.Write("]]");
|
||||
}
|
||||
|
||||
public void HtmlEncode(char[] value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write("HtmlEncode[[");
|
||||
output.Write(value, startIndex, charCount);
|
||||
output.Write("]]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
null, null, null, null,
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }
|
||||
},
|
||||
|
|
@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
null, string.Empty, "value", null,
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }, { "selected", "" }
|
||||
},
|
||||
|
|
@ -46,7 +46,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
null, "selected", "value", null,
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }, { "selected", "selected" }
|
||||
},
|
||||
|
|
@ -56,7 +56,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
null, null, "value", Enumerable.Empty<string>(),
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }
|
||||
},
|
||||
|
|
@ -66,7 +66,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
null, null, "value", new [] { string.Empty, },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }
|
||||
},
|
||||
|
|
@ -76,7 +76,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
null, string.Empty, "value", new [] { string.Empty, },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }, { "selected", "" }
|
||||
},
|
||||
|
|
@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
null, null, "value", new [] { "value", },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }, { "selected", "selected" }
|
||||
},
|
||||
|
|
@ -96,7 +96,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
null, null, "value", new [] { string.Empty, "value", },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }, { "selected", "selected" }
|
||||
},
|
||||
|
|
@ -106,7 +106,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string.Empty, null, null, null,
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }
|
||||
},
|
||||
|
|
@ -116,7 +116,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string.Empty, string.Empty, null, null,
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "selected", "" }
|
||||
},
|
||||
|
|
@ -126,7 +126,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string.Empty, "selected", null, null,
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "selected", "selected" }
|
||||
},
|
||||
|
|
@ -136,7 +136,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string.Empty, null, null, Enumerable.Empty<string>(),
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }
|
||||
},
|
||||
|
|
@ -146,7 +146,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string.Empty, null, null, new [] { string.Empty, },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "selected", "selected" }
|
||||
},
|
||||
|
|
@ -156,7 +156,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string.Empty, string.Empty, null, new [] { string.Empty, },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "selected", "" }
|
||||
},
|
||||
|
|
@ -166,7 +166,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string.Empty, null, null, new [] { "text", },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }
|
||||
},
|
||||
|
|
@ -176,18 +176,17 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string.Empty, null, null, new [] { string.Empty, "text", },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "selected", "selected" }
|
||||
},
|
||||
"")
|
||||
},
|
||||
|
||||
{
|
||||
"text", null, null, null,
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }
|
||||
},
|
||||
|
|
@ -197,7 +196,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", string.Empty, null, null,
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "selected", "" }
|
||||
},
|
||||
|
|
@ -207,7 +206,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", "selected", null, null,
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "selected", "selected" }
|
||||
},
|
||||
|
|
@ -217,7 +216,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", null, null, Enumerable.Empty<string>(),
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }
|
||||
},
|
||||
|
|
@ -227,7 +226,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", null, null, new [] { string.Empty, },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }
|
||||
},
|
||||
|
|
@ -237,7 +236,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", null, null, new [] { "text", },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "selected", "selected" }
|
||||
},
|
||||
|
|
@ -247,7 +246,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", string.Empty, null, new [] { "text", },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "selected", "" }
|
||||
},
|
||||
|
|
@ -257,18 +256,17 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", null, null, new [] { string.Empty, "text", },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "selected", "selected" }
|
||||
},
|
||||
"text")
|
||||
},
|
||||
|
||||
{
|
||||
"text", string.Empty, "value", null,
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }, { "selected", "" }
|
||||
},
|
||||
|
|
@ -278,7 +276,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", "selected", "value", null,
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }, { "selected", "selected" }
|
||||
},
|
||||
|
|
@ -288,7 +286,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", null, "value", Enumerable.Empty<string>(),
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }
|
||||
},
|
||||
|
|
@ -298,7 +296,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", null, "value", new [] { string.Empty, },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }
|
||||
},
|
||||
|
|
@ -308,7 +306,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", string.Empty, "value", new [] { string.Empty, },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }, { "selected", "" }
|
||||
},
|
||||
|
|
@ -318,7 +316,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", null, "value", new [] { "text", },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }
|
||||
},
|
||||
|
|
@ -328,7 +326,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", null, "value", new [] { "value", },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }, { "selected", "selected" }
|
||||
},
|
||||
|
|
@ -338,7 +336,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
"text", null, "value", new [] { string.Empty, "value", },
|
||||
GetTagHelperOutput(
|
||||
"not-option",
|
||||
new Dictionary<string, string>
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" }, { "value", "value" }, { "selected", "selected" }
|
||||
},
|
||||
|
|
@ -381,17 +379,21 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
TagHelperOutput expectedTagHelperOutput)
|
||||
{
|
||||
// Arrange
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" },
|
||||
};
|
||||
if (selected != null)
|
||||
{
|
||||
originalAttributes.Add("selected", selected);
|
||||
}
|
||||
|
||||
var contextAttributes = new Dictionary<string, object>
|
||||
var contextAttributes = new Dictionary<string, object>(originalAttributes);
|
||||
if (value != null)
|
||||
{
|
||||
{ "label", "my-label" },
|
||||
{ "selected", selected },
|
||||
{ "value", value },
|
||||
};
|
||||
contextAttributes.Add("value", value);
|
||||
}
|
||||
|
||||
var tagHelperContext = new TagHelperContext(
|
||||
contextAttributes,
|
||||
items: new Dictionary<object, object>(),
|
||||
|
|
@ -402,6 +404,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
tagHelperContent.SetContent(originalContent);
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
|
||||
var output = new TagHelperOutput(expectedTagHelperOutput.TagName, originalAttributes)
|
||||
{
|
||||
SelfClosing = false,
|
||||
|
|
@ -418,7 +421,6 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var tagHelper = new OptionTagHelper
|
||||
{
|
||||
Generator = htmlGenerator,
|
||||
Selected = selected,
|
||||
Value = value,
|
||||
ViewContext = viewContext,
|
||||
};
|
||||
|
|
@ -446,9 +448,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
TagHelperOutput ignored)
|
||||
{
|
||||
// Arrange
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" },
|
||||
{ "selected", selected },
|
||||
};
|
||||
var originalTagName = "not-option";
|
||||
|
||||
|
|
@ -487,7 +490,6 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
viewContext.FormContext.FormData[SelectTagHelper.SelectedValuesFormDataKey] = selectedValues;
|
||||
var tagHelper = new OptionTagHelper
|
||||
{
|
||||
Selected = selected,
|
||||
Value = value,
|
||||
ViewContext = viewContext,
|
||||
};
|
||||
|
|
@ -507,9 +509,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
TagHelperOutput ignoredOutput)
|
||||
{
|
||||
// Arrange
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "label", "my-label" },
|
||||
{ "selected", selected },
|
||||
};
|
||||
var originalTagName = "not-option";
|
||||
|
||||
|
|
@ -541,7 +544,6 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
var tagHelper = new OptionTagHelper
|
||||
{
|
||||
Selected = selected,
|
||||
Value = value,
|
||||
};
|
||||
|
||||
|
|
@ -551,7 +553,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
}
|
||||
|
||||
private static TagHelperOutput GetTagHelperOutput(
|
||||
string tagName, IDictionary<string, string> attributes, string content)
|
||||
string tagName, IDictionary<string, object> attributes, string content)
|
||||
{
|
||||
var tagHelperOutput = new TagHelperOutput(tagName, attributes);
|
||||
tagHelperOutput.Content.SetContent(content);
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var helper = new ScriptTagHelper
|
||||
{
|
||||
HtmlEncoder = new HtmlEncoder(),
|
||||
JavaScriptEncoder = new JavaScriptStringEncoder(),
|
||||
Logger = logger,
|
||||
HostingEnvironment = hostingEnvironment,
|
||||
ViewContext = viewContext,
|
||||
|
|
@ -441,10 +442,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var viewContext = MakeViewContext();
|
||||
|
||||
var output = MakeTagHelperOutput("src",
|
||||
attributes: new Dictionary<string, string>
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
["data-extra"] = "something",
|
||||
["src"] = "/blank.js",
|
||||
["data-more"] = "else",
|
||||
});
|
||||
|
||||
|
|
@ -454,11 +454,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var helper = new ScriptTagHelper
|
||||
{
|
||||
HtmlEncoder = new HtmlEncoder(),
|
||||
JavaScriptEncoder = new JavaScriptStringEncoder(),
|
||||
Logger = logger,
|
||||
ViewContext = viewContext,
|
||||
HostingEnvironment = hostingEnvironment,
|
||||
FallbackSrc = "~/blank.js",
|
||||
FallbackTestExpression = "http://www.example.com/blank.js",
|
||||
Src = "/blank.js",
|
||||
Cache = MakeCache(),
|
||||
};
|
||||
|
||||
|
|
@ -467,7 +469,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
// Assert
|
||||
Assert.StartsWith(
|
||||
"<script data-extra=\"something\" src=\"/blank.js\" data-more=\"else\"", output.Content.GetContent());
|
||||
"<script data-extra=\"something\" data-more=\"else\" src=\"/blank.js\"", output.Content.GetContent());
|
||||
Assert.Empty(logger.Logged);
|
||||
}
|
||||
|
||||
|
|
@ -481,10 +483,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
["src"] = "/js/site.js",
|
||||
["asp-src-include"] = "**/*.js"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, string>
|
||||
{
|
||||
["src"] = "/js/site.js"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, object>());
|
||||
var logger = new Mock<ILogger<ScriptTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
var viewContext = MakeViewContext();
|
||||
|
|
@ -497,6 +496,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Logger = logger.Object,
|
||||
HostingEnvironment = hostingEnvironment,
|
||||
ViewContext = viewContext,
|
||||
Src = "/js/site.js",
|
||||
SrcInclude = "**/*.js",
|
||||
HtmlEncoder = new HtmlEncoder(),
|
||||
Cache = MakeCache(),
|
||||
|
|
@ -519,10 +519,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
["src"] = "/js/site.js",
|
||||
["asp-src-include"] = "**/*.js"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, string>
|
||||
{
|
||||
["src"] = "/js/site.js"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, object>());
|
||||
var logger = new Mock<ILogger<ScriptTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
var viewContext = MakeViewContext();
|
||||
|
|
@ -535,8 +532,10 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
Logger = logger.Object,
|
||||
HostingEnvironment = hostingEnvironment,
|
||||
ViewContext = viewContext,
|
||||
Src = "/js/site.js",
|
||||
SrcInclude = "**/*.js",
|
||||
HtmlEncoder = new TestHtmlEncoder(),
|
||||
JavaScriptEncoder = new TestJavaScriptEncoder(),
|
||||
Cache = MakeCache(),
|
||||
};
|
||||
|
||||
|
|
@ -558,10 +557,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
["src"] = "/js/site.js",
|
||||
["asp-file-version"] = "true"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, string>
|
||||
{
|
||||
["src"] = "/js/site.js"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, object>());
|
||||
|
||||
var logger = new Mock<ILogger<ScriptTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
|
|
@ -574,6 +570,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
ViewContext = viewContext,
|
||||
FileVersion = true,
|
||||
HtmlEncoder = new TestHtmlEncoder(),
|
||||
JavaScriptEncoder = new TestJavaScriptEncoder(),
|
||||
Src = "/js/site.js",
|
||||
Cache = MakeCache(),
|
||||
};
|
||||
|
||||
|
|
@ -596,10 +594,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
["src"] = "/bar/js/site.js",
|
||||
["asp-file-version"] = "true"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, string>
|
||||
{
|
||||
["src"] = "/bar/js/site.js"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, object>());
|
||||
|
||||
var logger = new Mock<ILogger<ScriptTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
|
|
@ -612,6 +607,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
ViewContext = viewContext,
|
||||
FileVersion = true,
|
||||
HtmlEncoder = new TestHtmlEncoder(),
|
||||
JavaScriptEncoder = new TestJavaScriptEncoder(),
|
||||
Src = "/bar/js/site.js",
|
||||
Cache = MakeCache(),
|
||||
};
|
||||
|
||||
|
|
@ -636,10 +633,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
["asp-fallback-test"] = "isavailable()",
|
||||
["asp-file-version"] = "true"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, string>
|
||||
{
|
||||
["src"] = "/js/site.js"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, object>());
|
||||
|
||||
var logger = new Mock<ILogger<ScriptTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
|
|
@ -654,6 +648,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
FallbackTestExpression = "isavailable()",
|
||||
FileVersion = true,
|
||||
HtmlEncoder = new TestHtmlEncoder(),
|
||||
JavaScriptEncoder = new TestJavaScriptEncoder(),
|
||||
Src = "/js/site.js",
|
||||
Cache = MakeCache(),
|
||||
};
|
||||
|
||||
|
|
@ -663,7 +659,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Assert
|
||||
Assert.Equal(
|
||||
"<script src=\"HtmlEncode[[/js/site.js?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk]]\">" +
|
||||
"</script>\r\n<script>(isavailable()||document.write(\"<script src=\\\"HtmlEncode[[fallback.js" +
|
||||
"</script>\r\n<script>(isavailable()||document.write(\"<script src=\\\"JavaScriptEncode[[fallback.js" +
|
||||
"?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk]]\\\"><\\/script>\"));</script>",
|
||||
output.Content.GetContent());
|
||||
}
|
||||
|
|
@ -679,10 +675,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
["asp-src-include"] = "*.js",
|
||||
["asp-file-version"] = "true"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, string>
|
||||
{
|
||||
["src"] = "/js/site.js"
|
||||
});
|
||||
var output = MakeTagHelperOutput("script", attributes: new Dictionary<string, object>());
|
||||
var logger = new Mock<ILogger<ScriptTagHelper>>();
|
||||
var hostingEnvironment = MakeHostingEnvironment();
|
||||
var viewContext = MakeViewContext();
|
||||
|
|
@ -698,6 +691,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
SrcInclude = "*.js",
|
||||
FileVersion = true,
|
||||
HtmlEncoder = new TestHtmlEncoder(),
|
||||
JavaScriptEncoder = new TestJavaScriptEncoder(),
|
||||
Src = "/js/site.js",
|
||||
Cache = MakeCache(),
|
||||
};
|
||||
|
||||
|
|
@ -748,9 +743,9 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
return viewContext;
|
||||
}
|
||||
|
||||
private TagHelperOutput MakeTagHelperOutput(string tagName, IDictionary<string, string> attributes = null)
|
||||
private TagHelperOutput MakeTagHelperOutput(string tagName, IDictionary<string, object> attributes = null)
|
||||
{
|
||||
attributes = attributes ?? new Dictionary<string, string>();
|
||||
attributes = attributes ?? new Dictionary<string, object>();
|
||||
|
||||
return new TagHelperOutput(tagName, attributes);
|
||||
}
|
||||
|
|
@ -817,27 +812,5 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
return cache.Object;
|
||||
}
|
||||
|
||||
private class TestHtmlEncoder : IHtmlEncoder
|
||||
{
|
||||
public string HtmlEncode(string value)
|
||||
{
|
||||
return "HtmlEncode[[" + value + "]]";
|
||||
}
|
||||
|
||||
public void HtmlEncode(string value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write("HtmlEncode[[");
|
||||
output.Write(value.Substring(startIndex, charCount));
|
||||
output.Write("]]");
|
||||
}
|
||||
|
||||
public void HtmlEncode(char[] value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write("HtmlEncode[[");
|
||||
output.Write(value, startIndex, charCount);
|
||||
output.Write("]]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,6 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.Framework.WebEncoders;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -172,13 +171,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string ignored)
|
||||
{
|
||||
// Arrange
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
};
|
||||
var originalPostContent = "original content";
|
||||
|
||||
var expectedAttributes = new Dictionary<string, string>(originalAttributes)
|
||||
var expectedAttributes = new Dictionary<string, object>(originalAttributes)
|
||||
{
|
||||
{ "id", nameAndId.Id },
|
||||
{ "name", nameAndId.Name },
|
||||
|
|
@ -258,13 +257,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string expectedOptions)
|
||||
{
|
||||
// Arrange
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
};
|
||||
var originalPostContent = "original content";
|
||||
|
||||
var expectedAttributes = new Dictionary<string, string>(originalAttributes)
|
||||
var expectedAttributes = new Dictionary<string, object>(originalAttributes)
|
||||
{
|
||||
{ "id", nameAndId.Id },
|
||||
{ "name", nameAndId.Name },
|
||||
|
|
@ -359,13 +358,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string expectedOptions)
|
||||
{
|
||||
// Arrange
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
};
|
||||
var originalPostContent = "original content";
|
||||
|
||||
var expectedAttributes = new Dictionary<string, string>(originalAttributes)
|
||||
var expectedAttributes = new Dictionary<string, object>(originalAttributes)
|
||||
{
|
||||
{ "id", nameAndId.Id },
|
||||
{ "name", nameAndId.Name },
|
||||
|
|
@ -465,7 +464,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Provided for completeness. Select tag helper does not confirm AllAttributes set is consistent.
|
||||
{ attributeName, attributeValue },
|
||||
};
|
||||
var originalAttributes = new Dictionary<string, string>
|
||||
var originalAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ attributeName, attributeValue },
|
||||
};
|
||||
|
|
@ -547,7 +546,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var contextAttributes = new Dictionary<string, object>();
|
||||
var originalAttributes = new Dictionary<string, string>();
|
||||
var originalAttributes = new Dictionary<string, object>();
|
||||
var propertyName = "Property1";
|
||||
var tagName = "select";
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"p",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
var tagHelperContext = new TagHelperContext(
|
||||
allAttributes: new Dictionary<string, object>(StringComparer.Ordinal)
|
||||
{
|
||||
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
tagHelperContent.Append("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
var expectedAttribute = new KeyValuePair<string, string>(attributeName, attributeValue);
|
||||
var expectedAttribute = new KeyValuePair<string, object>(attributeName, attributeValue);
|
||||
|
||||
// Act
|
||||
tagHelperOutput.CopyHtmlAttribute("hello", tagHelperContext);
|
||||
|
|
@ -52,11 +52,11 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var attributeName = "hello";
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"p",
|
||||
attributes: new Dictionary<string, string>()
|
||||
attributes: new Dictionary<string, object>()
|
||||
{
|
||||
{ attributeName, "world2" }
|
||||
});
|
||||
var expectedAttribute = new KeyValuePair<string, string>(attributeName, "world2");
|
||||
var expectedAttribute = new KeyValuePair<string, object>(attributeName, "world2");
|
||||
var tagHelperContext = new TagHelperContext(
|
||||
allAttributes: new Dictionary<string, object>(StringComparer.Ordinal)
|
||||
{
|
||||
|
|
@ -85,12 +85,12 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"p",
|
||||
attributes: new Dictionary<string, string>()
|
||||
attributes: new Dictionary<string, object>()
|
||||
{
|
||||
{ "route-Hello", "World" },
|
||||
{ "Route-I", "Am" }
|
||||
});
|
||||
var expectedAttribute = new KeyValuePair<string, string>("type", "btn");
|
||||
var expectedAttribute = new KeyValuePair<string, object>("type", "btn");
|
||||
tagHelperOutput.Attributes.Add(expectedAttribute);
|
||||
var attributes = tagHelperOutput.FindPrefixedAttributes("route-");
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"p",
|
||||
attributes: new Dictionary<string, string>()
|
||||
attributes: new Dictionary<string, object>()
|
||||
{
|
||||
{ "routeHello", "World" },
|
||||
{ "Routee-I", "Am" }
|
||||
|
|
@ -131,8 +131,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"p",
|
||||
attributes: new Dictionary<string, string>());
|
||||
var expectedAttribute = new KeyValuePair<string, string>("type", "btn");
|
||||
attributes: new Dictionary<string, object>());
|
||||
var expectedAttribute = new KeyValuePair<string, object>("type", "btn");
|
||||
tagHelperOutput.Attributes.Add(expectedAttribute);
|
||||
|
||||
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
|
||||
|
|
@ -152,13 +152,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"p",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
tagHelperOutput.Attributes.Add("class", "Hello");
|
||||
|
||||
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
|
||||
tagBuilder.Attributes.Add("class", "btn");
|
||||
|
||||
var expectedAttribute = new KeyValuePair<string, string>("class", "Hello btn");
|
||||
var expectedAttribute = new KeyValuePair<string, object>("class", "Hello btn");
|
||||
|
||||
// Act
|
||||
tagHelperOutput.MergeAttributes(tagBuilder);
|
||||
|
|
@ -178,7 +178,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"p",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
tagHelperOutput.Attributes.Add(originalName, "Hello");
|
||||
|
||||
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
|
||||
|
|
@ -189,7 +189,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
// Assert
|
||||
var attribute = Assert.Single(tagHelperOutput.Attributes);
|
||||
Assert.Equal(new KeyValuePair<string, string>(originalName, "Hello btn"), attribute);
|
||||
Assert.Equal(new KeyValuePair<string, object>(originalName, "Hello btn"), attribute);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -198,11 +198,11 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"p",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
|
||||
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
|
||||
var expectedAttribute = new KeyValuePair<string, string>("visible", "val < 3");
|
||||
tagBuilder.Attributes.Add(expectedAttribute);
|
||||
var expectedAttribute = new KeyValuePair<string, object>("visible", "val < 3");
|
||||
tagBuilder.Attributes.Add("visible", "val < 3");
|
||||
|
||||
// Act
|
||||
tagHelperOutput.MergeAttributes(tagBuilder);
|
||||
|
|
@ -218,13 +218,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"p",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
|
||||
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
|
||||
var expectedAttribute1 = new KeyValuePair<string, string>("class", "btn");
|
||||
var expectedAttribute2 = new KeyValuePair<string, string>("class2", "btn");
|
||||
tagBuilder.Attributes.Add(expectedAttribute1);
|
||||
tagBuilder.Attributes.Add(expectedAttribute2);
|
||||
var expectedAttribute1 = new KeyValuePair<string, object>("class", "btn");
|
||||
var expectedAttribute2 = new KeyValuePair<string, object>("class2", "btn");
|
||||
tagBuilder.Attributes.Add("class", "btn");
|
||||
tagBuilder.Attributes.Add("class2", "btn");
|
||||
|
||||
// Act
|
||||
tagHelperOutput.MergeAttributes(tagBuilder);
|
||||
|
|
@ -243,8 +243,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"p",
|
||||
attributes: new Dictionary<string, string>());
|
||||
var expectedAttribute = new KeyValuePair<string, string>("class", "btn");
|
||||
attributes: new Dictionary<string, object>());
|
||||
var expectedAttribute = new KeyValuePair<string, object>("class", "btn");
|
||||
tagHelperOutput.Attributes.Add(expectedAttribute);
|
||||
|
||||
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
|
||||
|
|
@ -263,13 +263,13 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var tagHelperOutput = new TagHelperOutput(
|
||||
"p",
|
||||
attributes: new Dictionary<string, string>());
|
||||
var expectedOutputAttribute = new KeyValuePair<string, string>("class", "btn");
|
||||
attributes: new Dictionary<string, object>());
|
||||
var expectedOutputAttribute = new KeyValuePair<string, object>("class", "btn");
|
||||
tagHelperOutput.Attributes.Add(expectedOutputAttribute);
|
||||
|
||||
var tagBuilder = new TagBuilder("p", new HtmlEncoder());
|
||||
var expectedBuilderAttribute = new KeyValuePair<string, string>("for", "hello");
|
||||
tagBuilder.Attributes.Add(expectedBuilderAttribute);
|
||||
var expectedBuilderAttribute = new KeyValuePair<string, object>("for", "hello");
|
||||
tagBuilder.Attributes.Add("for", "hello");
|
||||
|
||||
// Act
|
||||
tagHelperOutput.MergeAttributes(tagBuilder);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using Microsoft.Framework.WebEncoders;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.TagHelpers
|
||||
|
|
@ -89,7 +88,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
string expectedContent)
|
||||
{
|
||||
// Arrange
|
||||
var expectedAttributes = new Dictionary<string, string>
|
||||
var expectedAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
{ "id", nameAndId.Id },
|
||||
|
|
@ -123,7 +122,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
tagHelperContent.SetContent("Something");
|
||||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
var htmlAttributes = new Dictionary<string, string>
|
||||
var htmlAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
var output = new TagHelperOutput(
|
||||
expectedTagName,
|
||||
attributes: new Dictionary<string, string>
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
{ "id", "myvalidationmessage" }
|
||||
});
|
||||
|
|
@ -105,7 +105,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
var output = new TagHelperOutput(
|
||||
"span",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
output.PreContent.SetContent(expectedPreContent);
|
||||
output.Content.SetContent(expectedContent);
|
||||
output.PostContent.SetContent(expectedPostContent);
|
||||
|
|
@ -145,7 +145,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
};
|
||||
var output = new TagHelperOutput(
|
||||
"span",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
output.Content.SetContent(outputContent);
|
||||
|
||||
var context = new TagHelperContext(
|
||||
|
|
@ -204,7 +204,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
};
|
||||
var output = new TagHelperOutput(
|
||||
"span",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
|
||||
var context = new TagHelperContext(
|
||||
allAttributes: new Dictionary<string, object>(),
|
||||
|
|
@ -259,7 +259,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var expectedPostContent = "original post-content";
|
||||
var output = new TagHelperOutput(
|
||||
"span",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
output.PreContent.SetContent(expectedPreContent);
|
||||
output.Content.SetContent(expectedContent);
|
||||
output.PostContent.SetContent(expectedPostContent);
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
});
|
||||
var output = new TagHelperOutput(
|
||||
expectedTagName,
|
||||
attributes: new Dictionary<string, string>
|
||||
attributes: new Dictionary<string, object>
|
||||
{
|
||||
{ "class", "form-control" }
|
||||
});
|
||||
|
|
@ -102,7 +102,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var expectedPostContent = "original post-content";
|
||||
var output = new TagHelperOutput(
|
||||
"div",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
output.PreContent.SetContent(expectedPreContent);
|
||||
output.Content.SetContent(expectedContent);
|
||||
output.PostContent.SetContent(expectedPostContent);
|
||||
|
|
@ -144,7 +144,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var expectedContent = "original content";
|
||||
var output = new TagHelperOutput(
|
||||
"div",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
output.PreContent.SetContent(expectedPreContent);
|
||||
output.Content.SetContent(expectedContent);
|
||||
output.PostContent.SetContent("Content of validation summary");
|
||||
|
|
@ -201,7 +201,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var expectedPostContent = "original post-content";
|
||||
var output = new TagHelperOutput(
|
||||
"div",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
output.PreContent.SetContent(expectedPreContent);
|
||||
output.Content.SetContent(expectedContent);
|
||||
output.PostContent.SetContent(expectedPostContent);
|
||||
|
|
@ -236,7 +236,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
var expectedContent = "original content";
|
||||
var output = new TagHelperOutput(
|
||||
"div",
|
||||
attributes: new Dictionary<string, string>());
|
||||
attributes: new Dictionary<string, object>());
|
||||
output.PreContent.SetContent(expectedPreContent);
|
||||
output.Content.SetContent(expectedContent);
|
||||
output.PostContent.SetContent("Content of validation message");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
// 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.IO;
|
||||
|
||||
namespace Microsoft.Framework.WebEncoders
|
||||
{
|
||||
internal class TestHtmlEncoder : IHtmlEncoder
|
||||
{
|
||||
public string HtmlEncode(string value)
|
||||
{
|
||||
return $"HtmlEncode[[{ value }]]";
|
||||
}
|
||||
|
||||
public void HtmlEncode(string value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write($"HtmlEncode[[{ value.Substring(startIndex, charCount) }]]");
|
||||
}
|
||||
|
||||
public void HtmlEncode(char[] value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write("HtmlEncode[[");
|
||||
output.Write(value, startIndex, charCount);
|
||||
output.Write("]]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// 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.IO;
|
||||
|
||||
namespace Microsoft.Framework.WebEncoders
|
||||
{
|
||||
internal class TestJavaScriptEncoder : IJavaScriptStringEncoder
|
||||
{
|
||||
public string JavaScriptStringEncode(string value)
|
||||
{
|
||||
return $"JavaScriptEncode[[{ value }]]";
|
||||
}
|
||||
|
||||
public void JavaScriptStringEncode(string value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write($"JavaScriptEncode[[{ value.Substring(startIndex, charCount) }]]");
|
||||
}
|
||||
|
||||
public void JavaScriptStringEncode(char[] value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write("JavaScriptEncode[[");
|
||||
output.Write(value, startIndex, charCount);
|
||||
output.Write("]]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// 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.IO;
|
||||
|
||||
namespace Microsoft.Framework.WebEncoders
|
||||
{
|
||||
internal class TestUrlEncoder : IUrlEncoder
|
||||
{
|
||||
public string UrlEncode(string value)
|
||||
{
|
||||
return $"UrlEncode[[{ value }]]";
|
||||
}
|
||||
|
||||
public void UrlEncode(string value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write($"UrlEncode[[{ value.Substring(startIndex, charCount) }]]");
|
||||
}
|
||||
|
||||
public void UrlEncode(char[] value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write("UrlEncode[[");
|
||||
output.Write(value, startIndex, charCount);
|
||||
output.Write("]]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,10 +7,10 @@
|
|||
<html>
|
||||
<body>
|
||||
<div>
|
||||
<a asp-controller="Product">Product Index</a>
|
||||
<a asp-controller="Product" title="<the title>">Product Index</a>
|
||||
</div>
|
||||
<div>
|
||||
<a asp-controller="Product" asp-action="List">Product List</a>
|
||||
<a asp-controller="Product" asp-action="List" title='"the" title'>Product List</a>
|
||||
</div>
|
||||
<div>
|
||||
<a id="MvcTagHelperTestIndex">MvcTagHelperTest Index</a>
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@
|
|||
<title>Link</title>
|
||||
|
||||
<!-- Plain link tag -->
|
||||
<link href="~/site.css" rel="stylesheet" />
|
||||
<link href="~/site.css" rel="stylesheet" title="<the title>" />
|
||||
|
||||
<!-- Globbed link tag with existing file -->
|
||||
<link asp-href-include="**/site.css" rel="stylesheet" />
|
||||
<link asp-href-include="**/site.css" rel="stylesheet" title="<the title>" />
|
||||
|
||||
<!-- Globbed link tag with existing file and exclude -->
|
||||
<link asp-href-include="**/*.css" asp-href-exclude="**/site3*.css" rel="stylesheet" />
|
||||
<link asp-href-include="**/*.css" asp-href-exclude="**/site3*.css" rel="stylesheet" title='"the" title' />
|
||||
|
||||
<!-- Globbed link tag missing include -->
|
||||
<link asp-href-exclude="**/site2.css" rel="stylesheet" />
|
||||
|
|
@ -37,8 +37,8 @@
|
|||
<link href="~/site.css" asp-href-include="**/site.css" rel="stylesheet" />
|
||||
|
||||
<!-- Fallback to static href -->
|
||||
<link href="~/site.min.css" rel="stylesheet" data-extra="test"
|
||||
asp-fallback-href="~/site.css"
|
||||
<link href="~/site.min.css?a=b&c=d" rel="stylesheet" data-extra="test" title='"the" title'
|
||||
asp-fallback-href="~/site.css?a=b&c=d"
|
||||
asp-fallback-test-class="hidden"
|
||||
asp-fallback-test-property="visibility"
|
||||
asp-fallback-test-value="hidden" />
|
||||
|
|
|
|||
|
|
@ -11,15 +11,15 @@
|
|||
</head>
|
||||
<body>
|
||||
<h2>Script tag helper test</h2>
|
||||
<script src="~/site.js" data-foo="foo-data1">
|
||||
<script src="~/site.js" data-foo="foo-data1" title="<the title>">
|
||||
// Regular script with comment in body, and extra properties.
|
||||
</script>
|
||||
|
||||
<script src="~/blank.js" asp-fallback-src="~/site.js" asp-fallback-test="false" data-foo="foo-data2">
|
||||
<script src="~/blank.js?a=b&c=d" asp-fallback-src="~/site.js?a=b&c=d" asp-fallback-test="false" data-foo="foo-data2" title="<the title>">
|
||||
// TagHelper script with comment in body, and extra properties.
|
||||
</script>
|
||||
|
||||
<script src="~/blank.js" asp-fallback-src-include="**/site.js" asp-fallback-test="false">
|
||||
<script src="~/blank.js" asp-fallback-src-include="**/site.js" asp-fallback-test="false" title='"the" title'>
|
||||
// Fallback to globbed src
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -23,12 +23,14 @@ namespace TagHelpersWebSite.TagHelpers
|
|||
|
||||
public bool? MakePretty { get; set; }
|
||||
|
||||
public string Style { get; set; }
|
||||
|
||||
[Activate]
|
||||
public ViewContext ViewContext { get; set; }
|
||||
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
// Need to check if output.TagName == null in-case the ConditionTagHelper calls into SuppressOutput and
|
||||
// Need to check if output.TagName == null in-case the ConditionTagHelper calls into SuppressOutput and
|
||||
// therefore sets the TagName to null.
|
||||
if (MakePretty.HasValue && !MakePretty.Value ||
|
||||
output.TagName == null)
|
||||
|
|
@ -40,9 +42,8 @@ namespace TagHelpersWebSite.TagHelpers
|
|||
|
||||
if (PrettyTagStyles.TryGetValue(output.TagName, out prettyStyle))
|
||||
{
|
||||
var style = string.Empty;
|
||||
|
||||
if (output.Attributes.TryGetValue("style", out style))
|
||||
var style = Style ?? string.Empty;
|
||||
if (!string.IsNullOrEmpty(style))
|
||||
{
|
||||
style += ";";
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue