From 769f0d97d2e7394434c012b432c811d193203977 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 12 Jul 2017 10:35:09 +0200 Subject: [PATCH 01/20] Added TruncateByWords method + overloads --- src/Umbraco.Web/HtmlStringUtilities.cs | 34 +++++++++ src/Umbraco.Web/UmbracoHelper.cs | 96 +++++++++++++++++++++++--- 2 files changed, 122 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index 24a643b5b0..778bc2b717 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -240,5 +240,39 @@ namespace Umbraco.Web } } } + + /// + /// Returns the length of the words from a html block + /// + /// Html text + /// Amount of words you would like to measure + /// + public int WordsToLength(string html, int words) + { + int wordCount = 0; + int length = 0; + int maxWords = words; + + 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])) + { + length++; + } + } + + return length; + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index 6f3da17254..33fa907e11 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -1457,18 +1457,98 @@ namespace Umbraco.Web /// 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 + public IHtmlString TruncateByWords(DynamicNull html, int words) + { + return new HtmlString(string.Empty); + } + /// + /// 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 + /// + public IHtmlString TruncateByWords(DynamicNull html, int words, bool addElipsis) + { + return new HtmlString(string.Empty); + } - #endregion + /// + /// 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 + /// + public IHtmlString TruncateByWords(DynamicNull html, int words, bool addElipsis, bool treatTagsAsContent) + { + return new HtmlString(string.Empty); + } - #region If + /// + /// 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 + /// + public IHtmlString TruncateByWords(string html, int words) + { + int length = _stringUtilities.WordsToLength(html, words); - /// - /// If the test is true, the string valueIfTrue will be returned, otherwise the valueIfFalse will be returned. - /// - public HtmlString If(bool test, string valueIfTrue, string valueIfFalse) + return Truncate(html, length, true, false); + } + + /// + /// 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 + /// + public IHtmlString TruncateByWords(string html, int words, bool addElipsis) + { + int length = _stringUtilities.WordsToLength(html, words); + + return Truncate(html, length, addElipsis, false); + } + + /// + /// 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 + /// + public IHtmlString TruncateByWords(string html, int words, bool addElipsis, bool treatTagsAsContent) + { + int length =_stringUtilities.WordsToLength(html, words); + + return Truncate(html, length, addElipsis, treatTagsAsContent); + } + + /// + /// 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 + /// + public IHtmlString TruncateByWords(IHtmlString html, int words) + { + int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words); + + return Truncate(html, length, true, false); + } + + /// + /// 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 + /// + public IHtmlString TruncateByWords(IHtmlString html, int words, bool addElipsis) + { + int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words); + + return Truncate(html, length, addElipsis, false); + } + + /// + /// 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 + /// + public IHtmlString TruncateByWords(IHtmlString html, int words, bool addElipsis, bool treatTagsAsContent) + { + int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words); + + return Truncate(html, length, addElipsis, treatTagsAsContent); + } + #endregion + #endregion + + #region If + + /// + /// If the test is true, the string valueIfTrue will be returned, otherwise the valueIfFalse will be returned. + /// + public HtmlString If(bool test, string valueIfTrue, string valueIfFalse) { return test ? new HtmlString(valueIfTrue) : new HtmlString(valueIfFalse); } From cddc6f31166f31bc8a18c44f55befb7f216fe5cb Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 12 Jul 2017 12:28:40 +0200 Subject: [PATCH 02/20] Cleared useless methods --- src/Umbraco.Web/UmbracoHelper.cs | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index 33fa907e11..3f9bc83784 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -1460,26 +1460,6 @@ namespace Umbraco.Web return _stringUtilities.Truncate(html, length, addElipsis, treatTagsAsContent); } #region Truncate by Words - public IHtmlString TruncateByWords(DynamicNull html, int words) - { - return new HtmlString(string.Empty); - } - - /// - /// 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 - /// - public IHtmlString TruncateByWords(DynamicNull html, int words, bool addElipsis) - { - return new HtmlString(string.Empty); - } - - /// - /// 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 - /// - public IHtmlString TruncateByWords(DynamicNull html, int words, bool addElipsis, bool treatTagsAsContent) - { - return new HtmlString(string.Empty); - } /// /// 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 From bb01eca7b7968d3d5c92cc75d88cb51fd9087efa Mon Sep 17 00:00:00 2001 From: Claus Date: Tue, 15 Aug 2017 13:08:30 +0200 Subject: [PATCH 03/20] added a few tests for the new UmbracoHelper methods. --- .../FrontEnd/UmbracoHelperTests.cs | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs index 672b9022e5..f951304874 100644 --- a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs +++ b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs @@ -21,6 +21,21 @@ namespace Umbraco.Tests.FrontEnd Assert.AreEqual("Hello world, this is some…", result); } + /// + /// If a truncated string ends with a space, we should trim the space before appending the ellipsis. + /// + [Test] + public void Truncate_Simple_With_Trimming() + { + var text = "Hello world, this is some text with a link"; + + var helper = new UmbracoHelper(); + + var result = helper.Truncate(text, 26).ToString(); + + Assert.AreEqual("Hello world, this is some…", result); + } + [Test] public void Truncate_Inside_Word() { @@ -78,5 +93,41 @@ namespace Umbraco.Tests.FrontEnd Assert.AreEqual(expectedResult, result); } + + [Test] + public void Truncate_By_Words() + { + var text = "Hello world, this is some text with a link"; + + 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, this is some text with a link"; + + var helper = new UmbracoHelper(); + + var result = helper.TruncateByWords(text, 4).ToString(); + + Assert.AreEqual("Hello world, this is…", result); + } + + [Test] + public void Truncate_By_Words_Mid_Tag() + { + var text = "Hello world, this is some text with a link"; + + var helper = new UmbracoHelper(); + + var result = helper.TruncateByWords(text, 7).ToString(); + + Assert.AreEqual("Hello world, this is some text with…", result); + } } } From 54f86c06f003a41f1e5b381e5de14a5d6991a8d5 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 21 Aug 2017 12:30:16 +0200 Subject: [PATCH 04/20] Fix TruncateByWords to work with tags --- src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs | 2 +- src/Umbraco.Web/HtmlStringUtilities.cs | 13 ++++++++++--- src/Umbraco.Web/UmbracoHelper.cs | 12 ++++++------ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs index f951304874..d886009e00 100644 --- a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs +++ b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs @@ -127,7 +127,7 @@ namespace Umbraco.Tests.FrontEnd var result = helper.TruncateByWords(text, 7).ToString(); - Assert.AreEqual("Hello world, this is some text with…", result); + Assert.AreEqual("Hello world, this is some text with…", result); } } } diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index 778bc2b717..08e73e389d 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Web; using HtmlAgilityPack; @@ -247,12 +248,19 @@ namespace Umbraco.Web /// Html text /// Amount of words you would like to measure /// - public int WordsToLength(string html, int words) + public int WordsToLength(string html, int words, bool tagsAsContent) { int wordCount = 0; int length = 0; int maxWords = words; + string strippedOfTags = Regex.Replace(html, "<.*?>", string.Empty).Trim(); + + if (tagsAsContent == false) + { + html = strippedOfTags; + } + while (length < html.Length) { // Check to see if the current wordCount reached the maxWords allowed @@ -266,12 +274,11 @@ namespace Umbraco.Web wordCount++; // Skip whitespace until the next word - while (length < html.Length && char.IsWhiteSpace(html[length])) + while (length < html.Length && char.IsWhiteSpace(html[length]) && wordCount.Equals(maxWords) == false) { length++; } } - return length; } } diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index 3f9bc83784..6969bc3a60 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -1466,7 +1466,7 @@ namespace Umbraco.Web /// public IHtmlString TruncateByWords(string html, int words) { - int length = _stringUtilities.WordsToLength(html, words); + int length = _stringUtilities.WordsToLength(html, words, false); return Truncate(html, length, true, false); } @@ -1476,7 +1476,7 @@ namespace Umbraco.Web /// public IHtmlString TruncateByWords(string html, int words, bool addElipsis) { - int length = _stringUtilities.WordsToLength(html, words); + int length = _stringUtilities.WordsToLength(html, words, false); return Truncate(html, length, addElipsis, false); } @@ -1486,7 +1486,7 @@ namespace Umbraco.Web /// public IHtmlString TruncateByWords(string html, int words, bool addElipsis, bool treatTagsAsContent) { - int length =_stringUtilities.WordsToLength(html, words); + int length =_stringUtilities.WordsToLength(html, words, treatTagsAsContent); return Truncate(html, length, addElipsis, treatTagsAsContent); } @@ -1496,7 +1496,7 @@ namespace Umbraco.Web /// public IHtmlString TruncateByWords(IHtmlString html, int words) { - int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words); + int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words, false); return Truncate(html, length, true, false); } @@ -1506,7 +1506,7 @@ namespace Umbraco.Web /// public IHtmlString TruncateByWords(IHtmlString html, int words, bool addElipsis) { - int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words); + int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words, false); return Truncate(html, length, addElipsis, false); } @@ -1516,7 +1516,7 @@ namespace Umbraco.Web /// public IHtmlString TruncateByWords(IHtmlString html, int words, bool addElipsis, bool treatTagsAsContent) { - int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words); + int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words, treatTagsAsContent); return Truncate(html, length, addElipsis, treatTagsAsContent); } From 84f684ed3125e9f6df9cb8ba647acff27cd95c6f Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 25 Aug 2017 11:39:13 +0200 Subject: [PATCH 05/20] Truncate with trimming should now work, added some mpore tests for truncate by words methods Fix: Original Truncate method show now be able to trim Add: Added some more tests for Truncate by words to cater for tagsAsContent parameter Fix: In original truncate, currentTextLength prop will be increased everytime a tag is added, this will fix an issue when tagsAsContent is set to true (it would have added an extra char per tag, which would have went over to the next word) --- .../FrontEnd/UmbracoHelperTests.cs | 47 ++++++++++++++++--- src/Umbraco.Web/HtmlStringUtilities.cs | 18 ++++++- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs index d886009e00..1e808ab8b2 100644 --- a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs +++ b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs @@ -95,37 +95,72 @@ namespace Umbraco.Tests.FrontEnd } [Test] - public void Truncate_By_Words() + public void Truncate_By_Words_TagsAsContentOff() { var text = "Hello world, this is some text with a link"; var helper = new UmbracoHelper(); - var result = helper.TruncateByWords(text, 4).ToString(); + var result = helper.TruncateByWords(text, 4, true, false).ToString(); Assert.AreEqual("Hello world, this is…", result); } [Test] - public void Truncate_By_Words_With_Tag() + public void Truncate_By_Words_With_Tag_TagsAsContentOff() { var text = "Hello world, this is some text with a link"; var helper = new UmbracoHelper(); - var result = helper.TruncateByWords(text, 4).ToString(); + var result = helper.TruncateByWords(text, 4, true, false).ToString(); Assert.AreEqual("Hello world, this is…", result); } [Test] - public void Truncate_By_Words_Mid_Tag() + public void Truncate_By_Words_Mid_Tag_TagsAsContentOff() { var text = "Hello world, this is some text with a link"; var helper = new UmbracoHelper(); - var result = helper.TruncateByWords(text, 7).ToString(); + var result = helper.TruncateByWords(text, 7, true, false).ToString(); + + Assert.AreEqual("Hello world, this is some text with…", result); + } + [Test] + public void Truncate_By_Words_TagsAsContentOn() + { + var text = "Hello world, this is some text with a link"; + + var helper = new UmbracoHelper(); + + var result = helper.TruncateByWords(text, 4, true, true).ToString(); + + Assert.AreEqual("Hello world, this is…", result); + } + + [Test] + public void Truncate_By_Words_With_Tag_TagsAsContentOn() + { + var text = "Hello world, this is some text with a link"; + + var helper = new UmbracoHelper(); + + var result = helper.TruncateByWords(text, 4, true, true).ToString(); + + Assert.AreEqual("Hello world, this is…", result); + } + + [Test] + public void Truncate_By_Words_Mid_Tag_TagsAsContentOn() + { + var text = "Hello world, this is some text with a link"; + + var helper = new UmbracoHelper(); + + var result = helper.TruncateByWords(text, 7, true, true).ToString(); Assert.AreEqual("Hello world, this is some text with…", result); } diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index 08e73e389d..166ba44667 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -6,6 +6,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Web; using HtmlAgilityPack; +using Umbraco.Web.WebApi.Filters; namespace Umbraco.Web { @@ -142,6 +143,10 @@ namespace Umbraco.Web { string thisTag = tagStack.Pop(); outputtw.Write(""); + if (treatTagsAsContent) + { + currentTextLength++; + } } if (!isTagClose && currentTag.Length > 0) { @@ -149,6 +154,10 @@ namespace Umbraco.Web { tagStack.Push(currentTag); outputtw.Write("<" + currentTag); + if (treatTagsAsContent) + { + currentTextLength++; + } if (!string.IsNullOrEmpty(tagContents)) { if (tagContents.EndsWith("/")) @@ -236,7 +245,14 @@ namespace Umbraco.Web outputms.Position = 0; using (TextReader outputtr = new StreamReader(outputms)) { - return new HtmlString(outputtr.ReadToEnd().Replace(" ", " ").Trim()); + string result = String.Empty; + + string firsTrim = 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 + result = firsTrim[firsTrim.Length -9] == ' ' ? firsTrim.Remove(firsTrim.Length - 9, 1) : firsTrim; + return new HtmlString(result); } } } From 047a41c05ea57b1c179f4566d0be3b090dd7902b Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 28 Aug 2017 10:14:16 +0200 Subject: [PATCH 06/20] Having a space in a tag is now taken as a char length and not as a space between words --- src/Umbraco.Web/HtmlStringUtilities.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index 166ba44667..1123563f43 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -268,6 +268,7 @@ namespace Umbraco.Web { int wordCount = 0; int length = 0; + int insideTagCounter = length; int maxWords = words; string strippedOfTags = Regex.Replace(html, "<.*?>", string.Empty).Trim(); @@ -284,6 +285,18 @@ namespace Umbraco.Web // Check if current char is part of a word while (length < html.Length && char.IsWhiteSpace(html[length]) == false) { + //Check if we have a space inside a tag and increase the length if we do + if (html[length].Equals('<') && html[length + 1].Equals('/') == false && tagsAsContent) + { + while (html[insideTagCounter].Equals('>') == false) + { + if (html[insideTagCounter].Equals(' ')) + { + length++; + } + insideTagCounter++; + } + } length++; } From 68fd74897fc823533457dfabbea4e6fb3c59a88b Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 28 Aug 2017 10:52:53 +0200 Subject: [PATCH 07/20] Replaced the Regex parse with HtmlAgilityPack parser --- src/Umbraco.Web/HtmlStringUtilities.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index 1123563f43..e2e8a772b6 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -266,15 +266,24 @@ namespace Umbraco.Web /// public int WordsToLength(string html, int words, bool tagsAsContent) { - int wordCount = 0; - int length = 0; - int insideTagCounter = length; - int maxWords = words; + HtmlDocument doc = new HtmlDocument(); - string strippedOfTags = Regex.Replace(html, "<.*?>", string.Empty).Trim(); + int wordCount = 0, + length = 0, + insideTagCounter = length, + maxWords = words; + string strippedOfTags = string.Empty; + + //If tagsAsContent is on, use the string stripped of html tags if (tagsAsContent == false) { + doc.LoadHtml(html); + + foreach (var node in doc.DocumentNode.ChildNodes) + { + strippedOfTags += node.InnerText; + } html = strippedOfTags; } From 039ab8f1d2c2c1fdf7a13b27e16303c5f67b80ee Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 30 Aug 2017 09:18:45 +0200 Subject: [PATCH 08/20] Null check for firstTrim added and fixed typo --- src/Umbraco.Web/HtmlStringUtilities.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index e2e8a772b6..de3d084e0b 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -87,6 +87,8 @@ namespace Umbraco.Web public IHtmlString Truncate(string html, int length, bool addElipsis, bool treatTagsAsContent) { + string hellip = "…"; + using (var outputms = new MemoryStream()) { using (var outputtw = new StreamWriter(outputms)) @@ -231,7 +233,7 @@ namespace Umbraco.Web // Reached truncate limit. if (addElipsis) { - outputtw.Write("…"); + outputtw.Write(hellip); } lengthReached = true; } @@ -247,11 +249,14 @@ namespace Umbraco.Web { string result = String.Empty; - string firsTrim = outputtr.ReadToEnd().Replace(" ", " ").Trim(); - + 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 - result = firsTrim[firsTrim.Length -9] == ' ' ? firsTrim.Remove(firsTrim.Length - 9, 1) : firsTrim; + if (String.IsNullOrEmpty(firstTrim) == false) + { + result = firstTrim[firstTrim.Length - hellip.Length -1] == ' ' ? firstTrim.Remove(firstTrim.Length - hellip.Length -1, 1) : firstTrim; + } return new HtmlString(result); } } From 8c1996a7a1242a9db7ae13066ee615d296b9e05c Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 31 Aug 2017 09:15:02 +0200 Subject: [PATCH 09/20] Changed from the String object qualifier to type qualifier --- src/Umbraco.Web/HtmlStringUtilities.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index de3d084e0b..e4d5b2a4e9 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -247,13 +247,13 @@ namespace Umbraco.Web outputms.Position = 0; using (TextReader outputtr = new StreamReader(outputms)) { - string result = String.Empty; + 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.IsNullOrEmpty(firstTrim) == false) + if (string.IsNullOrWhiteSpace(firstTrim) == false) { result = firstTrim[firstTrim.Length - hellip.Length -1] == ' ' ? firstTrim.Remove(firstTrim.Length - hellip.Length -1, 1) : firstTrim; } From 73937172dce66255f289462e667befe20ef4874e Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 31 Aug 2017 11:43:06 +0200 Subject: [PATCH 10/20] Added check for invalid HTML and sanitization on said HTML Added HtmlSanitization package Added check for invalid HTML and sanitization on WordsToLength and Truncate methods Addes some extra comments --- src/Umbraco.Core/Umbraco.Core.csproj | 3 ++ src/Umbraco.Core/packages.config | 1 + src/Umbraco.Web/HtmlStringUtilities.cs | 38 ++++++++++++++++++++------ src/Umbraco.Web/Umbraco.Web.csproj | 6 ++++ src/Umbraco.Web/packages.config | 2 ++ 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 24fdf32150..6a4305dec7 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -37,6 +37,9 @@ false + + ..\packages\AngleSharp.0.9.9\lib\net45\AngleSharp.dll + ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll True diff --git a/src/Umbraco.Core/packages.config b/src/Umbraco.Core/packages.config index dd00d61ea6..3634d0d25a 100644 --- a/src/Umbraco.Core/packages.config +++ b/src/Umbraco.Core/packages.config @@ -1,5 +1,6 @@  + diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index e4d5b2a4e9..3acdff9c81 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Web; +using Ganss.XSS; using HtmlAgilityPack; using Umbraco.Web.WebApi.Filters; @@ -89,6 +90,18 @@ namespace Umbraco.Web { string hellip = "…"; + HtmlDocument doc = new HtmlDocument(); + HtmlSanitizer sanitizer = new HtmlSanitizer(); + + doc.LoadHtml(html); + + //Check for invalid HTML + if (doc.ParseErrors.Any()) + { + //Sanitize invalid HTML, it will not be pretty, but it will be valid + html = sanitizer.Sanitize(html); + } + using (var outputms = new MemoryStream()) { using (var outputtw = new StreamWriter(outputms)) @@ -255,7 +268,7 @@ namespace Umbraco.Web //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; + result = firstTrim[firstTrim.Length - hellip.Length - 1] == ' ' ? firstTrim.Remove(firstTrim.Length - hellip.Length - 1, 1) : firstTrim; } return new HtmlString(result); } @@ -272,10 +285,13 @@ namespace Umbraco.Web public int WordsToLength(string html, int words, bool tagsAsContent) { HtmlDocument doc = new HtmlDocument(); + HtmlSanitizer sanitizer = new HtmlSanitizer(); + + doc.LoadHtml(html); int wordCount = 0, length = 0, - insideTagCounter = length, + insideTagCounter = 0, maxWords = words; string strippedOfTags = string.Empty; @@ -283,14 +299,21 @@ namespace Umbraco.Web //If tagsAsContent is on, use the string stripped of html tags if (tagsAsContent == false) { - doc.LoadHtml(html); - foreach (var node in doc.DocumentNode.ChildNodes) { strippedOfTags += node.InnerText; } html = strippedOfTags; } + else + { + //Check for invalid HTML + if (doc.ParseErrors.Any()) + { + //Sanitize invalid HTML, it will not be pretty, but it will be valid + html = sanitizer.Sanitize(html); + } + } while (length < html.Length) { @@ -300,14 +323,13 @@ namespace Umbraco.Web while (length < html.Length && char.IsWhiteSpace(html[length]) == false) { //Check if we have a space inside a tag and increase the length if we do + //We ignore the end tag as it is added by the Truncate method if (html[length].Equals('<') && html[length + 1].Equals('/') == false && tagsAsContent) { + insideTagCounter = length; while (html[insideTagCounter].Equals('>') == false) { - if (html[insideTagCounter].Equals(' ')) - { - length++; - } + length++; insideTagCounter++; } } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 9aaab32af9..f942a35adf 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -97,6 +97,9 @@ {07fbc26b-2927-4a22-8d96-d644c667fecc} UmbracoExamine + + ..\packages\AngleSharp.0.9.9\lib\net45\AngleSharp.dll + ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll True @@ -124,6 +127,9 @@ ..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll True + + ..\packages\HtmlSanitizer.3.4.156\lib\net45\HtmlSanitizer.dll + ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll True diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config index daef6ee7fd..ce25d7c26c 100644 --- a/src/Umbraco.Web/packages.config +++ b/src/Umbraco.Web/packages.config @@ -1,10 +1,12 @@  + + From 972d5f8296981397e04e0cd290d8a02b1ac1c677 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 3 Sep 2017 21:17:53 +0200 Subject: [PATCH 11/20] Reverted back to last commit, invalid html check added --- src/Umbraco.Core/Umbraco.Core.csproj | 3 --- src/Umbraco.Core/packages.config | 1 - src/Umbraco.Web/HtmlStringUtilities.cs | 32 ++------------------------ src/Umbraco.Web/Umbraco.Web.csproj | 6 ----- src/Umbraco.Web/packages.config | 2 -- 5 files changed, 2 insertions(+), 42 deletions(-) diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 6a4305dec7..24fdf32150 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -37,9 +37,6 @@ false - - ..\packages\AngleSharp.0.9.9\lib\net45\AngleSharp.dll - ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll True diff --git a/src/Umbraco.Core/packages.config b/src/Umbraco.Core/packages.config index 3634d0d25a..dd00d61ea6 100644 --- a/src/Umbraco.Core/packages.config +++ b/src/Umbraco.Core/packages.config @@ -1,6 +1,5 @@  - diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index 3acdff9c81..f9adfc5175 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Web; -using Ganss.XSS; using HtmlAgilityPack; using Umbraco.Web.WebApi.Filters; @@ -90,18 +89,6 @@ namespace Umbraco.Web { string hellip = "…"; - HtmlDocument doc = new HtmlDocument(); - HtmlSanitizer sanitizer = new HtmlSanitizer(); - - doc.LoadHtml(html); - - //Check for invalid HTML - if (doc.ParseErrors.Any()) - { - //Sanitize invalid HTML, it will not be pretty, but it will be valid - html = sanitizer.Sanitize(html); - } - using (var outputms = new MemoryStream()) { using (var outputtw = new StreamWriter(outputms)) @@ -285,16 +272,13 @@ namespace Umbraco.Web public int WordsToLength(string html, int words, bool tagsAsContent) { HtmlDocument doc = new HtmlDocument(); - HtmlSanitizer sanitizer = new HtmlSanitizer(); - doc.LoadHtml(html); int wordCount = 0, length = 0, - insideTagCounter = 0, maxWords = words; - string strippedOfTags = string.Empty; + bool invalidHtml = doc.ParseErrors.Any(); //If tagsAsContent is on, use the string stripped of html tags if (tagsAsContent == false) @@ -305,15 +289,6 @@ namespace Umbraco.Web } html = strippedOfTags; } - else - { - //Check for invalid HTML - if (doc.ParseErrors.Any()) - { - //Sanitize invalid HTML, it will not be pretty, but it will be valid - html = sanitizer.Sanitize(html); - } - } while (length < html.Length) { @@ -323,14 +298,11 @@ namespace Umbraco.Web while (length < html.Length && char.IsWhiteSpace(html[length]) == false) { //Check if we have a space inside a tag and increase the length if we do - //We ignore the end tag as it is added by the Truncate method if (html[length].Equals('<') && html[length + 1].Equals('/') == false && tagsAsContent) { - insideTagCounter = length; - while (html[insideTagCounter].Equals('>') == false) + while (html[length].Equals('>') == false && invalidHtml == false) { length++; - insideTagCounter++; } } length++; diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index f942a35adf..9aaab32af9 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -97,9 +97,6 @@ {07fbc26b-2927-4a22-8d96-d644c667fecc} UmbracoExamine - - ..\packages\AngleSharp.0.9.9\lib\net45\AngleSharp.dll - ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll True @@ -127,9 +124,6 @@ ..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll True - - ..\packages\HtmlSanitizer.3.4.156\lib\net45\HtmlSanitizer.dll - ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll True diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config index ce25d7c26c..daef6ee7fd 100644 --- a/src/Umbraco.Web/packages.config +++ b/src/Umbraco.Web/packages.config @@ -1,12 +1,10 @@  - - From 4b5c49907c9b84b6499cef9920aaf3bc1ff84ffc Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Sep 2017 10:01:39 +1000 Subject: [PATCH 12/20] switches to constant - comments out what seems to be a totally unused variable --- src/Umbraco.Web/HtmlStringUtilities.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index de3d084e0b..d66c965a51 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -32,6 +32,7 @@ namespace Umbraco.Web { var doc = new HtmlDocument(); doc.LoadHtml("

