Reintroduce WriteAttribute methods on RazorView type
This commit is contained in:
parent
f1183f57af
commit
9915b1c767
|
|
@ -3,6 +3,7 @@
|
|||
@{
|
||||
Layout = "/Views/Shared/_Layout.cshtml";
|
||||
ViewBag.Title = "Home Page";
|
||||
string nullValue = null;
|
||||
}
|
||||
|
||||
<div class="jumbotron">
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
<p><a href="http://asp.net" class="btn btn-primary btn-large">Learn more »</a></p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h3>Hello @Model.Name!</h3>
|
||||
<h3 title="@Model.Name" class="@nullValue">Hello @Model.Name!</h3>
|
||||
|
||||
<div class="col-md-4">
|
||||
<h2>Getting started</h2>
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
{
|
||||
public class AttributeValue
|
||||
{
|
||||
public AttributeValue(PositionTagged<string> prefix, PositionTagged<object> value, bool literal)
|
||||
{
|
||||
Prefix = prefix;
|
||||
Value = value;
|
||||
Literal = literal;
|
||||
}
|
||||
|
||||
public PositionTagged<string> Prefix { get; private set; }
|
||||
|
||||
public PositionTagged<object> Value { get; private set; }
|
||||
|
||||
public bool Literal { get; private set; }
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "We are using tuples here to avoid dependencies from Razor to WebPages")]
|
||||
public static AttributeValue FromTuple(Tuple<Tuple<string, int>, Tuple<object, int>, bool> value)
|
||||
{
|
||||
return new AttributeValue(value.Item1, value.Item2, value.Item3);
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "We are using tuples here to avoid dependencies from Razor to WebPages")]
|
||||
public static AttributeValue FromTuple(Tuple<Tuple<string, int>, Tuple<string, int>, bool> value)
|
||||
{
|
||||
return new AttributeValue(value.Item1, new PositionTagged<object>(value.Item2.Item1, value.Item2.Item2), value.Item3);
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "We are using tuples here to avoid dependencies from Razor to WebPages")]
|
||||
public static implicit operator AttributeValue(Tuple<Tuple<string, int>, Tuple<object, int>, bool> value)
|
||||
{
|
||||
return FromTuple(value);
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "We are using tuples here to avoid dependencies from Razor to WebPages")]
|
||||
public static implicit operator AttributeValue(Tuple<Tuple<string, int>, Tuple<string, int>, bool> value)
|
||||
{
|
||||
return FromTuple(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
{
|
||||
[DebuggerDisplay("({Position})\"{Value}\"")]
|
||||
public class PositionTagged<T>
|
||||
{
|
||||
public PositionTagged(T value, int offset)
|
||||
{
|
||||
Position = offset;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public int Position { get; private set; }
|
||||
|
||||
public T Value { get; private set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value.ToString();
|
||||
}
|
||||
|
||||
public static implicit operator T(PositionTagged<T> value)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static implicit operator PositionTagged<T>(Tuple<T, int> value)
|
||||
{
|
||||
return new PositionTagged<T>(value.Item1, value.Item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -92,6 +92,104 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
}
|
||||
}
|
||||
|
||||
public virtual void WriteAttribute(string name,
|
||||
PositionTagged<string> prefix,
|
||||
PositionTagged<string> suffix,
|
||||
params AttributeValue[] values)
|
||||
{
|
||||
WriteAttributeTo(Output, name, prefix, suffix, values);
|
||||
}
|
||||
|
||||
public virtual void WriteAttributeTo(TextWriter writer,
|
||||
string name,
|
||||
PositionTagged<string> prefix,
|
||||
PositionTagged<string> suffix,
|
||||
params AttributeValue[] values)
|
||||
{
|
||||
bool first = true;
|
||||
bool wroteSomething = false;
|
||||
if (values.Length == 0)
|
||||
{
|
||||
// Explicitly empty attribute, so write the prefix and suffix
|
||||
WritePositionTaggedLiteral(writer, prefix);
|
||||
WritePositionTaggedLiteral(writer, suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
AttributeValue attrVal = values[i];
|
||||
PositionTagged<object> val = attrVal.Value;
|
||||
PositionTagged<string> next = i == values.Length - 1 ?
|
||||
suffix : // End of the list, grab the suffix
|
||||
values[i + 1].Prefix; // Still in the list, grab the next prefix
|
||||
|
||||
if (val.Value == null)
|
||||
{
|
||||
// Nothing to write
|
||||
continue;
|
||||
}
|
||||
|
||||
// The special cases here are that the value we're writing might already be a string, or that the
|
||||
// value might be a bool. If the value is the bool 'true' we want to write the attribute name instead
|
||||
// of the string 'true'. If the value is the bool 'false' we don't want to write anything.
|
||||
//
|
||||
// Otherwise the value is another object (perhaps an IHtmlString), and we'll ask it to format itself.
|
||||
string stringValue;
|
||||
bool? boolValue = val.Value as bool?;
|
||||
if (boolValue == true)
|
||||
{
|
||||
stringValue = name;
|
||||
}
|
||||
else if (boolValue == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
stringValue = val.Value as string;
|
||||
}
|
||||
|
||||
if (first)
|
||||
{
|
||||
WritePositionTaggedLiteral(writer, prefix);
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
WritePositionTaggedLiteral(writer, attrVal.Prefix);
|
||||
}
|
||||
|
||||
// Calculate length of the source span by the position of the next value (or suffix)
|
||||
int sourceLength = next.Position - attrVal.Value.Position;
|
||||
|
||||
if (attrVal.Literal)
|
||||
{
|
||||
WriteLiteralTo(writer, stringValue ?? val.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteTo(writer, stringValue ?? val.Value); // Write value
|
||||
}
|
||||
wroteSomething = true;
|
||||
}
|
||||
if (wroteSomething)
|
||||
{
|
||||
WritePositionTaggedLiteral(writer, suffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WritePositionTaggedLiteral(TextWriter writer, string value, int position)
|
||||
{
|
||||
WriteLiteralTo(writer, value);
|
||||
}
|
||||
|
||||
private void WritePositionTaggedLiteral(TextWriter writer, PositionTagged<string> value)
|
||||
{
|
||||
WritePositionTaggedLiteral(writer, value.Value, value.Position);
|
||||
}
|
||||
|
||||
protected virtual HtmlString RenderBody()
|
||||
{
|
||||
if (BodyContent == null)
|
||||
|
|
|
|||
Loading…
Reference in New Issue