Add TagHelperOutput.Attributes and TagHelperContext.AllAttributes replacement.
- Added a TagHelperAttributes object that's used to hold 1=>many attributes. Is used for TagHelperOutput.Attributes. - Added a ReadOnlyTagHelperAttributes object that holds 1=>many IReadOnlyTagHelperAttributes. Is used for TagHelperContext.AllAttributes. - Added a TagHelperAttribute object which is used to represent attributes. - Added a IReadOnlyTagHelperAttribute which is used to represent attributes which cannot be modified. #279
This commit is contained in:
parent
de95f67400
commit
7c604d2b11
|
|
@ -218,6 +218,38 @@ namespace Microsoft.AspNet.Razor.Runtime
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidBoundAttributeName"), p0, p1, p2);
|
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorFactory_InvalidBoundAttributeName"), p0, p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cannot add a '{0}' with a null '{1}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string TagHelperAttributeList_CannotAddWithNullName
|
||||||
|
{
|
||||||
|
get { return GetString("TagHelperAttributeList_CannotAddWithNullName"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cannot add a '{0}' with a null '{1}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatTagHelperAttributeList_CannotAddWithNullName(object p0, object p1)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperAttributeList_CannotAddWithNullName"), p0, p1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cannot add a {0} with inconsistent names. The {1} property '{2}' must match the location '{3}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string TagHelperAttributeList_CannotAddAttribute
|
||||||
|
{
|
||||||
|
get { return GetString("TagHelperAttributeList_CannotAddAttribute"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cannot add a {0} with inconsistent names. The {1} property '{2}' must match the location '{3}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatTagHelperAttributeList_CannotAddAttribute(object p0, object p1, object p2, object p3)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperAttributeList_CannotAddAttribute"), p0, p1, p2, p3);
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetString(string name, params string[] formatterNames)
|
private static string GetString(string name, params string[] formatterNames)
|
||||||
{
|
{
|
||||||
var value = _resourceManager.GetString(name);
|
var value = _resourceManager.GetString(name);
|
||||||
|
|
|
||||||
|
|
@ -156,4 +156,10 @@
|
||||||
<data name="TagHelperDescriptorFactory_InvalidBoundAttributeName" xml:space="preserve">
|
<data name="TagHelperDescriptorFactory_InvalidBoundAttributeName" xml:space="preserve">
|
||||||
<value>Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes beginning with '{2}'.</value>
|
<value>Invalid tag helper bound property '{0}.{1}'. Tag helpers cannot bind to HTML attributes beginning with '{2}'.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TagHelperAttributeList_CannotAddWithNullName" xml:space="preserve">
|
||||||
|
<value>Cannot add a '{0}' with a null '{1}'.</value>
|
||||||
|
</data>
|
||||||
|
<data name="TagHelperAttributeList_CannotAddAttribute" xml:space="preserve">
|
||||||
|
<value>Cannot add a {0} with inconsistent names. The {1} property '{2}' must match the location '{3}'.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A read-only HTML tag helper attribute.
|
||||||
|
/// </summary>
|
||||||
|
public interface IReadOnlyTagHelperAttribute : IEquatable<IReadOnlyTagHelperAttribute>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the attribute.
|
||||||
|
/// </summary>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the value of the attribute.
|
||||||
|
/// </summary>
|
||||||
|
object Value { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,195 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.Framework.Internal;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A read-only collection of <typeparamref name="TAttribute"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TAttribute">
|
||||||
|
/// The type of <see cref="IReadOnlyTagHelperAttribute"/>s in the collection.
|
||||||
|
/// </typeparam>
|
||||||
|
public class ReadOnlyTagHelperAttributeList<TAttribute> : IReadOnlyList<TAttribute>
|
||||||
|
where TAttribute : IReadOnlyTagHelperAttribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a new instance of <see cref="ReadOnlyTagHelperAttributeList{TAttribute}"/> with an empty
|
||||||
|
/// collection.
|
||||||
|
/// </summary>
|
||||||
|
protected ReadOnlyTagHelperAttributeList()
|
||||||
|
{
|
||||||
|
Attributes = new List<TAttribute>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a new instance of <see cref="ReadOnlyTagHelperAttributeList{TAttribute}"/> with the specified
|
||||||
|
/// <paramref name="attributes"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="attributes">The collection to wrap.</param>
|
||||||
|
public ReadOnlyTagHelperAttributeList([NotNull] IEnumerable<TAttribute> attributes)
|
||||||
|
{
|
||||||
|
Attributes = new List<TAttribute>(attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The underlying collection of <typeparamref name="TAttribute"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Intended for use in a non-read-only subclass. Changes to this <see cref="List{TAttribute}"/> will
|
||||||
|
/// affect all getters that <see cref="ReadOnlyTagHelperAttributeList{TAttribute}"/> provides.</remarks>
|
||||||
|
protected List<TAttribute> Attributes { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public TAttribute this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Attributes[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the first <typeparamref name="TAttribute"/> with <see cref="IReadOnlyTagHelperAttribute.Name"/>
|
||||||
|
/// matching <paramref name="name"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">
|
||||||
|
/// The <see cref="IReadOnlyTagHelperAttribute.Name"/> of the <typeparamref name="TAttribute"/> to get.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>The first <typeparamref name="TAttribute"/> with <see cref="IReadOnlyTagHelperAttribute.Name"/>
|
||||||
|
/// matching <paramref name="name"/>.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks><paramref name="name"/> is compared case-insensitively.</remarks>
|
||||||
|
public TAttribute this[[NotNull] string name]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Attributes.FirstOrDefault(attribute => NameEquals(name, attribute));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Attributes.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether a <typeparamref name="TAttribute"/> matching <paramref name="item"/> exists in the
|
||||||
|
/// collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The <typeparamref name="TAttribute"/> to locate.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <c>true</c> if an <typeparamref name="TAttribute"/> matching <paramref name="item"/> exists in the
|
||||||
|
/// collection; otherwise, <c>false</c>.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// <paramref name="item"/>s <see cref="IReadOnlyTagHelperAttribute.Name"/> is compared case-insensitively.
|
||||||
|
/// </remarks>
|
||||||
|
public bool Contains([NotNull] TAttribute item)
|
||||||
|
{
|
||||||
|
return Attributes.Contains(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether a <typeparamref name="TAttribute"/> with the same
|
||||||
|
/// <see cref="IReadOnlyTagHelperAttribute.Name"/> exists in the collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The <see cref="IReadOnlyTagHelperAttribute.Name"/> of the
|
||||||
|
/// <typeparamref name="TAttribute"/> to get.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <c>true</c> if a <typeparamref name="TAttribute"/> with the same
|
||||||
|
/// <see cref="IReadOnlyTagHelperAttribute.Name"/> exists in the collection; otherwise, <c>false</c>.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks><paramref name="name"/> is compared case-insensitively.</remarks>
|
||||||
|
public bool ContainsName([NotNull] string name)
|
||||||
|
{
|
||||||
|
return Attributes.Any(attribute => NameEquals(name, attribute));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Searches for a <typeparamref name="TAttribute"/> matching <paramref name="item"/> in the collection and
|
||||||
|
/// returns the zero-based index of the first occurrence.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The <typeparamref name="TAttribute"/> to locate.</param>
|
||||||
|
/// <returns>The zero-based index of the first occurrence of a <typeparamref name="TAttribute"/> matching
|
||||||
|
/// <paramref name="item"/> in the collection, if found; otherwise, –1.</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// <paramref name="item"/>s <see cref="IReadOnlyTagHelperAttribute.Name"/> is compared case-insensitively.
|
||||||
|
/// </remarks>
|
||||||
|
public int IndexOf([NotNull] TAttribute item)
|
||||||
|
{
|
||||||
|
return Attributes.IndexOf(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the first <typeparamref name="TAttribute"/> with <see cref="IReadOnlyTagHelperAttribute.Name"/>
|
||||||
|
/// matching <paramref name="name"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The <see cref="IReadOnlyTagHelperAttribute.Name"/> of the
|
||||||
|
/// <typeparamref name="TAttribute"/> to get.</param>
|
||||||
|
/// <param name="attribute">When this method returns, the first <typeparamref name="TAttribute"/> with
|
||||||
|
/// <see cref="IReadOnlyTagHelperAttribute.Name"/> matching <paramref name="name"/>, if found; otherwise,
|
||||||
|
/// <c>null</c>.</param>
|
||||||
|
/// <returns><c>true</c> if a <typeparamref name="TAttribute"/> with the same
|
||||||
|
/// <see cref="IReadOnlyTagHelperAttribute.Name"/> exists in the collection; otherwise, <c>false</c>.</returns>
|
||||||
|
/// <remarks><paramref name="name"/> is compared case-insensitively.</remarks>
|
||||||
|
public bool TryGetAttribute([NotNull] string name, out TAttribute attribute)
|
||||||
|
{
|
||||||
|
attribute = Attributes.FirstOrDefault(attr => NameEquals(name, attr));
|
||||||
|
|
||||||
|
return attribute != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves <typeparamref name="TAttribute"/>s in the collection with
|
||||||
|
/// <see cref="IReadOnlyTagHelperAttribute.Name"/> matching <paramref name="name"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The <see cref="IReadOnlyTagHelperAttribute.Name"/> of the
|
||||||
|
/// <typeparamref name="TAttribute"/>s to get.</param>
|
||||||
|
/// <param name="attributes">When this method returns, the <typeparamref name="TAttribute"/>s with
|
||||||
|
/// <see cref="IReadOnlyTagHelperAttribute.Name"/> matching <paramref name="name"/>, if at least one is
|
||||||
|
/// found; otherwise, <c>null</c>.</param>
|
||||||
|
/// <returns><c>true</c> if at least one <typeparamref name="TAttribute"/> with the same
|
||||||
|
/// <see cref="IReadOnlyTagHelperAttribute.Name"/> exists in the collection; otherwise, <c>false</c>.</returns>
|
||||||
|
/// <remarks><paramref name="name"/> is compared case-insensitively.</remarks>
|
||||||
|
public bool TryGetAttributes([NotNull] string name, out IEnumerable<TAttribute> attributes)
|
||||||
|
{
|
||||||
|
attributes = Attributes.Where(attribute => NameEquals(name, attribute));
|
||||||
|
|
||||||
|
return attributes.Any();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IEnumerator<TAttribute> GetEnumerator()
|
||||||
|
{
|
||||||
|
return Attributes.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if the specified <paramref name="attribute"/> has the same name as <paramref name="name"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The value to compare against <paramref name="attribute"/>s
|
||||||
|
/// <see cref="TagHelperAttribute.Name"/>.</param>
|
||||||
|
/// <param name="attribute">The attribute to compare against.</param>
|
||||||
|
/// <returns><c>true</c> if <paramref name="name"/> case-insensitively matches <paramref name="attribute"/>s
|
||||||
|
/// <see cref="TagHelperAttribute.Name"/>.</returns>
|
||||||
|
protected static bool NameEquals(string name, [NotNull] TAttribute attribute)
|
||||||
|
{
|
||||||
|
return string.Equals(name, attribute.Name, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.Internal.Web.Utils;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An HTML tag helper attribute.
|
||||||
|
/// </summary>
|
||||||
|
public class TagHelperAttribute : IReadOnlyTagHelperAttribute
|
||||||
|
{
|
||||||
|
private static readonly int TypeHashCode = typeof(TagHelperAttribute).GetHashCode();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a new instance of <see cref="TagHelperAttribute"/>.
|
||||||
|
/// </summary>
|
||||||
|
public TagHelperAttribute()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a new instance of <see cref="TagHelperAttribute"/> with the specified <paramref name="name"/>
|
||||||
|
/// and <paramref name="value"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The <see cref="Name"/> of the attribute.</param>
|
||||||
|
/// <param name="value">The <see cref="Value"/> of the attribute.</param>
|
||||||
|
public TagHelperAttribute(string name, object value)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the name of the attribute.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the value of the attribute.
|
||||||
|
/// </summary>
|
||||||
|
public object Value { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the specified <paramref name="value"/> into a <see cref="TagHelperAttribute"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The <see cref="Value"/> of the created <see cref="TagHelperAttribute"/>.</param>
|
||||||
|
/// <remarks>Created <see cref="TagHelperAttribute"/>s <see cref="Name"/> is set to <c>null</c>.</remarks>
|
||||||
|
public static implicit operator TagHelperAttribute(string value)
|
||||||
|
{
|
||||||
|
return new TagHelperAttribute
|
||||||
|
{
|
||||||
|
Value = value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <remarks><see cref="Name"/> is compared case-insensitively.</remarks>
|
||||||
|
public bool Equals(IReadOnlyTagHelperAttribute other)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
other != null &&
|
||||||
|
string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
Equals(Value, other.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
var other = obj as IReadOnlyTagHelperAttribute;
|
||||||
|
|
||||||
|
return Equals(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return TypeHashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,239 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Framework.Internal;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A collection of <see cref="TagHelperAttribute"/>s.
|
||||||
|
/// </summary>
|
||||||
|
public class TagHelperAttributeList : ReadOnlyTagHelperAttributeList<TagHelperAttribute>, IList<TagHelperAttribute>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a new instance of <see cref="TagHelperAttributeList"/> with an empty collection.
|
||||||
|
/// </summary>
|
||||||
|
public TagHelperAttributeList()
|
||||||
|
: base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a new instance of <see cref="TagHelperAttributeList"/> with the specified
|
||||||
|
/// <paramref name="attributes"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="attributes">The collection to wrap.</param>
|
||||||
|
public TagHelperAttributeList([NotNull] IEnumerable<TagHelperAttribute> attributes)
|
||||||
|
: base(attributes)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <remarks>
|
||||||
|
/// <paramref name="value"/>'s <see cref="TagHelperAttribute.Name"/> must not be <c>null</c>.
|
||||||
|
/// </remarks>
|
||||||
|
public new TagHelperAttribute this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return base[index];
|
||||||
|
}
|
||||||
|
[param: NotNull]
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value.Name == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
Resources.FormatTagHelperAttributeList_CannotAddWithNullName(
|
||||||
|
typeof(TagHelperAttribute).FullName,
|
||||||
|
nameof(TagHelperAttribute.Name)),
|
||||||
|
nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
Attributes[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the first <see cref="TagHelperAttribute"/> with <see cref="TagHelperAttribute.Name"/> matching
|
||||||
|
/// <paramref name="name"/>. When setting, replaces the first matching
|
||||||
|
/// <see cref="TagHelperAttribute"/> with the specified <paramref name="value"/> and removes any additional
|
||||||
|
/// matching <see cref="TagHelperAttribute"/>s. If a matching <see cref="TagHelperAttribute"/> is not found,
|
||||||
|
/// adds the specified <paramref name="value"/> to the end of the collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">
|
||||||
|
/// The <see cref="TagHelperAttribute.Name"/> of the <see cref="TagHelperAttribute"/> to get or set.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>The first <see cref="TagHelperAttribute"/> with <see cref="TagHelperAttribute.Name"/> matching
|
||||||
|
/// <paramref name="name"/>.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks><paramref name="name"/> is compared case-insensitively. When setting,
|
||||||
|
/// <see cref="TagHelperAttribute"/>s <see cref="TagHelperAttribute.Name"/> must be <c>null</c> or
|
||||||
|
/// case-insensitively match the specified <paramref name="name"/>.</remarks>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// var attributes = new TagHelperAttributeList();
|
||||||
|
///
|
||||||
|
/// // Will "value" be converted to a TagHelperAttribute with a null Name
|
||||||
|
/// attributes["name"] = "value";
|
||||||
|
///
|
||||||
|
/// // TagHelperAttribute.Name must match the specified name.
|
||||||
|
/// attributes["name"] = new TagHelperAttribute("name", "value");
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
public new TagHelperAttribute this[[NotNull] string name]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return base[name];
|
||||||
|
}
|
||||||
|
[param: NotNull]
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// Name will be null if user attempts to set the attribute via an implicit conversion:
|
||||||
|
// output.Attributes["someName"] = "someValue"
|
||||||
|
if (value.Name == null)
|
||||||
|
{
|
||||||
|
value.Name = name;
|
||||||
|
}
|
||||||
|
else if (!NameEquals(name, value))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
Resources.FormatTagHelperAttributeList_CannotAddAttribute(
|
||||||
|
nameof(TagHelperAttribute),
|
||||||
|
nameof(TagHelperAttribute.Name),
|
||||||
|
value.Name,
|
||||||
|
name),
|
||||||
|
nameof(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
var attributeReplaced = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < Attributes.Count; i++)
|
||||||
|
{
|
||||||
|
if (NameEquals(name, Attributes[i]))
|
||||||
|
{
|
||||||
|
// We replace the first attribute with the provided value, remove all the rest.
|
||||||
|
if (!attributeReplaced)
|
||||||
|
{
|
||||||
|
// We replace the first attribute we find with the same name.
|
||||||
|
Attributes[i] = value;
|
||||||
|
attributeReplaced = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Attributes.RemoveAt(i--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we didn't replace an attribute value we should add value to the end of the collection.
|
||||||
|
if (!attributeReplaced)
|
||||||
|
{
|
||||||
|
Add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
bool ICollection<TagHelperAttribute>.IsReadOnly
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="TagHelperAttribute"/> to the end of the collection with the specified
|
||||||
|
/// <paramref name="name"/> and <paramref name="value"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The <see cref="TagHelperAttribute.Name"/> of the attribute to add.</param>
|
||||||
|
/// <param name="value">The <see cref="TagHelperAttribute.Value"/> of the attribute to add.</param>
|
||||||
|
public void Add([NotNull] string name, object value)
|
||||||
|
{
|
||||||
|
Attributes.Add(new TagHelperAttribute(name, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <remarks>
|
||||||
|
/// <paramref name="attribute"/>'s <see cref="TagHelperAttribute.Name"/> must not be <c>null</c>.
|
||||||
|
/// </remarks>
|
||||||
|
public void Add([NotNull] TagHelperAttribute attribute)
|
||||||
|
{
|
||||||
|
if (attribute.Name == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
Resources.FormatTagHelperAttributeList_CannotAddWithNullName(
|
||||||
|
typeof(TagHelperAttribute).FullName,
|
||||||
|
nameof(TagHelperAttribute.Name)),
|
||||||
|
nameof(attribute));
|
||||||
|
}
|
||||||
|
|
||||||
|
Attributes.Add(attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <remarks>
|
||||||
|
/// <paramref name="attribute"/>'s <see cref="TagHelperAttribute.Name"/> must not be <c>null</c>.
|
||||||
|
/// </remarks>
|
||||||
|
public void Insert(int index, [NotNull] TagHelperAttribute attribute)
|
||||||
|
{
|
||||||
|
if (attribute.Name == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
Resources.FormatTagHelperAttributeList_CannotAddWithNullName(
|
||||||
|
typeof(TagHelperAttribute).FullName,
|
||||||
|
nameof(TagHelperAttribute.Name)),
|
||||||
|
nameof(attribute));
|
||||||
|
}
|
||||||
|
|
||||||
|
Attributes.Insert(index, attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void CopyTo([NotNull] TagHelperAttribute[] array, int index)
|
||||||
|
{
|
||||||
|
Attributes.CopyTo(array, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <remarks>
|
||||||
|
/// <paramref name="attribute"/>s <see cref="TagHelperAttribute.Name"/> is compared case-insensitively.
|
||||||
|
/// </remarks>
|
||||||
|
public bool Remove([NotNull] TagHelperAttribute attribute)
|
||||||
|
{
|
||||||
|
return Attributes.Remove(attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void RemoveAt(int index)
|
||||||
|
{
|
||||||
|
Attributes.RemoveAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes all <see cref="TagHelperAttribute"/>s with <see cref="TagHelperAttribute.Name"/> matching
|
||||||
|
/// <paramref name="name"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">
|
||||||
|
/// The <see cref="TagHelperAttribute.Name"/> of <see cref="TagHelperAttribute"/>s to remove.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// <c>true</c> if at least 1 <see cref="TagHelperAttribute"/> was removed; otherwise, <c>false</c>.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks><paramref name="name"/> is compared case-insensitively.</remarks>
|
||||||
|
public bool RemoveAll([NotNull] string name)
|
||||||
|
{
|
||||||
|
return Attributes.RemoveAll(attribute => NameEquals(name, attribute)) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
Attributes.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
|
|
||||||
|
|
@ -25,12 +26,13 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
/// <param name="getChildContentAsync">A delegate used to execute and retrieve the rendered child content
|
/// <param name="getChildContentAsync">A delegate used to execute and retrieve the rendered child content
|
||||||
/// asynchronously.</param>
|
/// asynchronously.</param>
|
||||||
public TagHelperContext(
|
public TagHelperContext(
|
||||||
[NotNull] IDictionary<string, object> allAttributes,
|
[NotNull] IEnumerable<IReadOnlyTagHelperAttribute> allAttributes,
|
||||||
[NotNull] IDictionary<object, object> items,
|
[NotNull] IDictionary<object, object> items,
|
||||||
[NotNull] string uniqueId,
|
[NotNull] string uniqueId,
|
||||||
[NotNull] Func<Task<TagHelperContent>> getChildContentAsync)
|
[NotNull] Func<Task<TagHelperContent>> getChildContentAsync)
|
||||||
{
|
{
|
||||||
AllAttributes = allAttributes;
|
AllAttributes = new ReadOnlyTagHelperAttributeList<IReadOnlyTagHelperAttribute>(
|
||||||
|
allAttributes.Select(attribute => new TagHelperAttribute(attribute.Name, attribute.Value)));
|
||||||
Items = items;
|
Items = items;
|
||||||
UniqueId = uniqueId;
|
UniqueId = uniqueId;
|
||||||
_getChildContentAsync = getChildContentAsync;
|
_getChildContentAsync = getChildContentAsync;
|
||||||
|
|
@ -39,7 +41,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Every attribute associated with the current HTML element.
|
/// Every attribute associated with the current HTML element.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, object> AllAttributes { get; }
|
public ReadOnlyTagHelperAttributeList<IReadOnlyTagHelperAttribute> AllAttributes { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the collection of items used to communicate with other <see cref="ITagHelper"/>s.
|
/// Gets the collection of items used to communicate with other <see cref="ITagHelper"/>s.
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
_endTagHelperWritingScope = endTagHelperWritingScope;
|
_endTagHelperWritingScope = endTagHelperWritingScope;
|
||||||
|
|
||||||
SelfClosing = selfClosing;
|
SelfClosing = selfClosing;
|
||||||
AllAttributes = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
HTMLAttributes = new TagHelperAttributeList();
|
||||||
HTMLAttributes = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
AllAttributes = new TagHelperAttributeList();
|
||||||
TagName = tagName;
|
TagName = tagName;
|
||||||
Items = items;
|
Items = items;
|
||||||
UniqueId = uniqueId;
|
UniqueId = uniqueId;
|
||||||
|
|
@ -91,12 +91,12 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// HTML attributes.
|
/// HTML attributes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, object> HTMLAttributes { get; }
|
public TagHelperAttributeList HTMLAttributes { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <see cref="ITagHelper"/> bound attributes and HTML attributes.
|
/// <see cref="ITagHelper"/> bound attributes and HTML attributes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, object> AllAttributes { get; }
|
public TagHelperAttributeList AllAttributes { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An identifier unique to the HTML element this context is for.
|
/// An identifier unique to the HTML element this context is for.
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
{
|
{
|
||||||
// Internal for testing
|
// Internal for testing
|
||||||
internal TagHelperOutput(string tagName)
|
internal TagHelperOutput(string tagName)
|
||||||
: this(tagName, new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase))
|
: this(tagName, new TagHelperAttributeList())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -25,10 +25,10 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
/// <param name="attributes">The HTML attributes.</param>
|
/// <param name="attributes">The HTML attributes.</param>
|
||||||
public TagHelperOutput(
|
public TagHelperOutput(
|
||||||
string tagName,
|
string tagName,
|
||||||
[NotNull] IDictionary<string, object> attributes)
|
[NotNull] TagHelperAttributeList attributes)
|
||||||
{
|
{
|
||||||
TagName = tagName;
|
TagName = tagName;
|
||||||
Attributes = new Dictionary<string, object>(attributes, StringComparer.OrdinalIgnoreCase);
|
Attributes = new TagHelperAttributeList(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -94,7 +94,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
/// a <c>Microsoft.AspNet.Mvc.Rendering.HtmlString</c> instance. MVC converts most other types to a
|
/// a <c>Microsoft.AspNet.Mvc.Rendering.HtmlString</c> instance. MVC converts most other types to a
|
||||||
/// <see cref="string"/>, then HTML encodes the result.
|
/// <see cref="string"/>, then HTML encodes the result.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public IDictionary<string, object> Attributes { get; }
|
public TagHelperAttributeList Attributes { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Changes <see cref="TagHelperOutput"/> to generate nothing.
|
/// Changes <see cref="TagHelperOutput"/> to generate nothing.
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Microsoft.Internal.Web.Utils
|
namespace Microsoft.Internal.Web.Utils
|
||||||
{
|
{
|
||||||
internal class HashCodeCombiner
|
public class HashCodeCombiner
|
||||||
{
|
{
|
||||||
private long _combinedHash64 = 0x1505L;
|
private long _combinedHash64 = 0x1505L;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
||||||
{
|
{
|
||||||
TagName = source.TagName;
|
TagName = source.TagName;
|
||||||
Descriptors = source.Descriptors;
|
Descriptors = source.Descriptors;
|
||||||
Attributes = new Dictionary<string, SyntaxTreeNode>(source.Attributes);
|
Attributes = new List<KeyValuePair<string, SyntaxTreeNode>>(source.Attributes);
|
||||||
_start = source.Start;
|
_start = source.Start;
|
||||||
SelfClosing = source.SelfClosing;
|
SelfClosing = source.SelfClosing;
|
||||||
SourceStartTag = source.SourceStartTag;
|
SourceStartTag = source.SourceStartTag;
|
||||||
|
|
@ -36,9 +36,9 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
||||||
|
|
||||||
source.Reset();
|
source.Reset();
|
||||||
|
|
||||||
foreach (var attributeChildren in Attributes.Values)
|
foreach (var attributeChildren in Attributes)
|
||||||
{
|
{
|
||||||
attributeChildren.Parent = this;
|
attributeChildren.Value.Parent = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The HTML attributes.
|
/// The HTML attributes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, SyntaxTreeNode> Attributes { get; private set; }
|
public IList<KeyValuePair<string, SyntaxTreeNode>> Attributes { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override SourceLocation Start
|
public override SourceLocation Start
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
||||||
{
|
{
|
||||||
TagName = original.TagName;
|
TagName = original.TagName;
|
||||||
Descriptors = original.Descriptors;
|
Descriptors = original.Descriptors;
|
||||||
Attributes = new Dictionary<string, SyntaxTreeNode>(original.Attributes);
|
Attributes = new List<KeyValuePair<string, SyntaxTreeNode>>(original.Attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -39,26 +39,28 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
||||||
/// <param name="attributes">Attributes of the <see cref="TagHelperBlock"/>.</param>
|
/// <param name="attributes">Attributes of the <see cref="TagHelperBlock"/>.</param>
|
||||||
/// <param name="descriptors">The <see cref="TagHelperDescriptor"/>s associated with the current HTML
|
/// <param name="descriptors">The <see cref="TagHelperDescriptor"/>s associated with the current HTML
|
||||||
/// tag.</param>
|
/// tag.</param>
|
||||||
public TagHelperBlockBuilder(string tagName,
|
public TagHelperBlockBuilder(
|
||||||
bool selfClosing,
|
string tagName,
|
||||||
SourceLocation start,
|
bool selfClosing,
|
||||||
IDictionary<string, SyntaxTreeNode> attributes,
|
SourceLocation start,
|
||||||
IEnumerable<TagHelperDescriptor> descriptors)
|
IList<KeyValuePair<string, SyntaxTreeNode>> attributes,
|
||||||
|
IEnumerable<TagHelperDescriptor> descriptors)
|
||||||
{
|
{
|
||||||
TagName = tagName;
|
TagName = tagName;
|
||||||
SelfClosing = selfClosing;
|
SelfClosing = selfClosing;
|
||||||
Start = start;
|
Start = start;
|
||||||
Descriptors = descriptors;
|
Descriptors = descriptors;
|
||||||
Attributes = new Dictionary<string, SyntaxTreeNode>(attributes);
|
Attributes = new List<KeyValuePair<string, SyntaxTreeNode>>(attributes);
|
||||||
Type = BlockType.Tag;
|
Type = BlockType.Tag;
|
||||||
CodeGenerator = new TagHelperCodeGenerator(descriptors);
|
CodeGenerator = new TagHelperCodeGenerator(descriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal for testing
|
// Internal for testing
|
||||||
internal TagHelperBlockBuilder(string tagName,
|
internal TagHelperBlockBuilder(
|
||||||
bool selfClosing,
|
string tagName,
|
||||||
IDictionary<string, SyntaxTreeNode> attributes,
|
bool selfClosing,
|
||||||
IEnumerable<SyntaxTreeNode> children)
|
IList<KeyValuePair<string, SyntaxTreeNode>> attributes,
|
||||||
|
IEnumerable<SyntaxTreeNode> children)
|
||||||
{
|
{
|
||||||
TagName = tagName;
|
TagName = tagName;
|
||||||
SelfClosing = selfClosing;
|
SelfClosing = selfClosing;
|
||||||
|
|
@ -98,7 +100,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The HTML attributes.
|
/// The HTML attributes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, SyntaxTreeNode> Attributes { get; private set; }
|
public IList<KeyValuePair<string, SyntaxTreeNode>> Attributes { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The HTML tag name.
|
/// The HTML tag name.
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,14 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
return new TagHelperBlockBuilder(tagName, selfClosing, start, attributes, descriptors);
|
return new TagHelperBlockBuilder(tagName, selfClosing, start, attributes, descriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IDictionary<string, SyntaxTreeNode> GetTagAttributes(
|
private static IList<KeyValuePair<string, SyntaxTreeNode>> GetTagAttributes(
|
||||||
string tagName,
|
string tagName,
|
||||||
bool validStructure,
|
bool validStructure,
|
||||||
Block tagBlock,
|
Block tagBlock,
|
||||||
IEnumerable<TagHelperDescriptor> descriptors,
|
IEnumerable<TagHelperDescriptor> descriptors,
|
||||||
ErrorSink errorSink)
|
ErrorSink errorSink)
|
||||||
{
|
{
|
||||||
var attributes = new Dictionary<string, SyntaxTreeNode>(StringComparer.OrdinalIgnoreCase);
|
var attributes = new List<KeyValuePair<string, SyntaxTreeNode>>();
|
||||||
|
|
||||||
// Build a dictionary so we can easily lookup expected attribute value lookups
|
// Build a dictionary so we can easily lookup expected attribute value lookups
|
||||||
IReadOnlyDictionary<string, string> attributeValueTypes =
|
IReadOnlyDictionary<string, string> attributeValueTypes =
|
||||||
|
|
@ -88,7 +88,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
attribute.Key.Length);
|
attribute.Key.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes[attribute.Key] = attribute.Value;
|
attributes.Add(new KeyValuePair<string, SyntaxTreeNode>(attribute.Key, attribute.Value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,13 +137,13 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
|
|
||||||
if (afterEquals)
|
if (afterEquals)
|
||||||
{
|
{
|
||||||
// We've captured all leading whitespace, the attribute name, and an equals with an optional
|
// We've captured all leading whitespace, the attribute name, and an equals with an optional
|
||||||
// quote/double quote. We're now at: " asp-for='|...'" or " asp-for=|..."
|
// quote/double quote. We're now at: " asp-for='|...'" or " asp-for=|..."
|
||||||
// The goal here is to capture all symbols until the end of the attribute. Note this will not
|
// The goal here is to capture all symbols until the end of the attribute. Note this will not
|
||||||
// consume an ending quote due to the symbolOffset.
|
// consume an ending quote due to the symbolOffset.
|
||||||
|
|
||||||
// When symbols are accepted into SpanBuilders, their locations get altered to be offset by the
|
// When symbols are accepted into SpanBuilders, their locations get altered to be offset by the
|
||||||
// parent which is why we need to mark our start location prior to adding the symbol.
|
// parent which is why we need to mark our start location prior to adding the symbol.
|
||||||
// This is needed to know the location of the attribute value start within the document.
|
// This is needed to know the location of the attribute value start within the document.
|
||||||
if (!capturedAttributeValueStart)
|
if (!capturedAttributeValueStart)
|
||||||
{
|
{
|
||||||
|
|
@ -206,10 +206,10 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
}
|
}
|
||||||
else if (symbol.Type == HtmlSymbolType.WhiteSpace)
|
else if (symbol.Type == HtmlSymbolType.WhiteSpace)
|
||||||
{
|
{
|
||||||
// We're at the start of the attribute, this branch may be hit on the first iterations of
|
// We're at the start of the attribute, this branch may be hit on the first iterations of
|
||||||
// the loop since the parser separates attributes with their spaces included as symbols.
|
// the loop since the parser separates attributes with their spaces included as symbols.
|
||||||
// We're at: "| asp-for='...'" or "| asp-for=..."
|
// We're at: "| asp-for='...'" or "| asp-for=..."
|
||||||
// Note: This will not be hit even for situations like asp-for ="..." because the core Razor
|
// Note: This will not be hit even for situations like asp-for ="..." because the core Razor
|
||||||
// parser currently does not know how to handle attributes in that format. This will be addressed
|
// parser currently does not know how to handle attributes in that format. This will be addressed
|
||||||
// by https://github.com/aspnet/Razor/issues/123.
|
// by https://github.com/aspnet/Razor/issues/123.
|
||||||
|
|
||||||
|
|
@ -230,7 +230,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
{
|
{
|
||||||
errorSink.OnError(
|
errorSink.OnError(
|
||||||
span.Start,
|
span.Start,
|
||||||
RazorResources.TagHelperBlockRewriter_TagHelperAttributesMustBeWelformed,
|
RazorResources.TagHelperBlockRewriter_TagHelperAttributeListMustBeWelformed,
|
||||||
span.Content.Length);
|
span.Content.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -375,7 +375,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
||||||
else if (isDynamic && childSpan.CodeGenerator == SpanCodeGenerator.Null)
|
else if (isDynamic && childSpan.CodeGenerator == SpanCodeGenerator.Null)
|
||||||
{
|
{
|
||||||
// Usually the dynamic code generator handles rendering the null code generators underneath
|
// Usually the dynamic code generator handles rendering the null code generators underneath
|
||||||
// it. This doesn't make sense in terms of tag helpers though, we need to change null code
|
// it. This doesn't make sense in terms of tag helpers though, we need to change null code
|
||||||
// generators to markup code generators.
|
// generators to markup code generators.
|
||||||
|
|
||||||
newCodeGenerator = new MarkupCodeGenerator();
|
newCodeGenerator = new MarkupCodeGenerator();
|
||||||
|
|
|
||||||
|
|
@ -1369,17 +1369,17 @@ namespace Microsoft.AspNet.Razor
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TagHelper attributes must be welformed.
|
/// TagHelper attributes must be welformed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string TagHelperBlockRewriter_TagHelperAttributesMustBeWelformed
|
internal static string TagHelperBlockRewriter_TagHelperAttributeListMustBeWelformed
|
||||||
{
|
{
|
||||||
get { return GetString("TagHelperBlockRewriter_TagHelperAttributesMustBeWelformed"); }
|
get { return GetString("TagHelperBlockRewriter_TagHelperAttributeListMustBeWelformed"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TagHelper attributes must be welformed.
|
/// TagHelper attributes must be welformed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string FormatTagHelperBlockRewriter_TagHelperAttributesMustBeWelformed()
|
internal static string FormatTagHelperBlockRewriter_TagHelperAttributeListMustBeWelformed()
|
||||||
{
|
{
|
||||||
return GetString("TagHelperBlockRewriter_TagHelperAttributesMustBeWelformed");
|
return GetString("TagHelperBlockRewriter_TagHelperAttributeListMustBeWelformed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -390,7 +390,7 @@ Instead, wrap the contents of the block in "{{}}":
|
||||||
<data name="TagHelpersParseTreeRewriter_MissingCloseAngle" xml:space="preserve">
|
<data name="TagHelpersParseTreeRewriter_MissingCloseAngle" xml:space="preserve">
|
||||||
<value>Missing close angle for tag helper '{0}'.</value>
|
<value>Missing close angle for tag helper '{0}'.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TagHelperBlockRewriter_TagHelperAttributesMustBeWelformed" xml:space="preserve">
|
<data name="TagHelperBlockRewriter_TagHelperAttributeListMustBeWelformed" xml:space="preserve">
|
||||||
<value>TagHelper attributes must be welformed.</value>
|
<value>TagHelper attributes must be welformed.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TagHelpers_AttributeExpressionRequired" xml:space="preserve">
|
<data name="TagHelpers_AttributeExpressionRequired" xml:space="preserve">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue