Merge remote-tracking branch 'origin/dev-v7' into dev-v7.7
This commit is contained in:
@@ -1,12 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Web;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using ClientDependency.Core.CompositeFiles.Providers;
|
||||||
|
using ClientDependency.Core.Config;
|
||||||
using Umbraco.Core.IO;
|
using Umbraco.Core.IO;
|
||||||
using Umbraco.Core.Logging;
|
using Umbraco.Core.Logging;
|
||||||
|
|
||||||
namespace Umbraco.Core.Configuration
|
namespace Umbraco.Core.Configuration
|
||||||
{
|
{
|
||||||
internal class ClientDependencyConfiguration
|
/// <summary>
|
||||||
|
/// A utility class for working with CDF config and cache files - use sparingly!
|
||||||
|
/// </summary>
|
||||||
|
public class ClientDependencyConfiguration
|
||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly string _fileName;
|
private readonly string _fileName;
|
||||||
@@ -21,7 +28,7 @@ namespace Umbraco.Core.Configuration
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Changes the version number in ClientDependency.config to a random value to avoid stale caches
|
/// Changes the version number in ClientDependency.config to a random value to avoid stale caches
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal bool IncreaseVersionNumber()
|
public bool IncreaseVersionNumber()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -49,5 +56,55 @@ namespace Umbraco.Core.Configuration
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the temporary files stored for the ClientDependency folder
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="currentHttpContext"></param>
|
||||||
|
public bool ClearTempFiles(HttpContextBase currentHttpContext)
|
||||||
|
{
|
||||||
|
var cdfTempDirectories = new HashSet<string>();
|
||||||
|
foreach (BaseCompositeFileProcessingProvider provider in ClientDependencySettings.Instance
|
||||||
|
.CompositeFileProcessingProviderCollection)
|
||||||
|
{
|
||||||
|
var path = provider.CompositeFilePath.FullName;
|
||||||
|
cdfTempDirectories.Add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var fullPath = currentHttpContext.Server.MapPath(XmlFileMapper.FileMapVirtualFolder);
|
||||||
|
if (fullPath != null)
|
||||||
|
{
|
||||||
|
cdfTempDirectories.Add(fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//invalid path format or something... try/catch to be safe
|
||||||
|
LogHelper.Error<ClientDependencyConfiguration>("Could not get path from ClientDependency.config", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
var success = true;
|
||||||
|
foreach (var directory in cdfTempDirectories)
|
||||||
|
{
|
||||||
|
var directoryInfo = new DirectoryInfo(directory);
|
||||||
|
if (directoryInfo.Exists == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
directoryInfo.Delete(true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Something could be locking the directory or the was another error, making sure we don't break the upgrade installer
|
||||||
|
LogHelper.Error<ClientDependencyConfiguration>("Could not clear temp files", ex);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,6 +45,9 @@
|
|||||||
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll</HintPath>
|
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="ClientDependency.Core, Version=1.9.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="HtmlAgilityPack, Version=1.4.9.5, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
|
<Reference Include="HtmlAgilityPack, Version=1.4.9.5, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll</HintPath>
|
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
|
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
|
||||||
|
<package id="ClientDependency" version="1.9.2" targetFramework="net45" />
|
||||||
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="net45" />
|
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="net45" />
|
||||||
<package id="ImageProcessor" version="2.5.3" targetFramework="net45" />
|
<package id="ImageProcessor" version="2.5.3" targetFramework="net45" />
|
||||||
<package id="log4net" version="2.0.8" targetFramework="net45" />
|
<package id="log4net" version="2.0.8" targetFramework="net45" />
|
||||||
|
|||||||
@@ -21,6 +21,21 @@ namespace Umbraco.Tests.FrontEnd
|
|||||||
Assert.AreEqual("Hello world, this is some…", result);
|
Assert.AreEqual("Hello world, this is some…", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If a truncated string ends with a space, we should trim the space before appending the ellipsis.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void Truncate_Simple_With_Trimming()
|
||||||
|
{
|
||||||
|
var text = "Hello world, this is some text <a href='blah'>with a link</a>";
|
||||||
|
|
||||||
|
var helper = new UmbracoHelper();
|
||||||
|
|
||||||
|
var result = helper.Truncate(text, 26).ToString();
|
||||||
|
|
||||||
|
Assert.AreEqual("Hello world, this is some…", result);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Truncate_Inside_Word()
|
public void Truncate_Inside_Word()
|
||||||
{
|
{
|
||||||
@@ -78,5 +93,79 @@ namespace Umbraco.Tests.FrontEnd
|
|||||||
|
|
||||||
Assert.AreEqual(expectedResult, result);
|
Assert.AreEqual(expectedResult, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Truncate_By_Words()
|
||||||
|
{
|
||||||
|
var text = "Hello world, this is some text <a href='blah'>with a link</a>";
|
||||||
|
|
||||||
|
var helper = new UmbracoHelper();
|
||||||
|
|
||||||
|
var result = helper.TruncateByWords(text, 4).ToString();
|
||||||
|
|
||||||
|
Assert.AreEqual("Hello world, this is…", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Truncate_By_Words_With_Tag()
|
||||||
|
{
|
||||||
|
var text = "Hello world, <b>this</b> is some text <a href='blah'>with a link</a>";
|
||||||
|
|
||||||
|
var helper = new UmbracoHelper();
|
||||||
|
|
||||||
|
var result = helper.TruncateByWords(text, 4).ToString();
|
||||||
|
|
||||||
|
Assert.AreEqual("Hello world, <b>this</b> is…", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Truncate_By_Words_Mid_Tag()
|
||||||
|
{
|
||||||
|
var text = "Hello world, this is some text <a href='blah'>with a link</a>";
|
||||||
|
|
||||||
|
var helper = new UmbracoHelper();
|
||||||
|
|
||||||
|
var result = helper.TruncateByWords(text, 7).ToString();
|
||||||
|
|
||||||
|
Assert.AreEqual("Hello world, this is some text <a href='blah'>with…</a>", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Strip_All_Html()
|
||||||
|
{
|
||||||
|
var text = "Hello world, <b>this</b> is some text <a href='blah'>with a link</a>";
|
||||||
|
|
||||||
|
var helper = new UmbracoHelper();
|
||||||
|
|
||||||
|
var result = helper.StripHtml(text, null).ToString();
|
||||||
|
|
||||||
|
Assert.AreEqual("Hello world, this is some text with a link", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Strip_Specific_Html()
|
||||||
|
{
|
||||||
|
var text = "Hello world, <b>this</b> is some text <a href='blah'>with a link</a>";
|
||||||
|
|
||||||
|
string [] tags = {"b"};
|
||||||
|
|
||||||
|
var helper = new UmbracoHelper();
|
||||||
|
|
||||||
|
var result = helper.StripHtml(text, tags).ToString();
|
||||||
|
|
||||||
|
Assert.AreEqual("Hello world, this is some text <a href='blah'>with a link</a>", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Strip_Invalid_Html()
|
||||||
|
{
|
||||||
|
var text = "Hello world, <bthis</b> is some text <a href='blah'>with a link</a>";
|
||||||
|
|
||||||
|
var helper = new UmbracoHelper();
|
||||||
|
|
||||||
|
var result = helper.StripHtml(text).ToString();
|
||||||
|
|
||||||
|
Assert.AreEqual("Hello world, is some text with a link", result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using HtmlAgilityPack;
|
using HtmlAgilityPack;
|
||||||
|
using Umbraco.Web.WebApi.Filters;
|
||||||
|
|
||||||
namespace Umbraco.Web
|
namespace Umbraco.Web
|
||||||
{
|
{
|
||||||
@@ -30,6 +32,7 @@ namespace Umbraco.Web
|
|||||||
{
|
{
|
||||||
var doc = new HtmlDocument();
|
var doc = new HtmlDocument();
|
||||||
doc.LoadHtml("<p>" + html + "</p>");
|
doc.LoadHtml("<p>" + html + "</p>");
|
||||||
|
|
||||||
var targets = new List<HtmlNode>();
|
var targets = new List<HtmlNode>();
|
||||||
|
|
||||||
var nodes = doc.DocumentNode.FirstChild.SelectNodes(".//*");
|
var nodes = doc.DocumentNode.FirstChild.SelectNodes(".//*");
|
||||||
@@ -55,7 +58,7 @@ namespace Umbraco.Web
|
|||||||
{
|
{
|
||||||
return new HtmlString(html);
|
return new HtmlString(html);
|
||||||
}
|
}
|
||||||
return new HtmlString(doc.DocumentNode.FirstChild.InnerHtml);
|
return new HtmlString(doc.DocumentNode.FirstChild.InnerHtml.Replace(" ", " "));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal string Join<TIgnore>(string seperator, params object[] args)
|
internal string Join<TIgnore>(string seperator, params object[] args)
|
||||||
@@ -85,6 +88,8 @@ namespace Umbraco.Web
|
|||||||
|
|
||||||
public IHtmlString Truncate(string html, int length, bool addElipsis, bool treatTagsAsContent)
|
public IHtmlString Truncate(string html, int length, bool addElipsis, bool treatTagsAsContent)
|
||||||
{
|
{
|
||||||
|
const string hellip = "…";
|
||||||
|
|
||||||
using (var outputms = new MemoryStream())
|
using (var outputms = new MemoryStream())
|
||||||
{
|
{
|
||||||
using (var outputtw = new StreamWriter(outputms))
|
using (var outputtw = new StreamWriter(outputms))
|
||||||
@@ -106,7 +111,7 @@ namespace Umbraco.Web
|
|||||||
isTagClose = false;
|
isTagClose = false;
|
||||||
|
|
||||||
int ic = 0,
|
int ic = 0,
|
||||||
currentLength = 0,
|
//currentLength = 0,
|
||||||
currentTextLength = 0;
|
currentTextLength = 0;
|
||||||
|
|
||||||
string currentTag = string.Empty,
|
string currentTag = string.Empty,
|
||||||
@@ -141,6 +146,10 @@ namespace Umbraco.Web
|
|||||||
{
|
{
|
||||||
string thisTag = tagStack.Pop();
|
string thisTag = tagStack.Pop();
|
||||||
outputtw.Write("</" + thisTag + ">");
|
outputtw.Write("</" + thisTag + ">");
|
||||||
|
if (treatTagsAsContent)
|
||||||
|
{
|
||||||
|
currentTextLength++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!isTagClose && currentTag.Length > 0)
|
if (!isTagClose && currentTag.Length > 0)
|
||||||
{
|
{
|
||||||
@@ -148,6 +157,10 @@ namespace Umbraco.Web
|
|||||||
{
|
{
|
||||||
tagStack.Push(currentTag);
|
tagStack.Push(currentTag);
|
||||||
outputtw.Write("<" + currentTag);
|
outputtw.Write("<" + currentTag);
|
||||||
|
if (treatTagsAsContent)
|
||||||
|
{
|
||||||
|
currentTextLength++;
|
||||||
|
}
|
||||||
if (!string.IsNullOrEmpty(tagContents))
|
if (!string.IsNullOrEmpty(tagContents))
|
||||||
{
|
{
|
||||||
if (tagContents.EndsWith("/"))
|
if (tagContents.EndsWith("/"))
|
||||||
@@ -205,7 +218,7 @@ namespace Umbraco.Web
|
|||||||
{
|
{
|
||||||
var charToWrite = (char)ic;
|
var charToWrite = (char)ic;
|
||||||
outputtw.Write(charToWrite);
|
outputtw.Write(charToWrite);
|
||||||
currentLength++;
|
//currentLength++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,7 +234,7 @@ namespace Umbraco.Web
|
|||||||
// Reached truncate limit.
|
// Reached truncate limit.
|
||||||
if (addElipsis)
|
if (addElipsis)
|
||||||
{
|
{
|
||||||
outputtw.Write("…");
|
outputtw.Write(hellip);
|
||||||
}
|
}
|
||||||
lengthReached = true;
|
lengthReached = true;
|
||||||
}
|
}
|
||||||
@@ -235,10 +248,59 @@ namespace Umbraco.Web
|
|||||||
outputms.Position = 0;
|
outputms.Position = 0;
|
||||||
using (TextReader outputtr = new StreamReader(outputms))
|
using (TextReader outputtr = new StreamReader(outputms))
|
||||||
{
|
{
|
||||||
return new HtmlString(outputtr.ReadToEnd().Replace(" ", " ").Trim());
|
string result = string.Empty;
|
||||||
|
|
||||||
|
string firstTrim = outputtr.ReadToEnd().Replace(" ", " ").Trim();
|
||||||
|
|
||||||
|
//Check to see if there is an empty char between the hellip and the output string
|
||||||
|
//if there is, remove it
|
||||||
|
if (string.IsNullOrWhiteSpace(firstTrim) == false)
|
||||||
|
{
|
||||||
|
result = firstTrim[firstTrim.Length - hellip.Length - 1] == ' ' ? firstTrim.Remove(firstTrim.Length - hellip.Length - 1, 1) : firstTrim;
|
||||||
|
}
|
||||||
|
return new HtmlString(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the length of the words from a html block
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="html">Html text</param>
|
||||||
|
/// <param name="words">Amount of words you would like to measure</param>
|
||||||
|
/// <param name="tagsAsContent"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int WordsToLength(string html, int words)
|
||||||
|
{
|
||||||
|
HtmlDocument doc = new HtmlDocument();
|
||||||
|
doc.LoadHtml(html);
|
||||||
|
|
||||||
|
int wordCount = 0,
|
||||||
|
length = 0,
|
||||||
|
maxWords = words;
|
||||||
|
|
||||||
|
html = StripHtmlTags(html, null).ToString();
|
||||||
|
|
||||||
|
while (length < html.Length)
|
||||||
|
{
|
||||||
|
// Check to see if the current wordCount reached the maxWords allowed
|
||||||
|
if (wordCount.Equals(maxWords)) break;
|
||||||
|
// Check if current char is part of a word
|
||||||
|
while (length < html.Length && char.IsWhiteSpace(html[length]) == false)
|
||||||
|
{
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
wordCount++;
|
||||||
|
|
||||||
|
// Skip whitespace until the next word
|
||||||
|
while (length < html.Length && char.IsWhiteSpace(html[length]) && wordCount.Equals(maxWords) == false)
|
||||||
|
{
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ namespace Umbraco.Web.Install.Controllers
|
|||||||
// Update ClientDependency version
|
// Update ClientDependency version
|
||||||
var clientDependencyConfig = new ClientDependencyConfiguration(ApplicationContext.Current.ProfilingLogger.Logger);
|
var clientDependencyConfig = new ClientDependencyConfiguration(ApplicationContext.Current.ProfilingLogger.Logger);
|
||||||
var clientDependencyUpdated = clientDependencyConfig.IncreaseVersionNumber();
|
var clientDependencyUpdated = clientDependencyConfig.IncreaseVersionNumber();
|
||||||
|
// Delete ClientDependency temp directories to make sure we get fresh caches
|
||||||
|
var clientDependencyTempFilesDeleted = clientDependencyConfig.ClearTempFiles(HttpContext);
|
||||||
|
|
||||||
var result = _umbracoContext.Security.ValidateCurrentUser(false);
|
var result = _umbracoContext.Security.ValidateCurrentUser(false);
|
||||||
|
|
||||||
|
|||||||
@@ -1439,18 +1439,58 @@ namespace Umbraco.Web
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IHtmlString Truncate(string html, int length, bool addElipsis, bool treatTagsAsContent)
|
public IHtmlString Truncate(string html, int length, bool addElipsis, bool treatTagsAsContent)
|
||||||
{
|
{
|
||||||
return _stringUtilities.Truncate(html, length, addElipsis, treatTagsAsContent);
|
return _stringUtilities.Truncate(html, length, addElipsis, treatTagsAsContent);
|
||||||
}
|
}
|
||||||
|
#region Truncate by Words
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates a string to a given amount of words, can add a elipsis at the end (...). Method checks for open html tags, and makes sure to close them
|
||||||
|
/// </summary>
|
||||||
|
public IHtmlString TruncateByWords(string html, int words)
|
||||||
|
{
|
||||||
|
int length = _stringUtilities.WordsToLength(html, words);
|
||||||
|
|
||||||
#endregion
|
return Truncate(html, length, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
#region If
|
/// <summary>
|
||||||
|
/// Truncates a string to a given amount of words, can add a elipsis at the end (...). Method checks for open html tags, and makes sure to close them
|
||||||
|
/// </summary>
|
||||||
|
public IHtmlString TruncateByWords(string html, int words, bool addElipsis)
|
||||||
|
{
|
||||||
|
int length = _stringUtilities.WordsToLength(html, words);
|
||||||
|
|
||||||
/// <summary>
|
return Truncate(html, length, addElipsis, false);
|
||||||
/// If the test is true, the string valueIfTrue will be returned, otherwise the valueIfFalse will be returned.
|
}
|
||||||
/// </summary>
|
|
||||||
public HtmlString If(bool test, string valueIfTrue, string valueIfFalse)
|
/// <summary>
|
||||||
|
/// Truncates a string to a given amount of words, can add a elipsis at the end (...). Method checks for open html tags, and makes sure to close them
|
||||||
|
/// </summary>
|
||||||
|
public IHtmlString TruncateByWords(IHtmlString html, int words)
|
||||||
|
{
|
||||||
|
int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words);
|
||||||
|
|
||||||
|
return Truncate(html, length, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates a string to a given amount of words, can add a elipsis at the end (...). Method checks for open html tags, and makes sure to close them
|
||||||
|
/// </summary>
|
||||||
|
public IHtmlString TruncateByWords(IHtmlString html, int words, bool addElipsis)
|
||||||
|
{
|
||||||
|
int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words);
|
||||||
|
|
||||||
|
return Truncate(html, length, addElipsis, false);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region If
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the test is true, the string valueIfTrue will be returned, otherwise the valueIfFalse will be returned.
|
||||||
|
/// </summary>
|
||||||
|
public HtmlString If(bool test, string valueIfTrue, string valueIfFalse)
|
||||||
{
|
{
|
||||||
return test ? new HtmlString(valueIfTrue) : new HtmlString(valueIfFalse);
|
return test ? new HtmlString(valueIfTrue) : new HtmlString(valueIfFalse);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user