diff --git a/src/AddIns/BackendBindings/AspNet.Mvc/Project/AspNet.Mvc.csproj b/src/AddIns/BackendBindings/AspNet.Mvc/Project/AspNet.Mvc.csproj
index 3eb7704d3b..6fede1304a 100644
--- a/src/AddIns/BackendBindings/AspNet.Mvc/Project/AspNet.Mvc.csproj
+++ b/src/AddIns/BackendBindings/AspNet.Mvc/Project/AspNet.Mvc.csproj
@@ -115,6 +115,11 @@
+
+
+
+
+
@@ -198,8 +203,14 @@
+
+
+ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}
+ ICSharpCode.AvalonEdit
+ False
+
{2748AD25-9C63-4E12-877B-4DCE96FBED54}
ICSharpCode.SharpDevelop
diff --git a/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/CharacterReader.cs b/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/CharacterReader.cs
new file mode 100644
index 0000000000..74d0070082
--- /dev/null
+++ b/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/CharacterReader.cs
@@ -0,0 +1,85 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+
+namespace ICSharpCode.AspNet.Mvc.Folding
+{
+ public class CharacterReader
+ {
+ public const int EndOfCharacters = -1;
+
+ TextReader reader;
+
+ public CharacterReader(string html)
+ : this(new StringReader(html))
+ {
+ }
+
+ public CharacterReader(TextReader reader)
+ {
+ this.reader = reader;
+ }
+
+ public bool Read()
+ {
+ CurrentCharacter = reader.Read();
+ Offset++;
+ return HasMoreCharactersToRead();
+ }
+
+ bool HasMoreCharactersToRead()
+ {
+ return CurrentCharacter != EndOfCharacters;
+ }
+
+ public int Offset { get; private set; }
+
+ public int PreviousOffset {
+ get { return Offset - 1; }
+ }
+
+ public int CurrentCharacter { get; private set; }
+
+ public bool IsLetterOrDigit()
+ {
+ return Char.IsLetterOrDigit((char)CurrentCharacter);
+ }
+
+ public bool IsLessThanSign()
+ {
+ return CurrentCharacter == '<';
+ }
+
+ public bool IsGreaterThanSign()
+ {
+ return CurrentCharacter == '>';
+ }
+
+ public bool IsForwardSlash()
+ {
+ return CurrentCharacter == '/';
+ }
+
+ public bool IsNextCharacterForwardSlash()
+ {
+ return reader.Peek() == '/';
+ }
+
+ public bool IsSpace()
+ {
+ return CurrentCharacter == ' ';
+ }
+
+ public bool IsDoubleQuote()
+ {
+ return CurrentCharacter == '\"';
+ }
+
+ public bool IsSingleQuote()
+ {
+ return CurrentCharacter == '\'';
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/HtmlElementFold.cs b/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/HtmlElementFold.cs
new file mode 100644
index 0000000000..c7f3bc876a
--- /dev/null
+++ b/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/HtmlElementFold.cs
@@ -0,0 +1,56 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.AvalonEdit.Folding;
+
+namespace ICSharpCode.AspNet.Mvc.Folding
+{
+ public class HtmlElementFold : NewFolding
+ {
+ string elementName = String.Empty;
+
+ public HtmlElementFold()
+ {
+ }
+
+ public string ElementName {
+ get { return elementName; }
+ set {
+ elementName = value;
+ UpdateFoldName();
+ }
+ }
+
+ void UpdateFoldName()
+ {
+ Name = String.Format("<{0}>", elementName);
+ }
+
+ public override bool Equals(object obj)
+ {
+ var rhs = obj as HtmlElementFold;
+ if (rhs != null) {
+ return
+ (elementName == rhs.ElementName) &&
+ (StartOffset == rhs.StartOffset) &&
+ (EndOffset == rhs.EndOffset);
+ }
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return String.Format(
+ "[HtmlElementFold Name='{0}', StartOffset={1}, EndOffset={2}]",
+ Name,
+ StartOffset,
+ EndOffset);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/HtmlNode.cs b/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/HtmlNode.cs
new file mode 100644
index 0000000000..e7cc615f19
--- /dev/null
+++ b/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/HtmlNode.cs
@@ -0,0 +1,37 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Text;
+
+namespace ICSharpCode.AspNet.Mvc.Folding
+{
+ public class HtmlNode
+ {
+ StringBuilder nodeValue = new StringBuilder();
+
+ public string Value {
+ get { return GetElementNameBeforeSpaceCharacter(); }
+ }
+
+ string GetElementNameBeforeSpaceCharacter()
+ {
+ string elementName = nodeValue.ToString();
+ return GetTextBeforeSpaceCharacter(elementName);
+ }
+
+ string GetTextBeforeSpaceCharacter(string text)
+ {
+ int spaceIndex = text.IndexOf(' ');
+ if (spaceIndex > 0) {
+ return text.Substring(0, spaceIndex);
+ }
+ return text;
+ }
+
+ public void Append(int character)
+ {
+ nodeValue.Append((char)character);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/SimpleWebFormsHtmlReader.cs b/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/SimpleWebFormsHtmlReader.cs
new file mode 100644
index 0000000000..cb921018e2
--- /dev/null
+++ b/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/SimpleWebFormsHtmlReader.cs
@@ -0,0 +1,111 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using System.Text;
+
+namespace ICSharpCode.AspNet.Mvc.Folding
+{
+ public class SimpleWebFormsHtmlReader
+ {
+ CharacterReader reader;
+ HtmlNode currentNode = new HtmlNode();
+
+ public SimpleWebFormsHtmlReader(string html)
+ : this(new StringReader(html))
+ {
+ }
+
+ public SimpleWebFormsHtmlReader(TextReader reader)
+ : this(new CharacterReader(reader))
+ {
+ }
+
+ public SimpleWebFormsHtmlReader(CharacterReader reader)
+ {
+ this.reader = reader;
+ }
+
+ public string Value {
+ get { return currentNode.Value; }
+ }
+
+ public int Offset { get; private set; }
+ public int Length { get; private set; }
+
+ public int EndOffset {
+ get { return Offset + Length; }
+ }
+
+ public bool IsEmptyElement { get; private set; }
+ public bool IsEndElement { get; private set; }
+
+ public bool IsStartElement {
+ get { return !IsEndElement; }
+ }
+
+ public bool Read()
+ {
+ while (ReadNextCharacter()) {
+ if (IsElementStartCharacter()) {
+ currentNode = new HtmlNode();
+ IsEndElement = reader.IsNextCharacterForwardSlash();
+ IsEmptyElement = false;
+ Offset = reader.PreviousOffset;
+ } else if (IsElementEndCharacter()) {
+ Length = reader.Offset - Offset;
+ return true;
+ } else if (reader.IsForwardSlash()) {
+ IsEmptyElement = !IsEndElement;
+ } else if (IsElementNameCharacter()) {
+ currentNode.Append(reader.CurrentCharacter);
+ } else if (reader.IsDoubleQuote()) {
+ ReadDoubleQuotedString();
+ } else if (reader.IsSingleQuote()) {
+ ReadSingleQuotedString();
+ }
+ }
+ return false;
+ }
+
+ bool ReadNextCharacter()
+ {
+ return reader.Read();
+ }
+
+ bool IsElementStartCharacter()
+ {
+ return reader.IsLessThanSign();
+ }
+
+ bool IsElementEndCharacter()
+ {
+ return reader.IsGreaterThanSign();
+ }
+
+ bool IsElementNameCharacter()
+ {
+ return reader.IsLetterOrDigit() || reader.IsSpace();
+ }
+
+ void ReadDoubleQuotedString()
+ {
+ ReadUntil(() => reader.IsDoubleQuote());
+ }
+
+ void ReadUntil(Func match)
+ {
+ while (ReadNextCharacter()) {
+ if (match()) {
+ return;
+ }
+ }
+ }
+
+ void ReadSingleQuotedString()
+ {
+ ReadUntil(() => reader.IsSingleQuote());
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/WebFormsHtmlFoldParser.cs b/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/WebFormsHtmlFoldParser.cs
new file mode 100644
index 0000000000..236154e446
--- /dev/null
+++ b/src/AddIns/BackendBindings/AspNet.Mvc/Project/Src/Folding/WebFormsHtmlFoldParser.cs
@@ -0,0 +1,66 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using ICSharpCode.AvalonEdit.Folding;
+
+namespace ICSharpCode.AspNet.Mvc.Folding
+{
+ public class WebFormsHtmlFoldParser
+ {
+ List folds = new List();
+ Stack foldStack = new Stack();
+ SimpleWebFormsHtmlReader htmlReader;
+
+ public IEnumerable GetFolds(string html)
+ {
+ ClearPreviousFolds();
+ htmlReader = new SimpleWebFormsHtmlReader(html);
+ while (htmlReader.Read()) {
+ if (htmlReader.IsEmptyElement) {
+ // No folds for empty elements.
+ } else if (htmlReader.IsEndElement) {
+ AddFoldForCompletedElement();
+ } else {
+ SaveFoldStartOnStack();
+ }
+ }
+ SortFoldsByStartOffset();
+ return folds;
+ }
+
+ void ClearPreviousFolds()
+ {
+ folds.Clear();
+ }
+
+ void SaveFoldStartOnStack()
+ {
+ var fold = new HtmlElementFold() {
+ ElementName = htmlReader.Value,
+ StartOffset = htmlReader.Offset
+ };
+ foldStack.Push(fold);
+ }
+
+ void AddFoldForCompletedElement()
+ {
+ if (foldStack.Any()) {
+ var fold = foldStack.Pop();
+ if (fold.ElementName == htmlReader.Value) {
+ fold.EndOffset = htmlReader.EndOffset;
+ folds.Add(fold);
+ } else {
+ AddFoldForCompletedElement();
+ }
+ }
+ }
+
+ void SortFoldsByStartOffset()
+ {
+ folds.Sort((fold1, fold2) => fold1.StartOffset.CompareTo(fold2.StartOffset));
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/AspNet.Mvc/Test/AspNet.Mvc.Tests.csproj b/src/AddIns/BackendBindings/AspNet.Mvc/Test/AspNet.Mvc.Tests.csproj
index a7f03462ac..26486ef4fa 100644
--- a/src/AddIns/BackendBindings/AspNet.Mvc/Test/AspNet.Mvc.Tests.csproj
+++ b/src/AddIns/BackendBindings/AspNet.Mvc/Test/AspNet.Mvc.Tests.csproj
@@ -103,6 +103,9 @@
+
+
+
@@ -124,6 +127,10 @@
+
+ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}
+ ICSharpCode.AvalonEdit
+
{2748AD25-9C63-4E12-877B-4DCE96FBED54}
ICSharpCode.SharpDevelop
@@ -149,6 +156,7 @@
+
\ No newline at end of file
diff --git a/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/Folding/HtmlElementFoldTests.cs b/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/Folding/HtmlElementFoldTests.cs
new file mode 100644
index 0000000000..936279eefd
--- /dev/null
+++ b/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/Folding/HtmlElementFoldTests.cs
@@ -0,0 +1,105 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.AspNet.Mvc.Folding;
+using NUnit.Framework;
+
+namespace AspNet.Mvc.Tests.Folding
+{
+ [TestFixture]
+ public class HtmlElementFoldTests
+ {
+ HtmlElementFold fold;
+ HtmlElementFold lhs;
+ HtmlElementFold rhs;
+
+ void CreateHtmlElementFoldWithElementName(string elementName)
+ {
+ fold = new HtmlElementFold() { ElementName = elementName };
+ }
+
+ void CreateHtmlElementFoldsForComparison()
+ {
+ lhs = new HtmlElementFold();
+ rhs = new HtmlElementFold();
+ }
+
+ [Test]
+ public void Name_HtmlFoldCreatedUsingElementName_ReturnsElementNameInsideTags()
+ {
+ CreateHtmlElementFoldWithElementName("p");
+
+ Assert.AreEqual("
", fold.Name);
+ }
+
+ [Test]
+ public void Equals_AllPropertiesAreTheSame_ReturnsTrue()
+ {
+ CreateHtmlElementFoldsForComparison();
+
+ bool result = lhs.Equals(rhs);
+
+ Assert.IsTrue(result);
+ }
+
+ [Test]
+ public void Equals_NullCompared_ReturnsFalse()
+ {
+ CreateHtmlElementFoldsForComparison();
+
+ bool result = lhs.Equals(null);
+
+ Assert.IsFalse(result);
+ }
+
+ [Test]
+ public void Equals_DifferentElementNames_ReturnsFalse()
+ {
+ CreateHtmlElementFoldsForComparison();
+ lhs.ElementName = "Test1";
+ rhs.ElementName = "Test";
+
+ bool result = lhs.Equals(rhs);
+
+ Assert.IsFalse(result);
+ }
+
+ [Test]
+ public void Equals_DifferentStartOffsets_ReturnsFalse()
+ {
+ CreateHtmlElementFoldsForComparison();
+ lhs.StartOffset = 0;
+ rhs.StartOffset = 100;
+
+ bool result = lhs.Equals(rhs);
+
+ Assert.IsFalse(result);
+ }
+
+ [Test]
+ public void Equals_DifferentEndOffsets_ReturnsFalse()
+ {
+ CreateHtmlElementFoldsForComparison();
+ lhs.EndOffset = 0;
+ rhs.EndOffset = 100;
+
+ bool result = lhs.Equals(rhs);
+
+ Assert.IsFalse(result);
+ }
+
+ [Test]
+ public void ToString_ElementNameAndOffsetsSet_ReturnsFoldNameAndOffsets()
+ {
+ CreateHtmlElementFoldWithElementName("foo");
+ fold.StartOffset = 1;
+ fold.EndOffset = 10;
+
+ string text = fold.ToString();
+
+ string expectedText = "[HtmlElementFold Name='', StartOffset=1, EndOffset=10]";
+ Assert.AreEqual(expectedText, text);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/Folding/WebFormsHtmlFoldParserTests.cs b/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/Folding/WebFormsHtmlFoldParserTests.cs
new file mode 100644
index 0000000000..fa12832051
--- /dev/null
+++ b/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/Folding/WebFormsHtmlFoldParserTests.cs
@@ -0,0 +1,159 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using ICSharpCode.AspNet.Mvc.Folding;
+using ICSharpCode.AvalonEdit.Folding;
+using NUnit.Framework;
+
+namespace AspNet.Mvc.Tests.Folding
+{
+ [TestFixture]
+ public class WebFormsHtmlFoldParserTests
+ {
+ WebFormsHtmlFoldParser parser;
+ List folds;
+
+ void CreateParser()
+ {
+ parser = new WebFormsHtmlFoldParser();
+ }
+
+ void GetFolds(string text)
+ {
+ folds = parser.GetFolds(text).ToList();
+ }
+
+ [Test]
+ public void GetFolds_ParagraphStartAndEndTag_ReturnsOneFoldForParagraphTag()
+ {
+ CreateParser();
+
+ string text =
+ "\r\n" +
+ "
";
+
+ GetFolds(text);
+
+ var expectedFolds = new HtmlElementFold[] {
+ new HtmlElementFold() {
+ ElementName = "p",
+ StartOffset = 0,
+ EndOffset = 9
+ }
+ };
+
+ CollectionAssert.AreEqual(expectedFolds, folds);
+ }
+
+ [Test]
+ public void GetFolds_HtmlWithSingleParagraphStartAndEndTag_ReturnsTwoFolds()
+ {
+ CreateParser();
+
+ string text =
+ "\r\n" +
+ "\r\n" +
+ "
\r\n" +
+ "";
+
+ GetFolds(text);
+
+ var expectedFolds = new HtmlElementFold[] {
+ new HtmlElementFold() {
+ ElementName = "html",
+ StartOffset = 0,
+ EndOffset = 26
+ },
+ new HtmlElementFold() {
+ ElementName = "p",
+ StartOffset = 8,
+ EndOffset = 17
+ }
+ };
+
+ CollectionAssert.AreEqual(expectedFolds, folds);
+ }
+
+ [Test]
+ public void GetFolds_GetFoldsCalledTwiceForParagraphStartAndEndTag_ReturnsOneFoldForParagraphTag()
+ {
+ CreateParser();
+
+ string text =
+ "\r\n" +
+ "
";
+
+ GetFolds(text);
+ GetFolds(text);
+
+ var expectedFolds = new HtmlElementFold[] {
+ new HtmlElementFold() {
+ ElementName = "p",
+ StartOffset = 0,
+ EndOffset = 9
+ }
+ };
+
+ CollectionAssert.AreEqual(expectedFolds, folds);
+ }
+
+ [Test]
+ public void GetFolds_ParagraphTagsWithUnclosedBoldTagInside_ReturnsOneFoldForParagraphTag()
+ {
+ CreateParser();
+
+ string text =
+ "\r\n" +
+ "\r\n" +
+ "
";
+
+ GetFolds(text);
+
+ var expectedFolds = new HtmlElementFold[] {
+ new HtmlElementFold() {
+ ElementName = "p",
+ StartOffset = 0,
+ EndOffset = 14
+ }
+ };
+
+ CollectionAssert.AreEqual(expectedFolds, folds);
+ }
+
+ [Test]
+ public void GetFolds_EndParagraphTag_ReturnsNoFolds()
+ {
+ CreateParser();
+
+ GetFolds("
");
+
+ Assert.AreEqual(0, folds.Count);
+ }
+
+ [Test]
+ public void GetFolds_DivTagWithClassAttribute_ReturnsOneFold()
+ {
+ CreateParser();
+
+ string text =
+ "\r\n" +
+ "
\r\n";
+
+ GetFolds(text);
+
+ var expectedFolds = new HtmlElementFold[] {
+ new HtmlElementFold() {
+ ElementName = "div",
+ StartOffset = 0,
+ EndOffset = 25
+ }
+ };
+
+ CollectionAssert.AreEqual(expectedFolds, folds);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/Folding/WebFormsHtmlReaderTests.cs b/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/Folding/WebFormsHtmlReaderTests.cs
new file mode 100644
index 0000000000..cc54d29a6b
--- /dev/null
+++ b/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/Folding/WebFormsHtmlReaderTests.cs
@@ -0,0 +1,324 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using ICSharpCode.AspNet.Mvc.Folding;
+using NUnit.Framework;
+
+namespace AspNet.Mvc.Tests.Folding
+{
+ public class WebFormsHtmlReaderTests
+ {
+ SimpleWebFormsHtmlReader htmlReader;
+
+ void CreateHtmlReader(string html)
+ {
+ htmlReader = new SimpleWebFormsHtmlReader(html);
+ }
+
+ [Test]
+ public void Value_ReadSingleParagraphTag_ReturnsParagraphTagName()
+ {
+ CreateHtmlReader("");
+ htmlReader.Read();
+
+ string value = htmlReader.Value;
+
+ Assert.AreEqual("p", value);
+ }
+
+ [Test]
+ public void Read_EmptyString_ReturnsFalse()
+ {
+ CreateHtmlReader(String.Empty);
+
+ bool result = htmlReader.Read();
+
+ Assert.IsFalse(result);
+ }
+
+ [Test]
+ public void Read_ReadSingleParagraphTagHtml_ReturnsTrue()
+ {
+ CreateHtmlReader("
");
+
+ bool result = htmlReader.Read();
+
+ Assert.IsTrue(result);
+ }
+
+ [Test]
+ public void Read_ReadTwiceFromSingleParagraphTag_SecondReadReturnsFalse()
+ {
+ CreateHtmlReader("
");
+
+ bool result = htmlReader.Read();
+ result = htmlReader.Read();
+
+ Assert.IsFalse(result);
+ }
+
+ [Test]
+ public void Offset_SingleParagraphTagAtStartOfString_ReturnsZero()
+ {
+ CreateHtmlReader("
");
+ htmlReader.Read();
+
+ int offset = htmlReader.Offset;
+
+ Assert.AreEqual(0, offset);
+ }
+
+ [Test]
+ public void Length_SingleParagraphTagAtStartOfString_ReturnsThree()
+ {
+ CreateHtmlReader("
");
+ htmlReader.Read();
+
+ int length = htmlReader.Length;
+
+ Assert.AreEqual(3, length);
+ }
+
+ [Test]
+ public void Offset_SingleParagraphTagOnSecondLine_IsAfterCarriageReturnAndLineFeedAndReturnsTwo()
+ {
+ CreateHtmlReader("\r\n
");
+ htmlReader.Read();
+
+ int offset = htmlReader.Offset;
+
+ Assert.AreEqual(2, offset);
+ }
+
+ [Test]
+ public void Length_SingleParagraphTagOnSecondLine_ReturnsThreeForParagraphNodeRead()
+ {
+ CreateHtmlReader("\r\n
");
+ htmlReader.Read();
+
+ int length = htmlReader.Length;
+
+ Assert.AreEqual(3, length);
+ }
+
+ [Test]
+ public void Value_ReadSingleLineBreakTag_ReturnsLineBreakTagName()
+ {
+ CreateHtmlReader("
");
+ htmlReader.Read();
+
+ string value = htmlReader.Value;
+
+ Assert.AreEqual("br", value);
+ }
+
+ [Test]
+ public void Length_ReadSingleLineBreakTag_ReturnsFour()
+ {
+ CreateHtmlReader("
");
+ htmlReader.Read();
+
+ int length = htmlReader.Length;
+
+ Assert.AreEqual(4, length);
+ }
+
+ [Test]
+ public void Value_ReadParagraphTagFollowedByBoldTag_ReturnsBoldTagName()
+ {
+ CreateHtmlReader("
");
+ htmlReader.Read();
+ htmlReader.Read();
+
+ string value = htmlReader.Value;
+
+ Assert.AreEqual("b", value);
+ }
+
+ [Test]
+ public void Offset_ReadParagraphTagFollowedByBoldTag_ReturnsThree()
+ {
+ CreateHtmlReader("
");
+ htmlReader.Read();
+ htmlReader.Read();
+
+ int offset = htmlReader.Offset;
+
+ Assert.AreEqual(3, offset);
+ }
+
+ [Test]
+ public void Value_ReadParagraphTagFollowedByEndParagraphTag_ReturnsParagraphTagName()
+ {
+ CreateHtmlReader("
");
+ htmlReader.Read();
+ htmlReader.Read();
+
+ string value = htmlReader.Value;
+
+ Assert.AreEqual("p", value);
+ }
+
+ [Test]
+ public void IsEndElement_ReadParagraphTagFollowedByEndParagraphTag_ReturnsTrue()
+ {
+ CreateHtmlReader("");
+ htmlReader.Read();
+ htmlReader.Read();
+
+ bool result = htmlReader.IsEndElement;
+
+ Assert.IsTrue(result);
+ }
+
+ [Test]
+ public void IsEmptyElement_ReadEmptyBreakTagElement_ReturnsTrue()
+ {
+ CreateHtmlReader("
");
+ htmlReader.Read();
+
+ bool result = htmlReader.IsEmptyElement;
+
+ Assert.IsTrue(result);
+ }
+
+ [Test]
+ public void IsEmptyElement_ReadParagraphTagFollowedByEndParagraphTag_ReturnsFalse()
+ {
+ CreateHtmlReader("");
+ htmlReader.Read();
+ htmlReader.Read();
+
+ bool result = htmlReader.IsEmptyElement;
+
+ Assert.IsFalse(result);
+ }
+
+ [Test]
+ public void Length_ReadParagraphTagFollowedByEndParagraphTag_ReturnsFour()
+ {
+ CreateHtmlReader("");
+ htmlReader.Read();
+ htmlReader.Read();
+
+ int length = htmlReader.Length;
+
+ Assert.AreEqual(4, length);
+ }
+
+ [Test]
+ public void IsStartElement_ReadSingleParagraphTag_ReturnTrue()
+ {
+ CreateHtmlReader("");
+ htmlReader.Read();
+
+ bool result = htmlReader.IsStartElement;
+
+ Assert.IsTrue(result);
+ }
+
+ [Test]
+ public void IsEmptyElement_ReadEmptyBreakTagFollowedbySingleParagraphTag_ReturnFalse()
+ {
+ CreateHtmlReader("
");
+ htmlReader.Read();
+ htmlReader.Read();
+
+ bool result = htmlReader.IsEmptyElement;
+
+ Assert.IsFalse(result);
+ }
+
+ [Test]
+ public void IsStartElement_ReadEmptyBreakTag_ReturnsTrue()
+ {
+ CreateHtmlReader("
");
+ htmlReader.Read();
+
+ bool result = htmlReader.IsStartElement;
+
+ Assert.IsTrue(result);
+ }
+
+ [Test]
+ public void IsStartElement_ReadParagraphTagFollowedByEndParagraphTag_ReturnsFalse()
+ {
+ CreateHtmlReader("
");
+ htmlReader.Read();
+ htmlReader.Read();
+
+ bool result = htmlReader.IsStartElement;
+
+ Assert.IsFalse(result);
+ }
+
+ [Test]
+ public void Value_ReadParagraphTagsContainingText_ReturnsParagraphTagName()
+ {
+ CreateHtmlReader("abcdef
");
+ htmlReader.Read();
+ htmlReader.Read();
+
+ string value = htmlReader.Value;
+
+ Assert.AreEqual("p", value);
+ }
+
+ [Test]
+ public void Value_ReadDivStartTagWithClassAttribute_ReturnsDivTagName()
+ {
+ CreateHtmlReader("");
+ htmlReader.Read();
+
+ string value = htmlReader.Value;
+
+ Assert.AreEqual("div", value);
+ }
+
+ [Test]
+ public void Value_ScriptStartTagWithForwardSlashInTypeAttribute_ReturnsScriptTagName()
+ {
+ CreateHtmlReader("