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:
Shannon Deminick
2015-01-02 16:03:46 +11:00

View File

@@ -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("&hellip;");
}
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("&hellip;");
}
lengthReached = true;
}
}
}
}
}
outputtw.Flush();
outputms.Position = 0;
using (TextReader outputtr = new StreamReader(outputms))
{