mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Merge branch '1.9.x' into dev
# Conflicts: # src/Orchard.Web/Orchard.Web.csproj
This commit is contained in:
@@ -193,5 +193,35 @@ namespace Orchard.Tests.Mvc.Html {
|
||||
Assert.AreEqual(@"<label for=""prefix_SomeString"">bar</label>", result.ToString());
|
||||
}
|
||||
private class FooController : Controller { }
|
||||
|
||||
[Test]
|
||||
public void Ellipsize_DontCutHtmlEncodedChars() {
|
||||
//arrange
|
||||
var viewContext = new ViewContext();
|
||||
var viewDataContainer = new Mock<IViewDataContainer>();
|
||||
var html = new HtmlHelper(viewContext, viewDataContainer.Object);
|
||||
|
||||
//act
|
||||
var result = html.Ellipsize("foo & bar", 5);
|
||||
|
||||
//assert
|
||||
Assert.AreEqual("foo & \u2026", result.ToString());
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Excerpt_DontCutHtmlEncodedChars() {
|
||||
//arrange
|
||||
var viewContext = new ViewContext();
|
||||
var viewDataContainer = new Mock<IViewDataContainer>();
|
||||
var html = new HtmlHelper(viewContext, viewDataContainer.Object);
|
||||
|
||||
//act
|
||||
var result = html.Excerpt("<p>foo & bar</p>", 7);
|
||||
|
||||
//assert
|
||||
Assert.AreEqual("foo & \u2026", result.ToString());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -52,7 +52,7 @@ namespace Orchard.Tests.Utility.Extensions {
|
||||
[Test]
|
||||
public void Ellipsize_LongStringTruncatedToNearestWord() {
|
||||
const string toEllipsize = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed purus quis purus orci aliquam.";
|
||||
Assert.That(toEllipsize.Ellipsize(46), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur …"));
|
||||
Assert.That(toEllipsize.Ellipsize(46), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur\u00A0\u2026"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@@ -22,6 +22,7 @@ namespace Orchard.Core.Contents {
|
||||
var contentTypeDefinitions = _contentDefinitionManager.ListTypeDefinitions().OrderBy(d => d.Name);
|
||||
builder.AddImageSet("content")
|
||||
.Add(T("Content"), "1.4", menu => menu
|
||||
.Permission(Permissions.EditOwnContent)
|
||||
.Add(T("Content Items"), "1", item => item.Action("List", "Admin", new { area = "Contents", id = "" }).LocalNav()));
|
||||
var contentTypes = contentTypeDefinitions.Where(ctd => ctd.Settings.GetModel<ContentTypeSettings>().Creatable).OrderBy(ctd => ctd.DisplayName);
|
||||
if (contentTypes.Any()) {
|
||||
|
@@ -14,6 +14,7 @@
|
||||
var promptOnNavigate = element.data("prompt-on-navigate");
|
||||
var showSaveWarning = element.data("show-save-warning");
|
||||
var addButton = element.find(".button.add");
|
||||
var saveButton = $('.button.save');
|
||||
var removeAllButton = element.find(".button.remove");
|
||||
var template =
|
||||
'<li><div data-id="{contentItemId}" class="media-library-picker-item"><div class="thumbnail">{thumbnail}<div class="overlay"><h3>{title}</h3></div></div></div><a href="#" data-id="{contentItemId}" class="media-library-picker-remove">' + removeText + '</a>' + pipe + '<a href="{editLink}?ReturnUrl=' + returnUrl + '">' + editText + '</a></li>';
|
||||
@@ -28,10 +29,12 @@
|
||||
var itemsCount = element.find(".media-library-picker-item").length;
|
||||
|
||||
if(!multiple && itemsCount > 0) {
|
||||
addButton.hide();
|
||||
addButton.hide();
|
||||
saveButton.show();
|
||||
}
|
||||
else {
|
||||
addButton.show();
|
||||
saveButton.hide();
|
||||
}
|
||||
|
||||
if(itemsCount > 1) {
|
||||
|
@@ -6,6 +6,8 @@
|
||||
|
||||
.media-library-modal-window #media-library-main-selection-select {
|
||||
display: inherit;
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
}
|
||||
|
||||
.media-library-modal-window #main {
|
||||
|
@@ -35,7 +35,7 @@ namespace Orchard.Tokens.Providers {
|
||||
// {Text.Format:<formatstring>}
|
||||
.Token(
|
||||
token => FilterTokenParam("Format:", token),
|
||||
(token, d) => String.Format(d, token))
|
||||
(token, d) => String.Format(token, d))
|
||||
// {Text.TrimEnd:<chars|number>}
|
||||
.Token(token => FilterTokenParam("TrimEnd:", token), TrimEnd)
|
||||
.Token("UrlEncode", HttpUtility.UrlEncode)
|
||||
@@ -54,7 +54,7 @@ namespace Orchard.Tokens.Providers {
|
||||
return token.StartsWith(tokenName, StringComparison.OrdinalIgnoreCase) ? token.Substring(tokenName.Length) : null;
|
||||
}
|
||||
|
||||
private static string TrimEnd(string token, string param) {
|
||||
private static string TrimEnd(string param, string token) {
|
||||
if (String.IsNullOrEmpty(param)) {
|
||||
return token;
|
||||
}
|
||||
|
@@ -59,6 +59,7 @@
|
||||
<Compile Include="StubClock.cs" />
|
||||
<Compile Include="StubOrchardServices.cs" />
|
||||
<Compile Include="StubWorkContextAccessor.cs" />
|
||||
<Compile Include="TextTokenTests.cs" />
|
||||
<Compile Include="UserTokenTests.cs" />
|
||||
<Compile Include="TokenManagerTests.cs" />
|
||||
<Compile Include="TestTokenProvider.cs" />
|
||||
|
121
src/Orchard.Web/Modules/Orchard.Tokens/Tests/TextTokenTests.cs
Normal file
121
src/Orchard.Web/Modules/Orchard.Tokens/Tests/TextTokenTests.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System.Web;
|
||||
using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Tokens.Implementation;
|
||||
using Orchard.Tokens.Providers;
|
||||
|
||||
namespace Orchard.Tokens.Tests {
|
||||
[TestFixture]
|
||||
public class TextTokenTests {
|
||||
private IContainer _container;
|
||||
private ITokenizer _tokenizer;
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<Tokenizer>().As<ITokenizer>();
|
||||
builder.RegisterType<TokenManager>().As<ITokenManager>();
|
||||
builder.RegisterType<TextTokens>().As<ITokenProvider>();
|
||||
builder.RegisterType<TestTokenProvider>().As<ITokenProvider>();
|
||||
_container = builder.Build();
|
||||
_tokenizer = _container.Resolve<ITokenizer>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLimitWhenStringShorterThanLimit() {
|
||||
var str = "foo bar baz";
|
||||
var result = _tokenizer.Replace("{Text.Limit:" + (str.Length + 1) + "}", new { Text = str });
|
||||
Assert.That(result, Is.EqualTo("foo bar baz"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLimitWhenStringLengthEqualsLimit() {
|
||||
var str = "foo bar baz";
|
||||
var result = _tokenizer.Replace("{Text.Limit:" + str.Length + "}", new { Text = str });
|
||||
Assert.That(result, Is.EqualTo("foo bar baz"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLimitWhenStringLongerThanLimit() {
|
||||
var str = "foo bar baz";
|
||||
var result = _tokenizer.Replace("{Text.Limit:" + (str.Length - 1) + "}", new { Text = str });
|
||||
Assert.That(result, Is.EqualTo("foo bar ba"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLimitWhenStringEmpty() {
|
||||
var str = "";
|
||||
var result = _tokenizer.Replace("{Text.Limit:" + (str.Length - 1) + "}", new { Text = str });
|
||||
Assert.That(result, Is.EqualTo(""));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLimitWhenEllipsisSpecifed() {
|
||||
var str = "foo bar baz";
|
||||
var result = _tokenizer.Replace("{Text.Limit:" + (str.Length - 1) + ",...}", new { Text = str });
|
||||
Assert.That(result, Is.EqualTo("foo bar ba..."));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFormat() {
|
||||
var str = "bar";
|
||||
var result = _tokenizer.Replace("{Text.Format:foo {0} baz}", new { Text = str });
|
||||
Assert.That(result, Is.EqualTo("foo bar baz"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestTrimEnd() {
|
||||
var str = "foo ";
|
||||
var result = _tokenizer.Replace("{Text.TrimEnd: }", new { Text = str });
|
||||
Assert.That(result, Is.EqualTo("foo"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestTrimEndNumber() {
|
||||
var str = "foobarbaz";
|
||||
var result = _tokenizer.Replace("{Text.TrimEnd:3}", new { Text = str });
|
||||
Assert.That(result, Is.EqualTo("foobar"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestTrimEndWhenEmptyArg() {
|
||||
var str = "foobarbaz";
|
||||
var result = _tokenizer.Replace("{Text.TrimEnd:}", new { Text = str });
|
||||
Assert.That(result, Is.EqualTo("foobarbaz"));
|
||||
}
|
||||
|
||||
[TestCase("foo<bar", "foo%3cbar")]
|
||||
[TestCase("foo>bar", "foo%3ebar")]
|
||||
[TestCase("foo'bar", "foo%27bar")]
|
||||
[TestCase("foo\"bar", "foo%22bar")]
|
||||
[TestCase("foo bar", "foo+bar")]
|
||||
public void TestUrlEncode(string str, string expected) {
|
||||
var result = _tokenizer.Replace("{Text.UrlEncode}", new { Text = str });
|
||||
Assert.That(result, Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
[TestCase("foo<bar", "foo<bar")]
|
||||
[TestCase("foo>bar", "foo>bar")]
|
||||
[TestCase("foo&bar", "foo&bar")]
|
||||
[TestCase("foo\"bar", "foo"bar")]
|
||||
[TestCase("foo'bar", "foo'bar")]
|
||||
public void TestHtmlEncode(string str, string expected) {
|
||||
var result = _tokenizer.Replace("{Text.HtmlEncode}", new { Text = str }, new ReplaceOptions { Encoding = ReplaceOptions.NoEncode });
|
||||
Assert.That(result, Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestJavaScriptEncode() {
|
||||
var str = "f\"oo<bar>ba'z";
|
||||
var result = _tokenizer.Replace("{Text.JavaScriptEncode}", new { Text = str }, new ReplaceOptions { Encoding = ReplaceOptions.NoEncode });
|
||||
Assert.That(result, Is.EqualTo(HttpUtility.JavaScriptStringEncode(str)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLineEncode() {
|
||||
var str = "foo" + System.Environment.NewLine + "bar" + System.Environment.NewLine + "baz";
|
||||
var result = _tokenizer.Replace("{Text.LineEncode}", new { Text = str }, new ReplaceOptions { Encoding = ReplaceOptions.NoEncode });
|
||||
Assert.That(result, Is.EqualTo("foo<br />bar<br />baz"));
|
||||
}
|
||||
}
|
||||
}
|
@@ -39,7 +39,12 @@ namespace Orchard.Widgets {
|
||||
widget.Classes.Add("widget-" + widgetPart.Name);
|
||||
|
||||
// Widget__Name__[Name]
|
||||
displaying.ShapeMetadata.Alternates.Add("Widget__Name__" + widgetPart.Name);
|
||||
if (widgetPart.Name.Contains("-")) {
|
||||
displaying.ShapeMetadata.Alternates.Add("Widget__Name__" + widgetPart.Name.Replace("-", "__"));
|
||||
}
|
||||
else {
|
||||
displaying.ShapeMetadata.Alternates.Add("Widget__Name__" + widgetPart.Name);
|
||||
}
|
||||
}
|
||||
|
||||
// Adding other css classes to the widget.
|
||||
|
@@ -248,11 +248,10 @@
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets. -->
|
||||
<Target Name="BeforeBuild">
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. -->
|
||||
<Target Name="BeforeBuild">
|
||||
<CallTarget Targets="CopySqlCeBinaries" />
|
||||
</Target>
|
||||
</Target>
|
||||
<Target Name="ExcludeRootBinariesDeployment">
|
||||
<ItemGroup>
|
||||
<RootBinFiles Include="bin\*">
|
||||
|
@@ -92,7 +92,7 @@ namespace Orchard.ContentManagement {
|
||||
}
|
||||
|
||||
private void ForType(params string[] contentTypeNames) {
|
||||
if (contentTypeNames != null && contentTypeNames.Length != 0) {
|
||||
if (contentTypeNames != null) {
|
||||
var contentTypeIds = contentTypeNames.Select(GetContentTypeRecordId).ToArray();
|
||||
// don't use the IN operator if not needed for performance reasons
|
||||
if (contentTypeNames.Length == 1) {
|
||||
|
@@ -183,11 +183,11 @@ namespace Orchard.Mvc.Html {
|
||||
#region Ellipsize
|
||||
|
||||
public static IHtmlString Ellipsize(this HtmlHelper htmlHelper, string text, int characterCount) {
|
||||
return new HtmlString(htmlHelper.Encode(text).Ellipsize(characterCount));
|
||||
return new HtmlString(htmlHelper.Encode(text.Ellipsize(characterCount)));
|
||||
}
|
||||
|
||||
public static IHtmlString Ellipsize(this HtmlHelper htmlHelper, string text, int characterCount, string ellipsis) {
|
||||
return new HtmlString(htmlHelper.Encode(text).Ellipsize(characterCount, ellipsis));
|
||||
return new HtmlString(htmlHelper.Encode(text.Ellipsize(characterCount, ellipsis)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -195,8 +195,7 @@ namespace Orchard.Mvc.Html {
|
||||
#region Excerpt
|
||||
|
||||
public static MvcHtmlString Excerpt(this HtmlHelper html, string markup, int length) {
|
||||
|
||||
return MvcHtmlString.Create(markup.RemoveTags().Ellipsize(length));
|
||||
return MvcHtmlString.Create(html.Encode(HttpUtility.HtmlDecode(markup.RemoveTags()).Ellipsize(length)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@@ -181,6 +181,11 @@ namespace Orchard.Mvc.ViewEngines.Razor {
|
||||
|
||||
private string _tenantPrefix;
|
||||
public override string Href(string path, params object[] pathParts) {
|
||||
if (path.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
|
||||
|| path.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) {
|
||||
return path;
|
||||
}
|
||||
|
||||
if (_tenantPrefix == null) {
|
||||
_tenantPrefix = WorkContext.Resolve<ShellSettings>().RequestUrlPrefix ?? "";
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ namespace Orchard.Utility.Extensions {
|
||||
}
|
||||
|
||||
public static string Ellipsize(this string text, int characterCount) {
|
||||
return text.Ellipsize(characterCount, " …");
|
||||
return text.Ellipsize(characterCount, "\u00A0\u2026");
|
||||
}
|
||||
|
||||
public static string Ellipsize(this string text, int characterCount, string ellipsis, bool wordBoundary = false) {
|
||||
|
Reference in New Issue
Block a user