public void TryCloseTag(ITextChange textChange, IList <TextManipulation> manipulations)
        {
            var currentTag = _state.ParseCurrentTagName();

            if (textChange.NewText == "/" && !string.IsNullOrEmpty(currentTag) && currentTag != "/")
            {
                var  text = _text.Span;
                int  pos  = _state.ParserPos;
                char c    = ' ';
                while (char.IsWhiteSpace(c) && text.Length > pos + 1)
                {
                    pos++;
                    c = text[pos];
                }

                bool tagAlreadyClosed = c == '>';
                if (!tagAlreadyClosed)
                {
                    manipulations.Add(TextManipulation.Insert(_position + 1, $">"));
                }
                else
                {
                    var closingTagPos = FindClosingTag(currentTag, pos + 1);
                    if (closingTagPos != null)
                    {
                        manipulations.Add(TextManipulation.Insert(_position + 1, $">"));
                        manipulations.Add(TextManipulation.Delete(_position + 1, closingTagPos.Value - _position));
                    }
                }
            }
        }
示例#2
0
        private void SynchronizeStartAndEndTag(ITextChange textChange, List <TextManipulation> maniplations)
        {
            if (!textChange.NewText.All(n => char.IsLetterOrDigit(n) || XmlNameSpecialCharacters.Contains(n)))
            {
                return;
            }

            string startTag      = _state.ParseCurrentTagName();
            int?   maybeTagStart = _state.CurrentValueStart;

            if (maybeTagStart == null)
            {
                return;
            }

            int startPos = maybeTagStart.Value; // add 1 to take opening < into account

            if (startTag.EndsWith("/"))
            {
                return; // start tag is self-closing
            }
            if (textChange.NewPosition < startPos || textChange.NewPosition > startPos + startTag.Length)
            {
                return; //we are not editing tag name
            }

            XmlParser searchEndTag = _state.Clone();

            if (searchEndTag.SeekClosingTag())
            {
                string endTag = searchEndTag.ParseCurrentTagName();
                if (endTag[0] != '/')
                {
                    return;
                }

                maybeTagStart = searchEndTag.CurrentValueStart;
                if (maybeTagStart == null)
                {
                    return;
                }

                int endPos = maybeTagStart.Value; // add 1 to take opening < into account

                // reverse change to start tag
                startTag = textChange.ReverseOn(startTag, startPos);

                bool isTheSameTag = endTag.Length > 0 && endTag.Substring(1) == startTag;
                if (isTheSameTag)
                {
                    maniplations.AddRange(textChange.AsManipulations(endPos - startPos));
                }
            }
        }