diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCompletionDataProvider.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCompletionDataProvider.cs index 83fcc03080..dbe9c2ab03 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCompletionDataProvider.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCompletionDataProvider.cs @@ -63,9 +63,11 @@ namespace ICSharpCode.XmlEditor case ' ': // Attribute intellisense. - XmlElementPath path = XmlParser.GetActiveElementStartPath(text, text.Length); - if (path.Elements.Count > 0) { - return GetAttributeCompletionData(path); + if (!XmlParser.IsInsideAttributeValue(text, text.Length)) { + XmlElementPath path = XmlParser.GetActiveElementStartPath(text, text.Length); + if (path.Elements.Count > 0) { + return GetAttributeCompletionData(path); + } } break; diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlParser.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlParser.cs index e47f895ec3..56905da151 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlParser.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlParser.cs @@ -145,9 +145,7 @@ namespace ICSharpCode.XmlEditor return false; } - if (index >= xml.Length) { - index = xml.Length - 1; - } + index = GetCorrectedIndex(xml.Length, index); // Move back one character if the last character is an '=' if (xml[index] == '=') { @@ -202,9 +200,7 @@ namespace ICSharpCode.XmlEditor return String.Empty; } - if (index >= xml.Length) { - index = xml.Length - 1; - } + index = GetCorrectedIndex(xml.Length, index); string name = String.Empty; @@ -299,6 +295,58 @@ namespace ICSharpCode.XmlEditor return false; } + + /// + /// Determines whether the specified index is inside an attribute value. + /// + public static bool IsInsideAttributeValue(string xml, int index) + { + if (xml.Length == 0) { + return false; + } + + index = GetCorrectedIndex(xml.Length, index); + + int elementStartIndex = GetActiveElementStartIndex(xml, index); + if (elementStartIndex == - 1) { + return false; + } + + // Count the number of double quotes and single quotes that exist + // before the first equals sign encountered going backwards to + // the start of the active element. + bool foundEqualsSign = false; + int doubleQuotesCount = 0; + int singleQuotesCount = 0; + char lastQuoteChar = ' '; + for (int i = index; i > elementStartIndex; --i) { + char ch = xml[i]; + if (ch == '=') { + foundEqualsSign = true; + break; + } else if (ch == '\"') { + lastQuoteChar = ch; + ++doubleQuotesCount; + } else if (ch == '\'') { + lastQuoteChar = ch; + ++singleQuotesCount; + } + } + + bool isInside = false; + + if (foundEqualsSign) { + // Odd number of quotes? + if ((lastQuoteChar == '\"') && ((doubleQuotesCount % 2) > 0)) { + isInside = true; + } else if ((lastQuoteChar == '\'') && ((singleQuotesCount %2) > 0)) { + isInside = true; + } + } + + return isInside; + } + /// /// Gets the text of the xml element start tag that the index is /// currently inside. @@ -444,5 +492,21 @@ namespace ICSharpCode.XmlEditor return reversedString.ToString(); } + + /// + /// Ensures that the index is on the last character if it is + /// too large. + /// + /// The length of the string. + /// The current index. + /// The index unchanged if the index is smaller than the + /// length of the string; otherwise it returns length - 1. + static int GetCorrectedIndex(int length, int index) + { + if (index >= length) { + index = length - 1; + } + return index; + } } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Parser/InsideAttributeValueTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Parser/InsideAttributeValueTestFixture.cs new file mode 100644 index 0000000000..0001e21245 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Parser/InsideAttributeValueTestFixture.cs @@ -0,0 +1,102 @@ +// +// +// +// +// $Revision$ +// + +using ICSharpCode.XmlEditor; +using NUnit.Framework; +using System; +using System.Xml; + +namespace XmlEditor.Tests.Parser +{ + [TestFixture] + public class InsideAttributeValueTestFixture + { + [Test] + public void InvalidString() + { + Assert.IsFalse(XmlParser.IsInsideAttributeValue(String.Empty, 10)); + } + + [Test] + public void DoubleQuotesTest1() + { + string xml = " +