Converted Html.Link to return MvcHtmlString. Replaced unnecessary calls to <%= with <%: as a result of this change.

Added some unit tests for Html.Link.

--HG--
branch : dev
This commit is contained in:
Phil Haack
2010-06-09 23:06:36 -07:00
parent fa3c6a2854
commit 013638aca8
23 changed files with 97 additions and 28 deletions

View File

@@ -0,0 +1,68 @@
using System.Web;
using System.Web.Mvc;
using Moq;
using NUnit.Framework;
using Orchard.Mvc.Html;
namespace Orchard.Tests.Mvc.Html {
[TestFixture]
public class HtmlHelperExtensionsTests {
[Test]
public void LinkReturnsIHtmlString() {
//arrange
var viewContext = new ViewContext();
var viewDataContainer = new Mock<IViewDataContainer>();
var html = new HtmlHelper(viewContext, viewDataContainer.Object);
//act
var result = html.Link("test", "http://example.com") as IHtmlString;
//assert
Assert.IsNotNull(result);
}
[Test]
public void LinkHtmlEncodesLinkText() {
//arrange
var viewContext = new ViewContext();
var viewDataContainer = new Mock<IViewDataContainer>();
var html = new HtmlHelper(viewContext, viewDataContainer.Object);
//act
var result = html.Link("<br />", "http://example.com");
//assert
Assert.AreEqual(@"<a href=""http://example.com"">&lt;br /&gt;</a>", result.ToString());
}
[Test]
public void LinkHtmlAttributeEncodesAttributes() {
//arrange
var viewContext = new ViewContext();
var viewDataContainer = new Mock<IViewDataContainer>();
var html = new HtmlHelper(viewContext, viewDataContainer.Object);
//act
var result = html.Link("linkText", "http://example.com", new { title = "<br />" });
//assert
Assert.AreEqual(@"<a href=""http://example.com"" title=""&lt;br />"">linkText</a>", result.ToString());
}
[Test]
public void SelectOptionHtmlEncodesText() {
//arrange
var viewContext = new ViewContext();
var viewDataContainer = new Mock<IViewDataContainer>();
var html = new HtmlHelper(viewContext, viewDataContainer.Object);
//act
var result = html.SelectOption("value", false, "<br />");
//assert
Assert.AreEqual(@"<option value=""value"">&lt;br /&gt;</option>", result.ToString());
}
}
}

View File

@@ -197,6 +197,7 @@
<Compile Include="Environment\ShellBuilders\DefaultShellContainerFactoryTests.cs" />
<Compile Include="Environment\ShellBuilders\DefaultShellContextFactoryTests.cs" />
<Compile Include="Localization\CultureManagerTests.cs" />
<Compile Include="Mvc\Html\HtmlHelperExtensionsTests.cs" />
<Compile Include="Mvc\Routes\ShellRouteTests.cs" />
<Compile Include="Mvc\Routes\UrlPrefixTests.cs" />
<Compile Include="Stubs\StubCacheManager.cs" />

View File

@@ -5,7 +5,7 @@
<div class="archive-trail">
<%=T("Archives").ToString()
%> / <%=Html.Link(Model.ArchiveData.Year.ToString(), Url.BlogArchiveYear(Model.Blog.Slug, Model.ArchiveData.Year))
%> / <%: Html.Link(Model.ArchiveData.Year.ToString(), Url.BlogArchiveYear(Model.Blog.Slug, Model.ArchiveData.Year))
%><%=Model.ArchiveData.Month > 0 ? string.Format(" / {0}", Html.Link(Model.ArchiveData.ToDateTime().ToString("MMMM"), Url.BlogArchiveMonth(Model.Blog.Slug, Model.ArchiveData.Year, Model.ArchiveData.Month))) : ""
%><%=Model.ArchiveData.Day > 0 ? string.Format(" / {0}", Html.Link(Model.ArchiveData.Day.ToString(), Url.BlogArchiveDay(Model.Blog.Slug, Model.ArchiveData.Year, Model.ArchiveData.Month, Model.ArchiveData.Day))) : ""
%>

