public override void VisitMarkupElement(MarkupElementIntermediateNode node) { // We need to restore the state after processing this node. // We might have found a leaf-block of HTML, but that shouldn't // affect our parent's state. var originalState = _foundNonHtml; _foundNonHtml = false; if (node.HasDiagnostics) { // Treat node with errors as non-HTML - don't let the parent rewrite this either. _foundNonHtml = true; } if (string.Equals("script", node.TagName, StringComparison.OrdinalIgnoreCase)) { // Treat script tags as non-HTML - we trigger errors for script tags // later. _foundNonHtml = true; } base.VisitDefault(node); if (!_foundNonHtml) { Trees.Add(new IntermediateNodeReference(Parent, node)); } _foundNonHtml = originalState |= _foundNonHtml; }
public override void VisitMarkupElement(MarkupElementIntermediateNode node) { // Disallow <script> in components as per #552 if (string.Equals(node.TagName, "script", StringComparison.OrdinalIgnoreCase)) { for (var i = 0; i < node.Children.Count; i++) { // We allow you to suppress this error like: // <script suppress-error="BL9992" /> var attribute = node.Children[i] as HtmlAttributeIntermediateNode; if (attribute != null && attribute.AttributeName == "suppress-error" && attribute.Children.Count == 1 && attribute.Children[0] is HtmlAttributeValueIntermediateNode value && value.Children.Count == 1 && value.Children[0] is IntermediateToken token && token.IsHtml && string.Equals(token.Content, "BL9992", StringComparison.Ordinal)) { node.Children.RemoveAt(i); return; } } var diagnostic = ComponentDiagnosticFactory.Create_DisallowedScriptTag(node.Source); node.Diagnostics.Add(diagnostic); } base.VisitDefault(node); }
private void ProcessElement(MarkupElementIntermediateNode node, string cssScope) { // Add a minimized attribute whose name is simply the CSS scope node.Children.Add(new HtmlAttributeIntermediateNode { AttributeName = cssScope, Prefix = cssScope, Suffix = string.Empty, }); }
public override void VisitMarkupElement(MarkupElementIntermediateNode node) { for (var i = 0; i < _trees.Count; i++) { // Remove this node if it's in the list. This ensures that we don't // do redundant operations. if (ReferenceEquals(_trees[i].Node, node)) { _trees.RemoveAt(i); break; } } var isVoid = Legacy.ParserHelpers.VoidElements.Contains(node.TagName); var hasBodyContent = node.Body.Any(); Builder.Append('<'); Builder.Append(node.TagName); foreach (var attribute in node.Attributes) { Visit(attribute); } // If for some reason a void element contains body, then treat it as a // start/end tag. if (!hasBodyContent && isVoid) { // void Builder.Append('>'); return; } else if (!hasBodyContent) { // In HTML5, we can't have self-closing non-void elements, so explicitly // add a close tag Builder.Append("></"); Builder.Append(node.TagName); Builder.Append('>'); return; } // start/end tag with body. Builder.Append('>'); foreach (var item in node.Body) { Visit(item); } Builder.Append("</"); Builder.Append(node.TagName); Builder.Append('>'); }
public override void WriteMarkupElement(CodeRenderingContext context, MarkupElementIntermediateNode node) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (node == null) { throw new ArgumentNullException(nameof(node)); } context.RenderChildren(node); }
public override void VisitMarkupElement(MarkupElementIntermediateNode node) { // We need to restore the state after processing this node. // We might have found a leaf-block of HTML, but that shouldn't // affect our parent's state. var originalState = _foundNonHtml; _foundNonHtml = false; if (node.HasDiagnostics) { // Treat node with errors as non-HTML - don't let the parent rewrite this either. _foundNonHtml = true; } if (string.Equals("script", node.TagName, StringComparison.OrdinalIgnoreCase)) { // Treat script tags as non-HTML - we trigger errors for script tags // later. _foundNonHtml = true; } else if (string.Equals("option", node.TagName, StringComparison.OrdinalIgnoreCase)) { // Also, treat <option>...</option> as non-HTML - we don't want it to be coalesced so that we can support setting "selected" attribute on it. // We only care about option tags that are nested under a select tag. foreach (var ancestor in Ancestors) { if (ancestor is MarkupElementIntermediateNode element && string.Equals("select", element.TagName, StringComparison.OrdinalIgnoreCase)) { _foundNonHtml = true; break; } } } base.VisitDefault(node); if (!_foundNonHtml) { Trees.Add(new IntermediateNodeReference(Parent, node)); } _foundNonHtml = originalState |= _foundNonHtml; }
private MarkupElementIntermediateNode RewriteAsElement(TagHelperIntermediateNode node) { var result = new MarkupElementIntermediateNode() { Source = node.Source, TagName = node.TagName, }; for (var i = 0; i < node.Diagnostics.Count; i++) { result.Diagnostics.Add(node.Diagnostics[i]); } var visitor = new ElementRewriteVisitor(result.Children); visitor.Visit(node); return(result); }
public override void VisitMarkupElement(MarkupElementIntermediateNode node) { for (var i = 0; i < node.Children.Count; i++) { if (node.Children[i] is HtmlAttributeIntermediateNode attribute && attribute.AttributeName != null) { if (_attributes.TryGetValue(attribute.AttributeName, out var other)) { // As a special case we want to point it out explicitly where a directive or other construct // has emitted an attribute that causes a conflict. We're already looking at the lowered version // of this construct, so it's easy to detect. We just need the original name to report the issue. // // Example: `bind-value` will set `value` and `onchange`. var originalAttributeName = attribute.Annotations[ComponentMetadata.Common.OriginalAttributeName] as string ?? other.node.Annotations[ComponentMetadata.Common.OriginalAttributeName] as string; if (originalAttributeName != null) { other.node.Diagnostics.Add(ComponentDiagnosticFactory.Create_DuplicateMarkupAttributeDirective( other.name, originalAttributeName, other.node.Source ?? node.Source)); } else { // This is a conflict in the code the user wrote. other.node.Diagnostics.Add(ComponentDiagnosticFactory.Create_DuplicateMarkupAttribute( other.name, other.node.Source ?? node.Source)); } } // Replace the attribute we were previously tracking. Then if you have three, the two on the left will have // diagnostics. _attributes[attribute.AttributeName] = (attribute.AttributeName, attribute); } } _attributes.Clear(); base.VisitMarkupElement(node); }
public virtual void VisitMarkupElement(MarkupElementIntermediateNode node) { VisitDefault(node); }
public override void VisitMarkupElement(MarkupElementIntermediateNode node) { RemoveContiguousWhitespace(node.Children, TraversalDirection.Forwards); RemoveContiguousWhitespace(node.Children, TraversalDirection.Backwards); VisitDefault(node); }
public override void VisitMarkupElement(MarkupElementIntermediateNode node) { Context.NodeWriter.WriteMarkupElement(Context, node); }
public override void VisitMarkupElement(MarkupElementIntermediateNode node) { WriteContentNode(node, node.TagName); }
public virtual void WriteMarkupElement(CodeRenderingContext context, MarkupElementIntermediateNode node) { throw new NotSupportedException("This writer does not support components."); }