" + html + "

"); + var targets = new List(); var nodes = doc.DocumentNode.FirstChild.SelectNodes(".//*"); @@ -87,7 +88,7 @@ namespace Umbraco.Web public IHtmlString Truncate(string html, int length, bool addElipsis, bool treatTagsAsContent) { - string hellip = "…"; + const string hellip = "…"; using (var outputms = new MemoryStream()) { @@ -110,7 +111,7 @@ namespace Umbraco.Web isTagClose = false; int ic = 0, - currentLength = 0, + //currentLength = 0, currentTextLength = 0; string currentTag = string.Empty, @@ -217,7 +218,7 @@ namespace Umbraco.Web { var charToWrite = (char)ic; outputtw.Write(charToWrite); - currentLength++; + //currentLength++; } } @@ -253,7 +254,7 @@ namespace Umbraco.Web //Check to see if there is an empty char between the hellip and the output string //if there is, remove it - if (String.IsNullOrEmpty(firstTrim) == false) + if (string.IsNullOrEmpty(firstTrim) == false) { result = firstTrim[firstTrim.Length - hellip.Length -1] == ' ' ? firstTrim.Remove(firstTrim.Length - hellip.Length -1, 1) : firstTrim; } @@ -268,6 +269,7 @@ namespace Umbraco.Web /// /// Html text /// Amount of words you would like to measure + /// /// public int WordsToLength(string html, int words, bool tagsAsContent) { From b2798e38f7608f34e8800778acd74b18c3ab3ff0 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 6 Sep 2017 11:12:14 +0200 Subject: [PATCH 13/20] Replaced html stripping with already existing function, removing unused code --- src/Umbraco.Web/HtmlStringUtilities.cs | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index 7d51197984..ceb1254983 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -271,7 +271,7 @@ namespace Umbraco.Web /// Amount of words you would like to measure /// /// - public int WordsToLength(string html, int words, bool tagsAsContent) + public int WordsToLength(string html, int words) { HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(html); @@ -279,18 +279,8 @@ namespace Umbraco.Web int wordCount = 0, length = 0, maxWords = words; - string strippedOfTags = string.Empty; - bool invalidHtml = doc.ParseErrors.Any(); - //If tagsAsContent is on, use the string stripped of html tags - if (tagsAsContent == false) - { - foreach (var node in doc.DocumentNode.ChildNodes) - { - strippedOfTags += node.InnerText; - } - html = strippedOfTags; - } + html = StripHtmlTags(html, null).ToString(); while (length < html.Length) { @@ -299,14 +289,6 @@ namespace Umbraco.Web // Check if current char is part of a word while (length < html.Length && char.IsWhiteSpace(html[length]) == false) { - //Check if we have a space inside a tag and increase the length if we do - if (html[length].Equals('<') && html[length + 1].Equals('/') == false && tagsAsContent) - { - while (html[length].Equals('>') == false && invalidHtml == false) - { - length++; - } - } length++; } From b1358936b4df7db69269d7cd28a40c6f766b610e Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 6 Sep 2017 11:17:06 +0200 Subject: [PATCH 14/20] Cleaning up tests and useless TruncateByWords functions --- .../FrontEnd/UmbracoHelperTests.cs | 47 +++---------------- src/Umbraco.Web/UmbracoHelper.cs | 28 ++--------- 2 files changed, 10 insertions(+), 65 deletions(-) diff --git a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs index 1e808ab8b2..f0ba027ca4 100644 --- a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs +++ b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs @@ -95,72 +95,37 @@ namespace Umbraco.Tests.FrontEnd } [Test] - public void Truncate_By_Words_TagsAsContentOff() + public void Truncate_By_Words_TagsAsContent() { var text = "Hello world, this is some text with a link"; var helper = new UmbracoHelper(); - var result = helper.TruncateByWords(text, 4, true, false).ToString(); + var result = helper.TruncateByWords(text, 4).ToString(); Assert.AreEqual("Hello world, this is…", result); } [Test] - public void Truncate_By_Words_With_Tag_TagsAsContentOff() + public void Truncate_By_Words_With_Tag_TagsAsContent() { var text = "Hello world, this is some text with a link"; var helper = new UmbracoHelper(); - var result = helper.TruncateByWords(text, 4, true, false).ToString(); + var result = helper.TruncateByWords(text, 4).ToString(); Assert.AreEqual("Hello world, this is…", result); } [Test] - public void Truncate_By_Words_Mid_Tag_TagsAsContentOff() + public void Truncate_By_Words_Mid_Tag_TagsAsContent() { var text = "Hello world, this is some text with a link"; var helper = new UmbracoHelper(); - var result = helper.TruncateByWords(text, 7, true, false).ToString(); - - Assert.AreEqual("Hello world, this is some text with…", result); - } - [Test] - public void Truncate_By_Words_TagsAsContentOn() - { - var text = "Hello world, this is some text with a link"; - - var helper = new UmbracoHelper(); - - var result = helper.TruncateByWords(text, 4, true, true).ToString(); - - Assert.AreEqual("Hello world, this is…", result); - } - - [Test] - public void Truncate_By_Words_With_Tag_TagsAsContentOn() - { - var text = "Hello world, this is some text with a link"; - - var helper = new UmbracoHelper(); - - var result = helper.TruncateByWords(text, 4, true, true).ToString(); - - Assert.AreEqual("Hello world, this is…", result); - } - - [Test] - public void Truncate_By_Words_Mid_Tag_TagsAsContentOn() - { - var text = "Hello world, this is some text with a link"; - - var helper = new UmbracoHelper(); - - var result = helper.TruncateByWords(text, 7, true, true).ToString(); + var result = helper.TruncateByWords(text, 7).ToString(); Assert.AreEqual("Hello world, this is some text with…", result); } diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index 6969bc3a60..cc8bf2bdf4 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -1466,7 +1466,7 @@ namespace Umbraco.Web /// public IHtmlString TruncateByWords(string html, int words) { - int length = _stringUtilities.WordsToLength(html, words, false); + int length = _stringUtilities.WordsToLength(html, words); return Truncate(html, length, true, false); } @@ -1476,19 +1476,9 @@ namespace Umbraco.Web /// public IHtmlString TruncateByWords(string html, int words, bool addElipsis) { - int length = _stringUtilities.WordsToLength(html, words, false); + int length = _stringUtilities.WordsToLength(html, words); return Truncate(html, length, addElipsis, false); - } - - /// - /// 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 - /// - public IHtmlString TruncateByWords(string html, int words, bool addElipsis, bool treatTagsAsContent) - { - int length =_stringUtilities.WordsToLength(html, words, treatTagsAsContent); - - return Truncate(html, length, addElipsis, treatTagsAsContent); } /// @@ -1496,7 +1486,7 @@ namespace Umbraco.Web /// public IHtmlString TruncateByWords(IHtmlString html, int words) { - int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words, false); + int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words); return Truncate(html, length, true, false); } @@ -1506,19 +1496,9 @@ namespace Umbraco.Web /// public IHtmlString TruncateByWords(IHtmlString html, int words, bool addElipsis) { - int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words, false); + int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words); return Truncate(html, length, addElipsis, false); - } - - /// - /// 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 - /// - public IHtmlString TruncateByWords(IHtmlString html, int words, bool addElipsis, bool treatTagsAsContent) - { - int length = _stringUtilities.WordsToLength(html.ToHtmlString(), words, treatTagsAsContent); - - return Truncate(html, length, addElipsis, treatTagsAsContent); } #endregion #endregion From 6a3f94d0e132e62f66124c482b8fe9df471f289f Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 6 Sep 2017 11:19:30 +0200 Subject: [PATCH 15/20] Forgot to clean test names --- src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs index f0ba027ca4..d886009e00 100644 --- a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs +++ b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs @@ -95,7 +95,7 @@ namespace Umbraco.Tests.FrontEnd } [Test] - public void Truncate_By_Words_TagsAsContent() + public void Truncate_By_Words() { var text = "Hello world, this is some text with a link"; @@ -107,7 +107,7 @@ namespace Umbraco.Tests.FrontEnd } [Test] - public void Truncate_By_Words_With_Tag_TagsAsContent() + public void Truncate_By_Words_With_Tag() { var text = "Hello world, this is some text with a link"; @@ -119,7 +119,7 @@ namespace Umbraco.Tests.FrontEnd } [Test] - public void Truncate_By_Words_Mid_Tag_TagsAsContent() + public void Truncate_By_Words_Mid_Tag() { var text = "Hello world, this is some text with a link"; From 851d587d1f0b9523f41969f5221dff70a03aecce Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 6 Sep 2017 11:28:44 +0200 Subject: [PATCH 16/20] Added Html Strip tests --- .../FrontEnd/UmbracoHelperTests.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs index d886009e00..a3de9c2435 100644 --- a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs +++ b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs @@ -129,5 +129,31 @@ namespace Umbraco.Tests.FrontEnd Assert.AreEqual("Hello world, this is some text with…", result); } + + [Test] + public void Strip_All_Html() + { + var text = "Hello world, this is some text with a link"; + + 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, this is some text with a link"; + + string [] tags = {"b"}; + + var helper = new UmbracoHelper(); + + var result = helper.StripHtml(text, tags).ToString(); + + Assert.AreEqual("Hello world, this is some text with a link", result); + } } } From 18d0fec014b13c5a71b9743126274720345884f3 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 6 Sep 2017 12:03:15 +0200 Subject: [PATCH 17/20] Added some trimming and test to StripHtmlTags --- src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs | 12 ++++++++++++ src/Umbraco.Web/HtmlStringUtilities.cs | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs index a3de9c2435..97f12cdaf8 100644 --- a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs +++ b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs @@ -155,5 +155,17 @@ namespace Umbraco.Tests.FrontEnd Assert.AreEqual("Hello world, this is some text with a link", result); } + + [Test] + public void Strip_Invalid_Html() + { + var text = "Hello world, is some text with a link"; + + var helper = new UmbracoHelper(); + + var result = helper.StripHtml(text).ToString(); + + Assert.AreEqual("Hello world, is some text with a link", result); + } } } diff --git a/src/Umbraco.Web/HtmlStringUtilities.cs b/src/Umbraco.Web/HtmlStringUtilities.cs index ceb1254983..a8d82ce79b 100644 --- a/src/Umbraco.Web/HtmlStringUtilities.cs +++ b/src/Umbraco.Web/HtmlStringUtilities.cs @@ -58,7 +58,7 @@ namespace Umbraco.Web { return new HtmlString(html); } - return new HtmlString(doc.DocumentNode.FirstChild.InnerHtml); + return new HtmlString(doc.DocumentNode.FirstChild.InnerHtml.Replace(" ", " ")); } internal string Join(string seperator, params object[] args) From 23950c0cacfb18963e3ae1ef114e6db49732db9d Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 11 Sep 2017 12:22:38 +0200 Subject: [PATCH 18/20] U4-10400 Clear CDF temp files during upgrades --- .../ClientDependencyConfiguration.cs | 57 ++++++++++++++++++- src/Umbraco.Core/Umbraco.Core.csproj | 3 + src/Umbraco.Core/packages.config | 1 + .../Install/Controllers/InstallController.cs | 2 + 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs b/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs index 6fbdec6901..e0d92f52f1 100644 --- a/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs +++ b/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs @@ -1,6 +1,10 @@ using System; -using System.Linq; +using System.Collections.Generic; +using System.IO; +using System.Web; using System.Xml.Linq; +using ClientDependency.Core.CompositeFiles.Providers; +using ClientDependency.Core.Config; using Umbraco.Core.IO; using Umbraco.Core.Logging; @@ -49,5 +53,56 @@ namespace Umbraco.Core.Configuration return false; } + + /// + /// Clears the temporary files stored for the ClientDependency folder + /// + internal bool ClearTempFiles() + { + var cdfTempDirectories = new HashSet(); + foreach (BaseCompositeFileProcessingProvider provider in ClientDependencySettings.Instance + .CompositeFileProcessingProviderCollection) + { + var path = provider.CompositeFilePath.FullName; + cdfTempDirectories.Add(path); + } + + try + { + var relativePath = HttpContext.Current.Server.MapPath(XmlFileMapper.FileMapVirtualFolder); + if (relativePath != null) + { + var directoryInfo = new DirectoryInfo(relativePath); + var path = directoryInfo.FullName; + cdfTempDirectories.Add(path); + } + } + catch (Exception ex) + { + //invalid path format or something... try/catch to be safe + LogHelper.Error("Could not get path from ClientDependency.config", ex); + } + + var noErrorsDeleting = 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("Could not clear temp files", ex); + noErrorsDeleting = false; + } + } + + return noErrorsDeleting; + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 8854c3c4ab..ef7533f471 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -45,6 +45,9 @@ ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll True
+ + ..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll + ..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll True diff --git a/src/Umbraco.Core/packages.config b/src/Umbraco.Core/packages.config index dd00d61ea6..2a84e2d967 100644 --- a/src/Umbraco.Core/packages.config +++ b/src/Umbraco.Core/packages.config @@ -1,6 +1,7 @@  + diff --git a/src/Umbraco.Web/Install/Controllers/InstallController.cs b/src/Umbraco.Web/Install/Controllers/InstallController.cs index 360e35efda..0ad837b239 100644 --- a/src/Umbraco.Web/Install/Controllers/InstallController.cs +++ b/src/Umbraco.Web/Install/Controllers/InstallController.cs @@ -47,6 +47,8 @@ namespace Umbraco.Web.Install.Controllers // Update ClientDependency version var clientDependencyConfig = new ClientDependencyConfiguration(ApplicationContext.Current.ProfilingLogger.Logger); var clientDependencyUpdated = clientDependencyConfig.IncreaseVersionNumber(); + // Delete ClientDependency temp directories to make sure we get fresh caches + var clientDependencyTempFilesDeleted = clientDependencyConfig.ClearTempFiles(); var result = _umbracoContext.Security.ValidateCurrentUser(false); From c55cf75ada217e34a322a4f3dea5d7bbe4fb912f Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 11 Sep 2017 13:30:06 +0200 Subject: [PATCH 19/20] Use HttpContext from the controller --- .../Configuration/ClientDependencyConfiguration.cs | 5 +++-- src/Umbraco.Web/Install/Controllers/InstallController.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs b/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs index e0d92f52f1..b3076f2143 100644 --- a/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs +++ b/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs @@ -57,7 +57,8 @@ namespace Umbraco.Core.Configuration /// /// Clears the temporary files stored for the ClientDependency folder /// - internal bool ClearTempFiles() + /// + internal bool ClearTempFiles(HttpContextBase currentHttpContext) { var cdfTempDirectories = new HashSet(); foreach (BaseCompositeFileProcessingProvider provider in ClientDependencySettings.Instance @@ -69,7 +70,7 @@ namespace Umbraco.Core.Configuration try { - var relativePath = HttpContext.Current.Server.MapPath(XmlFileMapper.FileMapVirtualFolder); + var relativePath = currentHttpContext.Server.MapPath(XmlFileMapper.FileMapVirtualFolder); if (relativePath != null) { var directoryInfo = new DirectoryInfo(relativePath); diff --git a/src/Umbraco.Web/Install/Controllers/InstallController.cs b/src/Umbraco.Web/Install/Controllers/InstallController.cs index 0ad837b239..7e3336e1e8 100644 --- a/src/Umbraco.Web/Install/Controllers/InstallController.cs +++ b/src/Umbraco.Web/Install/Controllers/InstallController.cs @@ -48,7 +48,7 @@ namespace Umbraco.Web.Install.Controllers var clientDependencyConfig = new ClientDependencyConfiguration(ApplicationContext.Current.ProfilingLogger.Logger); var clientDependencyUpdated = clientDependencyConfig.IncreaseVersionNumber(); // Delete ClientDependency temp directories to make sure we get fresh caches - var clientDependencyTempFilesDeleted = clientDependencyConfig.ClearTempFiles(); + var clientDependencyTempFilesDeleted = clientDependencyConfig.ClearTempFiles(HttpContext); var result = _umbracoContext.Security.ValidateCurrentUser(false); From 4356d3f94a0aeb934c872686347750a9b5619e96 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 Sep 2017 13:30:57 +1000 Subject: [PATCH 20/20] publicizes class, fixes up some naming and removes unneeded DirectoryInfo allocations --- .../ClientDependencyConfiguration.cs | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs b/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs index b3076f2143..62cd1ab59c 100644 --- a/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs +++ b/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs @@ -9,8 +9,11 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; namespace Umbraco.Core.Configuration -{ - internal class ClientDependencyConfiguration +{ + /// + /// A utility class for working with CDF config and cache files - use sparingly! + /// + public class ClientDependencyConfiguration { private readonly ILogger _logger; private readonly string _fileName; @@ -25,7 +28,7 @@ namespace Umbraco.Core.Configuration /// /// Changes the version number in ClientDependency.config to a random value to avoid stale caches /// - internal bool IncreaseVersionNumber() + public bool IncreaseVersionNumber() { try { @@ -58,7 +61,7 @@ namespace Umbraco.Core.Configuration /// Clears the temporary files stored for the ClientDependency folder /// /// - internal bool ClearTempFiles(HttpContextBase currentHttpContext) + public bool ClearTempFiles(HttpContextBase currentHttpContext) { var cdfTempDirectories = new HashSet(); foreach (BaseCompositeFileProcessingProvider provider in ClientDependencySettings.Instance @@ -70,12 +73,10 @@ namespace Umbraco.Core.Configuration try { - var relativePath = currentHttpContext.Server.MapPath(XmlFileMapper.FileMapVirtualFolder); - if (relativePath != null) + var fullPath = currentHttpContext.Server.MapPath(XmlFileMapper.FileMapVirtualFolder); + if (fullPath != null) { - var directoryInfo = new DirectoryInfo(relativePath); - var path = directoryInfo.FullName; - cdfTempDirectories.Add(path); + cdfTempDirectories.Add(fullPath); } } catch (Exception ex) @@ -84,7 +85,7 @@ namespace Umbraco.Core.Configuration LogHelper.Error("Could not get path from ClientDependency.config", ex); } - var noErrorsDeleting = true; + var success = true; foreach (var directory in cdfTempDirectories) { var directoryInfo = new DirectoryInfo(directory); @@ -99,11 +100,11 @@ namespace Umbraco.Core.Configuration { // Something could be locking the directory or the was another error, making sure we don't break the upgrade installer LogHelper.Error("Could not clear temp files", ex); - noErrorsDeleting = false; + success = false; } } - return noErrorsDeleting; + return success; } } } \ No newline at end of file