View File

@@ -2,6 +2,6 @@
<%@ Import Namespace="Orchard.Mvc.ViewModels"%>
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
<%@ Import Namespace="Orchard.Blogs.Models"%>
<h2><%=Html.Link(Html.Encode(Model.Item.Name), Url.Blog(Model.Item.Slug)) %></h2>
<h2><%: Html.Link(Model.Item.Name, Url.Blog(Model.Item.Slug)) %></h2>
<% if (!string.IsNullOrEmpty(Model.Item.Description)) { %><p><%: Model.Item.Description %></p><% } %>
<div class="blog metadata"><%: T("{0} post{1}", Model.Item.PostCount, Model.Item.PostCount == 1 ? "" : "s")%> | <%Html.Zone("meta");%></div>

View File

@@ -14,7 +14,7 @@
} %>
</div>
<div class="properties">
<h3><%=Html.Link(Html.Encode(Model.Item.Name), Url.BlogForAdmin(Model.Item.Slug)) %></h3>
<h3><%: Html.Link(Model.Item.Name, Url.BlogForAdmin(Model.Item.Slug)) %></h3>
<p><% Html.Zone("meta");%></p>
<%--<p>[list of authors] [modify blog access]</p>--%>
<p><%: Model.Item.Description %></p>

View File

@@ -4,6 +4,6 @@
<%@ Import Namespace="Orchard.Mvc.ViewModels"%>
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
<%@ Import Namespace="Orchard.Blogs.Models"%>
<h2><%=Html.Link(Html.Encode(Model.Item.Title), Url.BlogPost(Model.Item)) %></h2>
<h2><%: Html.Link(Model.Item.Title, Url.BlogPost(Model.Item)) %></h2>
<div class="meta"><%=Html.PublishedState(Model.Item) %> | <%Html.Zone("meta");%></div>
<div class="content"><% Html.Zone("primary", ":manage :metadata");%></div>

View File

@@ -7,7 +7,7 @@
<%@ Import Namespace="Orchard.Blogs.Models"%>
<div class="summary">
<div class="properties">
<h3><%=Html.Link(Html.Encode(Model.Item.Title), Url.BlogPostEdit(Model.Item))%></h3>
<h3><%: Html.Link(s, Url.BlogPostEdit(Model.Item))%></h3>
<ul>
<li><%
if (Model.Item.HasPublished) { %>

View File

@@ -6,7 +6,7 @@ foreach (var comment in Model) { %>
<div class="comment">
<span class="who"><%=Html.LinkOrDefault(Html.Encode(comment.Record.UserName), Html.Encode(comment.Record.SiteName), new { rel = "nofollow" })%></span>
<%-- todo: (heskew) need comment permalink --%>
<span>said <%=Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc.GetValueOrDefault()), "#")%></span>
<span>said <%: Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc.GetValueOrDefault()), "#")%></span>
</div>
<div class="text">
<%-- todo: (heskew) comment text needs processing depending on comment markup style --%>

View File

@@ -2,4 +2,4 @@
<%@ Import Namespace="Orchard.MultiTenancy.Extensions"%>
<%@ Import Namespace="Orchard.Mvc.Html"%>
<%@ Import Namespace="Orchard.Environment.Configuration" %>
<%=Html.Link(T("Set Up").ToString(), Url.Tenant(Model))%>
<%: Html.Link(T("Set Up").ToString(), Url.Tenant(Model))%>

View File

@@ -11,7 +11,7 @@
<div class="properties">
<h3><span class="tenantName"><%: tenant.Name %></span><%
if (!string.IsNullOrEmpty(tenant.RequestUrlHost)) {
%><span class="tenantHost"> - <%=Html.Link(Url.Tenant(tenant), Url.Tenant(tenant))%></span><%
%><span class="tenantHost"> - <%: Html.Link(Url.Tenant(tenant), Url.Tenant(tenant))%></span><%
} %></h3>
</div>
<div class="related"><%

