public override void VisitTagHelperBody(TagHelperBodyIntermediateNode node) { for (var i = 0; i < node.Children.Count; i++) { _children.Add(node.Children[i]); } }
public override void VisitTagHelperBody(TagHelperBodyIntermediateNode node) { // The goal here is to remove leading/trailing whitespace inside component child content. However, // at the time this whitespace pass runs, ComponentChildContent is still TagHelperBody in the tree. RemoveContiguousWhitespace(node.Children, TraversalDirection.Forwards); RemoveContiguousWhitespace(node.Children, TraversalDirection.Backwards); VisitDefault(node); }
public ComponentBodyExtensionNode(TagHelperBodyIntermediateNode bodyNode) { if (bodyNode == null) { throw new ArgumentNullException(nameof(bodyNode)); } Source = bodyNode.Source; for (var i = 0; i < bodyNode.Children.Count; i++) { Children.Add(bodyNode.Children[i]); } for (var i = 0; i < bodyNode.Diagnostics.Count; i++) { Diagnostics.Add(bodyNode.Diagnostics[i]); } }
public virtual void VisitTagHelperBody(TagHelperBodyIntermediateNode node) { VisitDefault(node); }
public override void VisitTagHelperBody(TagHelperBodyIntermediateNode node) { // Wrap the component's children in a ChildContent node if we have some significant // content. if (node.Children.Count == 0) { return; } // If we get a single HTML content node containing only whitespace, // then this is probably a tag that looks like '<MyComponent> </MyComponent> // // We don't want to create a child content for this case, because it can conflict // with a child content that's set via an attribute. We don't want the formatting // of insignificant whitespace to be annoying when setting attributes directly. if (node.Children.Count == 1 && IsIgnorableWhitespace(node.Children[0])) { return; } // From here we fork and behave differently based on whether the component's child content is // implicit or explicit. // // Explicit child content will look like: <MyComponent><ChildContent><div>...</div></ChildContent></MyComponent> // compared with implicit: <MyComponent><div></div></MyComponent> // // Using implicit child content: // 1. All content is grouped into a single child content lambda, and assigned to the property 'ChildContent' // // Using explicit child content: // 1. All content must be contained within 'child content' elements that are direct children // 2. Whitespace outside of 'child content' elements will be ignored (not an error) // 3. Non-whitespace outside of 'child content' elements will cause an error // 4. All 'child content' elements must match parameters on the component (exception for ChildContent, // which is always allowed. // 5. Each 'child content' element will generate its own lambda, and be assigned to the property // that matches the element name. if (!node.Children.OfType <TagHelperIntermediateNode>().Any(t => t.TagHelpers.Any(th => th.IsChildContentTagHelper()))) { // This node has implicit child content. It may or may not have an attribute that matches. var attribute = _component.Component.BoundAttributes .Where(a => string.Equals(a.Name, ComponentsApi.RenderTreeBuilder.ChildContent, StringComparison.Ordinal)) .FirstOrDefault(); _children.Add(RewriteChildContent(attribute, node.Source, node.Children)); return; } // OK this node has explicit child content, we can rewrite it by visiting each node // in sequence, since we: // a) need to rewrite each child content element // b) any significant content outside of a child content is an error for (var i = 0; i < node.Children.Count; i++) { var child = node.Children[i]; if (IsIgnorableWhitespace(child)) { continue; } if (child is TagHelperIntermediateNode tagHelperNode && tagHelperNode.TagHelpers.Any(th => th.IsChildContentTagHelper())) { // This is a child content element var attribute = _component.Component.BoundAttributes .Where(a => string.Equals(a.Name, tagHelperNode.TagName, StringComparison.Ordinal)) .FirstOrDefault(); _children.Add(RewriteChildContent(attribute, child.Source, child.Children)); continue; } // If we get here then this is significant content inside a component with explicit child content. child.Diagnostics.Add(ComponentDiagnosticFactory.Create_ChildContentMixedWithExplicitChildContent(child.Source, _component)); _children.Add(child); } bool IsIgnorableWhitespace(IntermediateNode n) { if (n is HtmlContentIntermediateNode html && html.Children.Count == 1 && html.Children[0] is IntermediateToken token && string.IsNullOrWhiteSpace(token.Content)) { return(true); } return(false); } }