static string[] EnsureCorrectNesting(MarkupWriter writer, TagDefinition tagDefinition) { if (tagDefinition == null) { return new string[] { } } ; var injection = new List <string>(); // If we're not allowed to have any parents at all, close them all down if (tagDefinition.BlockedParents.Union(tagDefinition.BlockedDirectParents).Intersect(TagDefinition.AllTags).Any()) { while (writer.OpenTags.Count > 0) { writer.CloseTag(); } } // Keep closing tags until we get out from under any disallowed direct parents while ( tagDefinition.BlockedDirectParents.Any() && writer.OpenTags.Any() && tagDefinition.BlockedDirectParents.Contains(writer.OpenTags.Peek())) { writer.CloseTag(); } // If we have to be withing a particular direct parent, keep closing tags until we find one while ( tagDefinition.RequiredDirectParents.Any() && writer.OpenTags.Any() && !tagDefinition.RequiredDirectParents.Contains(writer.OpenTags.Peek())) { writer.CloseTag(); } // Keep closing tags until we get out from under any disallowed parents while ( tagDefinition.BlockedParents.Any() && writer.OpenTags.Intersect(tagDefinition.BlockedParents).Any()) { writer.CloseTag(); } // If we have to be within a specific parent, inject it if (tagDefinition.RequiredDirectParents.Any()) { var directParentInjectionCandidates = ( from dpt in tagDefinition.RequiredDirectParents where !dpt.Equals(TagDefinition.TagRoot) select dpt).ToArray(); var haveRequiredDirectParent = (writer.OpenTags.Count == 0 && tagDefinition.RequiredDirectParents.Contains(TagDefinition.TagRoot)) || (writer.OpenTags.Any() && directParentInjectionCandidates.Contains(writer.OpenTags.First())); if (!haveRequiredDirectParent) { var injectionTag = writer.GetTagDefinition(directParentInjectionCandidates.First()); InjectParent(writer, injection, injectionTag); } } if (tagDefinition.RequiredParents.Any()) { var haveRequiredParent = writer.OpenTags.Intersect(tagDefinition.RequiredParents).Any(); if (!haveRequiredParent) { var injectionTag = writer.GetTagDefinition(tagDefinition.RequiredParents.First()); InjectParent(writer, injection, injectionTag); } } // If any injection has occurred, record the tag that caused it so we can collapse it later if (injection.Any()) { injection.Insert(0, tagDefinition.TagName); } return(injection.Distinct().ToArray()); }
private static void InjectParent(MarkupWriter writer, List <string> injection, TagDefinition injectionTag) { injection.Add(injectionTag.TagName); injection.AddRange(EnsureCorrectNesting(writer, injectionTag)); writer.OpenTag(injectionTag, null); }