View File

@@ -19,7 +19,7 @@
sbClass.Append("current ");
var classValue = sbClass.ToString().TrimEnd(); %>
<li<%=!string.IsNullOrEmpty(classValue) ? string.Format(" class=\"{0}\"", classValue) : "" %>><%=Html.Link(menuItem.Text, menuItem.Href) %></li><%
<li<%=!string.IsNullOrEmpty(classValue) ? string.Format(" class=\"{0}\"", classValue) : "" %>><%: Html.Link(menuItem.Text, menuItem.Href) %></li><%
++counter;
} %>
</ul>

View File

@@ -3,6 +3,6 @@
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
<%@ Import Namespace="Orchard.Blogs.Models"%>
<h3><%=Html.Link(Html.Encode(Model.Item.Name), Url.Blog(Model.Item.Slug)) %></h3>
<h3><%: Html.Link(Model.Item.Name, Url.Blog(Model.Item.Slug)) %></h3>
<div class="blog meta"><a href="<%=Url.Blog(Model.Item.Slug) %>"><%: T("{0} post{1}", Model.Item.PostCount, Model.Item.PostCount == 1 ? "" : "s")%></a></div>
<div class="blogdescription"><p><%: Model.Item.Description %></p></div>

View File

@@ -5,7 +5,7 @@
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
<%@ Import Namespace="Orchard.Blogs.Models"%>
<%Model.Zones.AddRenderPartial("zonetest", "ZoneTest", Model); %>
<h2><%=Html.Link(Html.Encode(Model.Item.Title), Url.BlogPost(Model.Item)) %></h2>
<h2><%: Html.Link(Model.Item.Title, Url.BlogPost(Model.Item)) %></h2>
<div class="meta"><%=Html.PublishedState(Model.Item) %> | <%Html.Zone("meta");%></div>
<div class="postsummary">
<% Html.Zone("primary"); %>

View File

@@ -3,6 +3,6 @@
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
<%@ Import Namespace="Orchard.Blogs.Models"%>
<h3><%=Html.Link(Html.Encode(Model.Item.Name), Url.Blog(Model.Item.Slug)) %></h3>
<h3><%: Html.Link(Model.Item.Name, Url.Blog(Model.Item.Slug)) %></h3>
<div class="blog meta"><a href="<%=Url.Blog(Model.Item.Slug) %>"><%: T("{0} post{1}", Model.Item.PostCount, Model.Item.PostCount == 1 ? "" : "s")%></a></div>
<div class="blogdescription"><p><%: Model.Item.Description %></p></div>

View File

@@ -5,7 +5,7 @@
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
<%@ Import Namespace="Orchard.Blogs.Models"%>
<%Model.Zones.AddRenderPartial("zonetest", "ZoneTest", Model); %>
<h2><%=Html.Link(Html.Encode(Model.Item.Title), Url.BlogPost(Model.Item)) %></h2>
<h2><%: Html.Link(Model.Item.Title, Url.BlogPost(Model.Item)) %></h2>
<div class="meta"><%=Html.PublishedState(Model.Item) %> | <%Html.Zone("meta");%></div>
<div class="postsummary">
<% Html.Zone("primary"); %>

View File

