private void FixElement(StringBuilder edit, MetadataControlResolver metadataControlResolver, ITextBuffer textBuffer, DothtmlElementNode element) { // fix element name var metadata = metadataControlResolver.GetMetadata(element.FullTagName); if (metadata != null) { // we have found the metadata for the control if (metadata.FullTagName != element.FullTagName) { // the used name differs from the correct, fix the tag name edit.SetRange(element.TagPrefixToken.StartPosition, element.TagPrefixToken.Length, metadata.TagPrefix); edit.SetRange(element.TagNameToken.StartPosition, element.TagNameToken.Length, metadata.TagName); if (element.CorrespondingEndTag != null) { edit.SetRange(element.CorrespondingEndTag.TagPrefixToken.StartPosition, element.CorrespondingEndTag.TagPrefixToken.Length, metadata.TagPrefix); edit.SetRange(element.CorrespondingEndTag.TagNameToken.StartPosition, element.CorrespondingEndTag.TagNameToken.Length, metadata.TagName); } } // fix attribute names foreach (var attribute in element.Attributes) { var property = metadata.GetProperty(attribute.AttributeName); if (property != null && property.Name != attribute.AttributeName) { // the used name differs from the correct, fix the tag name edit.SetRange(attribute.AttributeNameToken.StartPosition, attribute.AttributeNameToken.Length, property.Name); } } // fix property elements foreach (var child in element.Content.OfType<DothtmlElementNode>()) { var property = metadata.GetProperty(child.FullTagName); if (property != null && property.IsElement && property.Name != child.FullTagName) { // the used name differs from the correct, fix the tag name edit.SetRange(child.TagNameToken.StartPosition, child.TagNameToken.Length, property.Name); if (child.CorrespondingEndTag != null) { edit.SetRange(child.CorrespondingEndTag.TagNameToken.StartPosition, child.CorrespondingEndTag.TagNameToken.Length, property.Name); } } } } }
/// <summary> /// Reads the element. /// </summary> private DothtmlElementNode ReadElement() { var startIndex = CurrentIndex; var node = new DothtmlElementNode() { StartPosition = Peek().StartPosition }; Assert(DothtmlTokenType.OpenTag); Read(); SkipWhitespace(); if (Peek().Type == DothtmlTokenType.Slash) { Read(); SkipWhitespace(); node.IsClosingTag = true; } // element name Assert(DothtmlTokenType.Text); node.TagNameToken = Read(); node.TagName = node.TagNameToken.Text; if (Peek().Type == DothtmlTokenType.Colon) { Read(); node.TagPrefix = node.TagName; node.TagPrefixToken = node.TagNameToken; Assert(DothtmlTokenType.Text); node.TagNameToken = Read(); node.TagName = node.TagNameToken.Text; } SkipWhitespace(); // attributes if (!node.IsClosingTag) { while (Peek().Type == DothtmlTokenType.Text) { var attribute = ReadAttribute(); attribute.ParentElement = node; node.Attributes.Add(attribute); SkipWhitespace(); } if (Peek().Type == DothtmlTokenType.Slash) { Read(); SkipWhitespace(); node.IsSelfClosingTag = true; } } Assert(DothtmlTokenType.CloseTag); Read(); SkipWhitespace(); node.Tokens.AddRange(GetTokensFrom(startIndex)); return node; }
private void ResolveWrongClosingTag(DothtmlElementNode element) { Debug.Assert(element.IsClosingTag); var startElement = ElementHierarchy.Peek() as DothtmlElementNode; Debug.Assert(startElement != null); Debug.Assert(startElement.FullTagName != element.FullTagName); while (startElement.FullTagName != element.FullTagName) { ElementHierarchy.Pop(); if (HtmlWriter.SelfClosingTags.Contains(startElement.FullTagName)) { // automatic immediate close of the tag (for <img src="">) ElementHierarchy.Peek().Content.AddRange(startElement.Content); startElement.Content.Clear(); } else if (AutomaticClosingTags.Contains(startElement.FullTagName)) { // elements than can contain itself like <p> are closed on the first occurance of element with the same name var sameElementIndex = startElement.Content.FindIndex(a => (a as DothtmlElementNode)?.FullTagName == startElement.FullTagName); if (sameElementIndex >= 0) { var count = startElement.Content.Count - sameElementIndex; ElementHierarchy.Peek().Content.AddRange(startElement.Content.Skip(sameElementIndex)); startElement.Content.RemoveRange(sameElementIndex, count); } } // otherwise just pop the element startElement = (DothtmlElementNode)ElementHierarchy.Peek(); } }