Merge pull request #597 from chrisjsherm/issue-u4-4158
Fix for Truncate function stripping out content between tags. This issue...
This commit is contained in:
@@ -1140,143 +1140,146 @@ namespace Umbraco.Web
|
||||
}
|
||||
public IHtmlString Truncate(string html, int length, bool addElipsis, bool treatTagsAsContent)
|
||||
{
|
||||
using (var outputms = new MemoryStream())
|
||||
{
|
||||
using (var outputtw = new StreamWriter(outputms))
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
using (var tw = new StreamWriter(ms))
|
||||
{
|
||||
tw.Write(html);
|
||||
tw.Flush();
|
||||
ms.Position = 0;
|
||||
var tagStack = new Stack<string>();
|
||||
using (TextReader tr = new StreamReader(ms))
|
||||
{
|
||||
bool IsInsideElement = false;
|
||||
bool lengthReached = false;
|
||||
int ic = 0;
|
||||
int currentLength = 0, currentTextLength = 0;
|
||||
string currentTag = string.Empty;
|
||||
string tagContents = string.Empty;
|
||||
bool insideTagSpaceEncountered = false;
|
||||
bool isTagClose = false;
|
||||
while ((ic = tr.Read()) != -1)
|
||||
{
|
||||
bool write = true;
|
||||
using (var outputms = new MemoryStream())
|
||||
{
|
||||
using (var outputtw = new StreamWriter(outputms))
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
using (var tw = new StreamWriter(ms))
|
||||
{
|
||||
tw.Write(html);
|
||||
tw.Flush();
|
||||
ms.Position = 0;
|
||||
var tagStack = new Stack<string>();
|
||||
|
||||
if (ic == (int)'<')
|
||||
{
|
||||
if (!lengthReached)
|
||||
{
|
||||
IsInsideElement = true;
|
||||
}
|
||||
insideTagSpaceEncountered = false;
|
||||
currentTag = string.Empty;
|
||||
tagContents = string.Empty;
|
||||
isTagClose = false;
|
||||
if (tr.Peek() == (int)'/')
|
||||
{
|
||||
isTagClose = true;
|
||||
}
|
||||
}
|
||||
else if (ic == (int)'>')
|
||||
{
|
||||
//if (IsInsideElement)
|
||||
//{
|
||||
IsInsideElement = false;
|
||||
//if (write)
|
||||
//{
|
||||
// outputtw.Write('>');
|
||||
//}
|
||||
currentTextLength++;
|
||||
if (isTagClose && tagStack.Count > 0)
|
||||
{
|
||||
string thisTag = tagStack.Pop();
|
||||
outputtw.Write("</" + thisTag + ">");
|
||||
}
|
||||
if (!isTagClose && currentTag.Length > 0)
|
||||
{
|
||||
if (!lengthReached)
|
||||
{
|
||||
tagStack.Push(currentTag);
|
||||
outputtw.Write("<" + currentTag);
|
||||
if (tr.Peek() != (int)' ')
|
||||
{
|
||||
if (!string.IsNullOrEmpty(tagContents))
|
||||
{
|
||||
if (tagContents.EndsWith("/"))
|
||||
{
|
||||
//short close
|
||||
tagStack.Pop();
|
||||
}
|
||||
outputtw.Write(tagContents);
|
||||
}
|
||||
outputtw.Write(">");
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsInsideElement)
|
||||
{
|
||||
if (ic == (int)' ')
|
||||
{
|
||||
if (!insideTagSpaceEncountered)
|
||||
{
|
||||
insideTagSpaceEncountered = true;
|
||||
//if (!isTagClose)
|
||||
//{
|
||||
// tagStack.Push(currentTag);
|
||||
//}
|
||||
}
|
||||
}
|
||||
if (!insideTagSpaceEncountered)
|
||||
{
|
||||
currentTag += (char)ic;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsInsideElement || insideTagSpaceEncountered)
|
||||
{
|
||||
write = false;
|
||||
if (insideTagSpaceEncountered)
|
||||
{
|
||||
tagContents += (char)ic;
|
||||
}
|
||||
}
|
||||
if (!IsInsideElement || treatTagsAsContent)
|
||||
{
|
||||
currentTextLength++;
|
||||
}
|
||||
currentLength++;
|
||||
if (currentTextLength <= length || (lengthReached && IsInsideElement))
|
||||
{
|
||||
if (write)
|
||||
{
|
||||
outputtw.Write((char)ic);
|
||||
}
|
||||
}
|
||||
if (!lengthReached && currentTextLength >= length)
|
||||
{
|
||||
//reached truncate point
|
||||
if (addElipsis)
|
||||
{
|
||||
outputtw.Write("…");
|
||||
}
|
||||
lengthReached = true;
|
||||
}
|
||||
using (TextReader tr = new StreamReader(ms))
|
||||
{
|
||||
bool isInsideElement = false,
|
||||
lengthReached = false,
|
||||
insideTagSpaceEncountered = false,
|
||||
isTagClose = false;
|
||||
|
||||
}
|
||||
int ic = 0,
|
||||
currentLength = 0,
|
||||
currentTextLength = 0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
outputtw.Flush();
|
||||
string currentTag = string.Empty,
|
||||
tagContents = string.Empty;
|
||||
|
||||
while ((ic = tr.Read()) != -1)
|
||||
{
|
||||
bool write = true;
|
||||
|
||||
switch ((char)ic)
|
||||
{
|
||||
case '<':
|
||||
if (!lengthReached)
|
||||
{
|
||||
isInsideElement = true;
|
||||
}
|
||||
|
||||
insideTagSpaceEncountered = false;
|
||||
currentTag = string.Empty;
|
||||
tagContents = string.Empty;
|
||||
isTagClose = false;
|
||||
if (tr.Peek() == (int)'/')
|
||||
{
|
||||
isTagClose = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case '>':
|
||||
isInsideElement = false;
|
||||
|
||||
if (isTagClose && tagStack.Count > 0)
|
||||
{
|
||||
string thisTag = tagStack.Pop();
|
||||
outputtw.Write("</" + thisTag + ">");
|
||||
}
|
||||
if (!isTagClose && currentTag.Length > 0)
|
||||
{
|
||||
if (!lengthReached)
|
||||
{
|
||||
tagStack.Push(currentTag);
|
||||
outputtw.Write("<" + currentTag);
|
||||
if (!string.IsNullOrEmpty(tagContents))
|
||||
{
|
||||
if (tagContents.EndsWith("/"))
|
||||
{
|
||||
// No end tag e.g. <br />.
|
||||
tagStack.Pop();
|
||||
}
|
||||
|
||||
outputtw.Write(tagContents);
|
||||
write = true;
|
||||
insideTagSpaceEncountered = false;
|
||||
}
|
||||
outputtw.Write(">");
|
||||
}
|
||||
}
|
||||
// Continue to next iteration of the text reader.
|
||||
continue;
|
||||
|
||||
default:
|
||||
if (isInsideElement)
|
||||
{
|
||||
if (ic == (int)' ')
|
||||
{
|
||||
if (!insideTagSpaceEncountered)
|
||||
{
|
||||
insideTagSpaceEncountered = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!insideTagSpaceEncountered)
|
||||
{
|
||||
currentTag += (char)ic;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (isInsideElement || insideTagSpaceEncountered)
|
||||
{
|
||||
write = false;
|
||||
if (insideTagSpaceEncountered)
|
||||
{
|
||||
tagContents += (char)ic;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isInsideElement || treatTagsAsContent)
|
||||
{
|
||||
currentTextLength++;
|
||||
}
|
||||
|
||||
if (currentTextLength <= length || (lengthReached && isInsideElement))
|
||||
{
|
||||
if (write)
|
||||
{
|
||||
var charToWrite = (char)ic;
|
||||
outputtw.Write(charToWrite);
|
||||
currentLength++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lengthReached && currentTextLength >= length)
|
||||
{
|
||||
// Reached truncate limit.
|
||||
if (addElipsis)
|
||||
{
|
||||
outputtw.Write("…");
|
||||
}
|
||||
lengthReached = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
outputtw.Flush();
|
||||
outputms.Position = 0;
|
||||
using (TextReader outputtr = new StreamReader(outputms))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user