@@ -5,7 +5,7 @@
<div class="archive-trail">
<%=T("Archives").ToString()
%> / <%=Html.Link(Model.ArchiveData.Year.ToString(), Url.BlogArchiveYear(Model.Blog.Slug, Model.ArchiveData.Year))
%> / <%: Html.Link(Model.ArchiveData.Year.ToString(), Url.BlogArchiveYear(Model.Blog.Slug, Model.ArchiveData.Year))
%><%=Model.ArchiveData.Month > 0 ? string.Format(" / {0}", Html.Link(Model.ArchiveData.ToDateTime().ToString("MMMM"), Url.BlogArchiveMonth(Model.Blog.Slug, Model.ArchiveData.Year, Model.ArchiveData.Month))) : ""
%><%=Model.ArchiveData.Day > 0 ? string.Format(" / {0}", Html.Link(Model.ArchiveData.Day.ToString(), Url.BlogArchiveDay(Model.Blog.Slug, Model.ArchiveData.Year, Model.ArchiveData.Month, Model.ArchiveData.Day))) : ""
%>

View File

@@ -9,7 +9,7 @@ foreach (var comment in Model) { %>
</div>
<div class="commentauthor">
<span class="who"><%=Html.LinkOrDefault(Html.Encode(comment.Record.UserName), Html.Encode(comment.Record.SiteName), new { rel = "nofollow" })%></span>&nbsp;<span>said <%=Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc.GetValueOrDefault()), "#")%></span>
<span class="who"><%=Html.LinkOrDefault(Html.Encode(comment.Record.UserName), Html.Encode(comment.Record.SiteName), new { rel = "nofollow" })%></span>&nbsp;<span>said <%: Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc.GetValueOrDefault()), "#")%></span>
</div>
</li><%

View File

@@ -5,7 +5,7 @@
<div class="archive-trail">
<%=T("Archives").ToString()
%> / <%=Html.Link(Model.ArchiveData.Year.ToString(), Url.BlogArchiveYear(Model.Blog.Slug, Model.ArchiveData.Year))
%> / <%: Html.Link(Model.ArchiveData.Year.ToString(), Url.BlogArchiveYear(Model.Blog.Slug, Model.ArchiveData.Year))
%><%=Model.ArchiveData.Month > 0 ? string.Format(" / {0}", Html.Link(Model.ArchiveData.ToDateTime().ToString("MMMM"), Url.BlogArchiveMonth(Model.Blog.Slug, Model.ArchiveData.Year, Model.ArchiveData.Month))) : ""
%><%=Model.ArchiveData.Day > 0 ? string.Format(" / {0}", Html.Link(Model.ArchiveData.Day.ToString(), Url.BlogArchiveDay(Model.Blog.Slug, Model.ArchiveData.Year, Model.ArchiveData.Month, Model.ArchiveData.Day))) : ""
%>

View File

@@ -9,7 +9,7 @@ foreach (var comment in Model) { %>
</div>
<div class="commentauthor">
<span class="who"><%=Html.LinkOrDefault(Html.Encode(comment.Record.UserName), Html.Encode(comment.Record.SiteName), new { rel = "nofollow" })%></span>&nbsp;<span>said <%=Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc.GetValueOrDefault()), "#")%></span>
<span class="who"><%=Html.LinkOrDefault(Html.Encode(comment.Record.UserName), Html.Encode(comment.Record.SiteName), new { rel = "nofollow" })%></span>&nbsp;<span>said <%: Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc.GetValueOrDefault()), "#")%></span>
</div>
</li><%

View File

@@ -2,6 +2,6 @@
<%@ Import Namespace="Orchard.Mvc.ViewModels"%>
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
<%@ Import Namespace="Orchard.Blogs.Models"%>
<h3><%=Html.Link(Html.Encode(Model.Item.Name), Url.Blog(Model.Item.Slug)) %></h3>
<h3><%: Html.Link(Model.Item.Name, Url.Blog(Model.Item.Slug)) %></h3>
<div class="blog meta"><a href="<%=Url.Blog(Model.Item.Slug) %>"><%: T("{0} post{1}", Model.Item.PostCount, Model.Item.PostCount == 1 ? "" : "s")%></a></div>
<div class="blogdescription"><p><%: Model.Item.Description %></p></div>

View File

@@ -5,7 +5,7 @@
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
<%@ Import Namespace="Orchard.Blogs.Models"%>
<h3><%=Html.Link(Html.Encode(Model.Item.Title), Url.BlogPost(Model.Item)) %></h3>
<h3><%: Html.Link(Model.Item.Title, Url.BlogPost(Model.Item)) %></h3>
<div class="meta"><%=Html.PublishedState(Model.Item) %> | <%Html.Zone("meta");%></div>

View File

@@ -9,7 +9,7 @@ foreach (var comment in Model) { %>
</div>
<div class="commentauthor">
<span class="who"><%=Html.LinkOrDefault(Html.Encode(comment.Record.UserName), Html.Encode(comment.Record.SiteName), new { rel = "nofollow" })%></span>&nbsp;<span>said <%=Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc.GetValueOrDefault()), "#")%></span>
<span class="who"><%=Html.LinkOrDefault(Html.Encode(comment.Record.UserName), Html.Encode(comment.Record.SiteName), new { rel = "nofollow" })%></span>&nbsp;<span>said <%: Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc.GetValueOrDefault()), "#")%></span>
</div>
</li><%

View File

@@ -36,7 +36,7 @@ namespace Orchard.Mvc.Html {
if (selected)
builder.MergeAttribute("selected", "selected");
builder.SetInnerText(html.Encode(text));
builder.SetInnerText(text);
return MvcHtmlString.Create(builder.ToString(TagRenderMode.Normal));
}
@@ -241,23 +241,23 @@ namespace Orchard.Mvc.Html {
#region Link
public static string Link(this HtmlHelper htmlHelper, string linkContents, string href)
public static MvcHtmlString Link(this HtmlHelper htmlHelper, string linkContents, string href)
{
return htmlHelper.Link(linkContents, href, null);
}
public static string Link(this HtmlHelper htmlHelper, string linkContents, string href, object htmlAttributes)
public static MvcHtmlString Link(this HtmlHelper htmlHelper, string linkContents, string href, object htmlAttributes)
{
return htmlHelper.Link(linkContents, href, new RouteValueDictionary(htmlAttributes));
}
public static string Link(this HtmlHelper htmlHelper, string linkContents, string href, IDictionary<string, object> htmlAttributes)
public static MvcHtmlString Link(this HtmlHelper htmlHelper, string linkContents, string href, IDictionary<string, object> htmlAttributes)
{
TagBuilder tagBuilder = new TagBuilder("a")
{ InnerHtml = htmlHelper.Encode(linkContents) };
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("href", href);
return tagBuilder.ToString(TagRenderMode.Normal);
return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
}
#endregion
@@ -336,15 +336,15 @@ namespace Orchard.Mvc.Html {
#region AntiForgeryTokenValueOrchardLink
public static string AntiForgeryTokenValueOrchardLink(this HtmlHelper htmlHelper, string linkContents, string href) {
public static MvcHtmlString AntiForgeryTokenValueOrchardLink(this HtmlHelper htmlHelper, string linkContents, string href) {
return htmlHelper.AntiForgeryTokenValueOrchardLink(linkContents, href, (object)null);
}
public static string AntiForgeryTokenValueOrchardLink(this HtmlHelper htmlHelper, string linkContents, string href, object htmlAttributes) {
public static MvcHtmlString AntiForgeryTokenValueOrchardLink(this HtmlHelper htmlHelper, string linkContents, string href, object htmlAttributes) {
return htmlHelper.AntiForgeryTokenValueOrchardLink(linkContents, href, new RouteValueDictionary(htmlAttributes));
}
public static string AntiForgeryTokenValueOrchardLink(this HtmlHelper htmlHelper, string linkContents, string href, IDictionary<string, object> htmlAttributes) {
public static MvcHtmlString AntiForgeryTokenValueOrchardLink(this HtmlHelper htmlHelper, string linkContents, string href, IDictionary<string, object> htmlAttributes) {
return htmlHelper.Link(linkContents, htmlHelper.AntiForgeryTokenGetUrl(href), htmlAttributes);
}