diff --git a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netcoreapp.cs b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netcoreapp.cs
index 1ee9bf558a..b6c4f834e2 100644
--- a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netcoreapp.cs
+++ b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netcoreapp.cs
@@ -407,6 +407,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
{
public RenderTreeBuilder() { }
public void AddAttribute(int sequence, in Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrame frame) { }
+ public void AddAttribute(int sequence, string name) { }
public void AddAttribute(int sequence, string name, Microsoft.AspNetCore.Components.EventCallback value) { }
public void AddAttribute(int sequence, string name, bool value) { }
public void AddAttribute(int sequence, string name, System.MulticastDelegate? value) { }
diff --git a/src/Components/Components/src/Rendering/RenderTreeBuilder.cs b/src/Components/Components/src/Rendering/RenderTreeBuilder.cs
index 224fc55ff9..4e9280c70f 100644
--- a/src/Components/Components/src/Rendering/RenderTreeBuilder.cs
+++ b/src/Components/Components/src/Rendering/RenderTreeBuilder.cs
@@ -157,6 +157,29 @@ namespace Microsoft.AspNetCore.Components.Rendering
public void AddContent(int sequence, object? textContent)
=> AddContent(sequence, textContent?.ToString());
+ ///
+ ///
+ /// Appends a frame representing a bool-valued attribute with value 'true'.
+ ///
+ ///
+ /// The attribute is associated with the most recently added element.
+ ///
+ ///
+ /// An integer that represents the position of the instruction in the source code.
+ /// The name of the attribute.
+ public void AddAttribute(int sequence, string name)
+ {
+ ProfilingStart();
+
+ if (_lastNonAttributeFrameType != RenderTreeFrameType.Element)
+ {
+ throw new InvalidOperationException($"Valueless attributes may only be added immediately after frames of type {RenderTreeFrameType.Element}");
+ }
+
+ Append(RenderTreeFrame.Attribute(sequence, name, BoxedTrue));
+ ProfilingEnd();
+ }
+
///
///
/// Appends a frame representing a bool-valued attribute.
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentCssScopePass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentCssScopePass.cs
new file mode 100644
index 0000000000..9192f23e69
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentCssScopePass.cs
@@ -0,0 +1,46 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+
+namespace Microsoft.AspNetCore.Razor.Language.Components
+{
+ internal class ComponentCssScopePass : ComponentIntermediateNodePassBase, IRazorOptimizationPass
+ {
+ // Runs after components/bind, since it's preferable for the auto-generated attribute to appear later
+ // in the DOM than developer-written ones
+ public override int Order => 110;
+
+ protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
+ {
+ if (!IsComponentDocument(documentNode))
+ {
+ return;
+ }
+
+ var cssScope = codeDocument.GetCssScope();
+ if (string.IsNullOrEmpty(cssScope))
+ {
+ return;
+ }
+
+ var nodes = documentNode.FindDescendantNodes();
+ for (var i = 0; i < nodes.Count; i++)
+ {
+ ProcessElement(nodes[i], cssScope);
+ }
+ }
+
+ 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,
+ });
+ }
+ }
+}
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs
index c1e0c625f6..4e2cd831ef 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs
@@ -316,8 +316,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
.WriteStartMethodInvocation($"{_scopeStack.BuilderVarName}.{nameof(ComponentsApi.RenderTreeBuilder.AddAttribute)}")
.Write("-1")
.WriteParameterSeparator()
- .WriteStringLiteral(key)
- .WriteParameterSeparator();
+ .WriteStringLiteral(key);
}
protected override void BeginWriteAttribute(CodeRenderingContext context, IntermediateNode expression)
@@ -341,8 +340,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
{
context.CodeWriter.Write(tokens[i].Content);
}
-
- context.CodeWriter.WriteParameterSeparator();
}
public override void WriteComponent(CodeRenderingContext context, ComponentIntermediateNode node)
@@ -731,6 +728,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
// OR
// __builder.AddAttribute(1, "ChildContent", (RenderFragment)((person) => (__builder73) => { ... }));
BeginWriteAttribute(context, node.AttributeName);
+ context.CodeWriter.WriteParameterSeparator();
context.CodeWriter.Write($"({node.TypeName})(");
WriteComponentChildContentInnards(context, node);
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs
index b57552e5e6..93df99a41e 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs
@@ -673,6 +673,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
// OR
// _builder.AddAttribute(1, "ChildContent", (RenderFragment)((person) => (__builder73) => { ... }));
BeginWriteAttribute(context, node.AttributeName);
+ context.CodeWriter.WriteParameterSeparator();
context.CodeWriter.Write($"({node.TypeName})(");
WriteComponentChildContentInnards(context, node);
@@ -851,14 +852,22 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
private void WriteAttribute(CodeRenderingContext context, string key, IList value)
{
BeginWriteAttribute(context, key);
- WriteAttributeValue(context, value);
+ if (value.Count > 0)
+ {
+ context.CodeWriter.WriteParameterSeparator();
+ WriteAttributeValue(context, value);
+ }
context.CodeWriter.WriteEndMethodInvocation();
}
private void WriteAttribute(CodeRenderingContext context, IntermediateNode nameExpression, IList value)
{
BeginWriteAttribute(context, nameExpression);
- WriteAttributeValue(context, value);
+ if (value.Count > 0)
+ {
+ context.CodeWriter.WriteParameterSeparator();
+ WriteAttributeValue(context, value);
+ }
context.CodeWriter.WriteEndMethodInvocation();
}
@@ -868,8 +877,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
.WriteStartMethodInvocation($"{_scopeStack.BuilderVarName}.{ComponentsApi.RenderTreeBuilder.AddAttribute}")
.Write((_sourceSequence++).ToString())
.WriteParameterSeparator()
- .WriteStringLiteral(key)
- .WriteParameterSeparator();
+ .WriteStringLiteral(key);
}
protected override void BeginWriteAttribute(CodeRenderingContext context, IntermediateNode nameExpression)
@@ -883,8 +891,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
{
WriteCSharpToken(context, tokens[i]);
}
-
- context.CodeWriter.WriteParameterSeparator();
}
private static string GetHtmlContent(HtmlContentIntermediateNode node)
@@ -988,8 +994,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
}
else
{
- // Minimized attributes always map to 'true'
- writer.Write("true");
+ throw new InvalidOperationException("Found attribute whose value is neither HTML nor CSharp");
}
}
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngine.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngine.cs
index c8fc4f6f9b..a11e63cc90 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngine.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectEngine.cs
@@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Razor.Language
}
var importSourceDocuments = GetImportSourceDocuments(importItems);
- return CreateCodeDocumentCore(sourceDocument, projectItem.FileKind, importSourceDocuments, tagHelpers: null, configureParser, configureCodeGeneration);
+ return CreateCodeDocumentCore(sourceDocument, projectItem.FileKind, importSourceDocuments, tagHelpers: null, configureParser, configureCodeGeneration, cssScope: projectItem.CssScope);
}
protected internal RazorCodeDocument CreateCodeDocumentCore(
@@ -94,7 +94,8 @@ namespace Microsoft.AspNetCore.Razor.Language
IReadOnlyList importSourceDocuments = null,
IReadOnlyList tagHelpers = null,
Action configureParser = null,
- Action configureCodeGeneration = null)
+ Action configureCodeGeneration = null,
+ string cssScope = null)
{
if (sourceDocument == null)
{
@@ -122,6 +123,11 @@ namespace Microsoft.AspNetCore.Razor.Language
codeDocument.SetFileKind(fileKind);
}
+ if (cssScope != null)
+ {
+ codeDocument.SetCssScope(cssScope);
+ }
+
return codeDocument;
}
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectFileSystem.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectFileSystem.cs
index c80f43307b..de7f34f5cd 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectFileSystem.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectFileSystem.cs
@@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var relativePhysicalPath = file.FullName.Substring(absoluteBasePath.Length + 1); // Include leading separator
var filePath = "/" + relativePhysicalPath.Replace(Path.DirectorySeparatorChar, '/');
- return new DefaultRazorProjectItem(basePath, filePath, relativePhysicalPath, fileKind: null, file);
+ return new DefaultRazorProjectItem(basePath, filePath, relativePhysicalPath, fileKind: null, file, cssScope: null);
});
}
@@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var relativePhysicalPath = file.FullName.Substring(absoluteBasePath.Length + 1); // Include leading separator
var filePath = "/" + relativePhysicalPath.Replace(Path.DirectorySeparatorChar, '/');
- return new DefaultRazorProjectItem("/", filePath, relativePhysicalPath, fileKind, new FileInfo(absolutePath));
+ return new DefaultRazorProjectItem("/", filePath, relativePhysicalPath, fileKind, new FileInfo(absolutePath), cssScope: null);
}
[Obsolete("Use GetItem(string path, string fileKind) instead.")]
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectItem.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectItem.cs
index 082ed4666a..5dc5100238 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectItem.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorProjectItem.cs
@@ -17,13 +17,15 @@ namespace Microsoft.AspNetCore.Razor.Language
/// The path.
/// The file kind. If null, the document kind will be inferred from the file extension.
/// The .
- public DefaultRazorProjectItem(string basePath, string filePath, string relativePhysicalPath, string fileKind, FileInfo file)
+ /// A scope identifier that will be used on elements in the generated class, or null.
+ public DefaultRazorProjectItem(string basePath, string filePath, string relativePhysicalPath, string fileKind, FileInfo file, string cssScope)
{
BasePath = basePath;
FilePath = filePath;
RelativePhysicalPath = relativePhysicalPath;
_fileKind = fileKind;
File = file;
+ CssScope = cssScope;
}
public FileInfo File { get; }
@@ -40,6 +42,8 @@ namespace Microsoft.AspNetCore.Razor.Language
public override string FileKind => _fileKind ?? base.FileKind;
+ public override string CssScope { get; }
+
public override Stream Read() => new FileStream(PhysicalPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
}
}
\ No newline at end of file
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeDocumentExtensions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeDocumentExtensions.cs
index 6d22aa5f27..df6240e2e5 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeDocumentExtensions.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorCodeDocumentExtensions.cs
@@ -14,6 +14,7 @@ namespace Microsoft.AspNetCore.Razor.Language
{
private static readonly char[] PathSeparators = new char[] { '/', '\\' };
private static readonly char[] NamespaceSeparators = new char[] { '.' };
+ private static object CssScopeKey = new object();
public static TagHelperDocumentContext GetTagHelperContext(this RazorCodeDocument document)
{
@@ -216,6 +217,26 @@ namespace Microsoft.AspNetCore.Razor.Language
document.Items[typeof(FileKinds)] = fileKind;
}
+ public static string GetCssScope(this RazorCodeDocument document)
+ {
+ if (document == null)
+ {
+ throw new ArgumentNullException(nameof(document));
+ }
+
+ return (string)document.Items[CssScopeKey];
+ }
+
+ public static void SetCssScope(this RazorCodeDocument document, string cssScope)
+ {
+ if (document == null)
+ {
+ throw new ArgumentNullException(nameof(document));
+ }
+
+ document.Items[CssScopeKey] = cssScope;
+ }
+
// In general documents will have a relative path (relative to the project root).
// We can only really compute a nice namespace when we know a relative path.
//
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngine.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngine.cs
index ac75eac6d1..1d664e8028 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngine.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectEngine.cs
@@ -238,6 +238,7 @@ namespace Microsoft.AspNetCore.Razor.Language
builder.Features.Add(new ComponentReferenceCaptureLoweringPass());
builder.Features.Add(new ComponentSplatLoweringPass());
builder.Features.Add(new ComponentBindLoweringPass());
+ builder.Features.Add(new ComponentCssScopePass());
builder.Features.Add(new ComponentTemplateDiagnosticPass());
builder.Features.Add(new ComponentGenericTypePass());
builder.Features.Add(new ComponentChildContentDiagnosticPass());
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectItem.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectItem.cs
index 5ee33824d5..6c245de893 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectItem.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/RazorProjectItem.cs
@@ -35,6 +35,11 @@ namespace Microsoft.AspNetCore.Razor.Language
///
public virtual string RelativePhysicalPath => null;
+ ///
+ /// A scope identifier that will be used on elements in the generated class, or null.
+ ///
+ public virtual string CssScope { get; }
+
///
/// Gets the document kind that should be used for the generated document. If possible this will be inferred from the file path. May be null.
///
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/DefaultRazorProjectItemTest.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/DefaultRazorProjectItemTest.cs
index f903b16f63..f302becbea 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/DefaultRazorProjectItemTest.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/DefaultRazorProjectItemTest.cs
@@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
// Act
- var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", "test", fileInfo);
+ var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", "test", fileInfo, "MyCssScope");
// Assert
Assert.Equal("/Home.cshtml", projectItem.FilePath);
@@ -30,6 +30,7 @@ namespace Microsoft.AspNetCore.Razor.Language
Assert.Equal("test", projectItem.FileKind);
Assert.Equal(fileInfo.FullName, projectItem.PhysicalPath);
Assert.Equal("Home.cshtml", projectItem.RelativePhysicalPath);
+ Assert.Equal("MyCssScope", projectItem.CssScope);
}
[Fact]
@@ -39,7 +40,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
// Act
- var projectItem = new DefaultRazorProjectItem("/", "/Home.razor", "Home.cshtml", fileKind: null, fileInfo);
+ var projectItem = new DefaultRazorProjectItem("/", "/Home.razor", "Home.cshtml", fileKind: null, fileInfo, cssScope: null);
// Assert
Assert.Equal(FileKinds.Component, projectItem.FileKind);
@@ -52,7 +53,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
// Act
- var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", fileKind: null, fileInfo);
+ var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", fileKind: null, fileInfo, cssScope: null);
// Assert
Assert.Equal(FileKinds.Legacy, projectItem.FileKind);
@@ -65,7 +66,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
// Act
- var projectItem = new DefaultRazorProjectItem("/", filePath: null, "Home.cshtml", fileKind: null, fileInfo);
+ var projectItem = new DefaultRazorProjectItem("/", filePath: null, "Home.cshtml", fileKind: null, fileInfo, cssScope: null);
// Assert
Assert.Null(projectItem.FileKind);
@@ -78,7 +79,7 @@ namespace Microsoft.AspNetCore.Razor.Language
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Views", "FileDoesNotExist.cshtml"));
// Act
- var projectItem = new DefaultRazorProjectItem("/Views", "/FileDoesNotExist.cshtml", Path.Combine("Views", "FileDoesNotExist.cshtml"), "test", fileInfo);
+ var projectItem = new DefaultRazorProjectItem("/Views", "/FileDoesNotExist.cshtml", Path.Combine("Views", "FileDoesNotExist.cshtml"), "test", fileInfo, cssScope: null);
// Assert
Assert.False(projectItem.Exists);
@@ -89,7 +90,7 @@ namespace Microsoft.AspNetCore.Razor.Language
{
// Arrange
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
- var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", "test", fileInfo);
+ var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", "test", fileInfo, cssScope: null);
// Act
var stream = projectItem.Read();
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs
index d7d135b9b1..0308fe46c4 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs
@@ -4929,6 +4929,69 @@ namespace New.Test
#endregion
+ #region "CSS scoping"
+ [Fact]
+ public void Component_WithCssScope()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(Parse(@"
+using Microsoft.AspNetCore.Components;
+
+namespace Test
+{
+ public class TemplatedComponent : ComponentBase
+ {
+ [Parameter]
+ public RenderFragment ChildContent { get; set; }
+ }
+}
+"));
+
+ // Act
+ // This test case attempts to use all syntaxes that might interact with auto-generated attributes
+ var generated = CompileToCSharp(@"
+@using Microsoft.AspNetCore.Components.Web
+@using Microsoft.AspNetCore.Components.Rendering
+
Element with no attributes
+
+
+ With text
+
+ This is in child content
+
+
+@if (DateTime.Now.Year > 1950)
+{
+ Content
+
+}
+
+@code {
+ ElementReference myElementReference;
+ TemplatedComponent myComponentReference;
+ string myVariable;
+
+ void MethodRenderingMarkup(RenderTreeBuilder __builder)
+ {
+ for (var i = 0; i < 10; i++)
+ {
+ Something @i
+ }
+
+ System.GC.KeepAlive(myElementReference);
+ System.GC.KeepAlive(myComponentReference);
+ System.GC.KeepAlive(myVariable);
+ }
+}
+", cssScope: "TestCssScope");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+ #endregion
+
#region Misc
[Fact] // We don't process - we just skip them
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/RazorProjectEngineTest.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/RazorProjectEngineTest.cs
index c9fa4504cd..d483472fa4 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/RazorProjectEngineTest.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/RazorProjectEngineTest.cs
@@ -49,6 +49,7 @@ namespace Microsoft.AspNetCore.Razor.Language
feature => Assert.IsType(feature),
feature => Assert.IsType(feature),
feature => Assert.IsType(feature),
+ feature => Assert.IsType(feature),
feature => Assert.IsType(feature),
feature => Assert.IsType(feature),
feature => Assert.IsType(feature),
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithCssScope/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithCssScope/TestComponent.codegen.cs
new file mode 100644
index 0000000000..95b48f43d9
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithCssScope/TestComponent.codegen.cs
@@ -0,0 +1,148 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using Microsoft.AspNetCore.Components;
+#nullable restore
+#line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
+using Microsoft.AspNetCore.Components.Web;
+
+#line default
+#line hidden
+#nullable disable
+#nullable restore
+#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
+using Microsoft.AspNetCore.Components.Rendering;
+
+#line default
+#line hidden
+#nullable disable
+ public partial class TestComponent : Microsoft.AspNetCore.Components.ComponentBase
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
+ {
+ __o =
+#nullable restore
+#line 4 "x:\dir\subdir\Test\TestComponent.cshtml"
+ 123
+
+#line default
+#line hidden
+#nullable disable
+ ;
+ __builder.AddAttribute(-1, "ChildContent", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
+ }
+ ));
+#nullable restore
+#line 7 "x:\dir\subdir\Test\TestComponent.cshtml"
+ myComponentReference = default(Test.TemplatedComponent);
+
+#line default
+#line hidden
+#nullable disable
+#nullable restore
+#line 7 "x:\dir\subdir\Test\TestComponent.cshtml"
+__o = typeof(TemplatedComponent);
+
+#line default
+#line hidden
+#nullable disable
+#nullable restore
+#line 11 "x:\dir\subdir\Test\TestComponent.cshtml"
+ if (DateTime.Now.Year > 1950)
+{
+
+
+#line default
+#line hidden
+#nullable disable
+#nullable restore
+#line 13 "x:\dir\subdir\Test\TestComponent.cshtml"
+ myElementReference = default(Microsoft.AspNetCore.Components.ElementReference);
+
+#line default
+#line hidden
+#nullable disable
+
+
+ __o = Microsoft.AspNetCore.Components.BindConverter.FormatValue(
+#nullable restore
+#line 14 "x:\dir\subdir\Test\TestComponent.cshtml"
+ myVariable
+
+#line default
+#line hidden
+#nullable disable
+ );
+ __o = Microsoft.AspNetCore.Components.EventCallback.Factory.CreateBinder(this, __value => myVariable = __value, myVariable);
+#nullable restore
+#line 14 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+}
+
+#line default
+#line hidden
+#nullable disable
+ }
+ #pragma warning restore 1998
+#nullable restore
+#line 17 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+ ElementReference myElementReference;
+ TemplatedComponent myComponentReference;
+ string myVariable;
+
+ void MethodRenderingMarkup(RenderTreeBuilder __builder)
+ {
+ for (var i = 0; i < 10; i++)
+ {
+
+
+#line default
+#line hidden
+#nullable disable
+ __o =
+#nullable restore
+#line 26 "x:\dir\subdir\Test\TestComponent.cshtml"
+ i
+
+#line default
+#line hidden
+#nullable disable
+ ;
+#nullable restore
+#line 26 "x:\dir\subdir\Test\TestComponent.cshtml"
+ __o = i;
+
+#line default
+#line hidden
+#nullable disable
+#nullable restore
+#line 26 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+ }
+
+ System.GC.KeepAlive(myElementReference);
+ System.GC.KeepAlive(myComponentReference);
+ System.GC.KeepAlive(myVariable);
+ }
+
+#line default
+#line hidden
+#nullable disable
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithCssScope/TestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithCssScope/TestComponent.ir.txt
new file mode 100644
index 0000000000..0d679be1f3
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithCssScope/TestComponent.ir.txt
@@ -0,0 +1,114 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [12] ) - System
+ UsingDirective - (18:2,1 [32] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [17] ) - System.Linq
+ UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks
+ UsingDirective - (104:5,1 [37] ) - Microsoft.AspNetCore.Components
+ UsingDirective - (1:0,1 [41] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Web
+ UsingDirective - (45:1,1 [47] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Rendering
+ ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ HtmlContent - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (42:0,42 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ HtmlContent - (92:1,48 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (92:1,48 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ MarkupElement - (94:2,0 [35] x:\dir\subdir\Test\TestComponent.cshtml) - h1
+ HtmlContent - (98:2,4 [26] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (98:2,4 [26] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Element with no attributes
+ HtmlContent - (129:2,35 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (129:2,35 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ MarkupElement - (131:3,0 [305] x:\dir\subdir\Test\TestComponent.cshtml) - parent
+ HtmlAttribute - (138:3,7 [22] x:\dir\subdir\Test\TestComponent.cshtml) - with-attributes=" - "
+ HtmlAttributeValue - (156:3,25 [3] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (156:3,25 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - yes
+ HtmlAttribute - (160:3,29 [37] x:\dir\subdir\Test\TestComponent.cshtml) - with-csharp-attribute-value=" - "
+ CSharpExpressionAttributeValue - (190:3,59 [6] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (192:3,61 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 123
+ HtmlContent - (198:3,67 [6] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (198:3,67 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ MarkupElement - (204:4,4 [9] x:\dir\subdir\Test\TestComponent.cshtml) - child
+ HtmlContent - (213:4,13 [6] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (213:4,13 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ MarkupElement - (219:5,4 [67] x:\dir\subdir\Test\TestComponent.cshtml) - child
+ HtmlAttribute - (225:5,10 [4] x:\dir\subdir\Test\TestComponent.cshtml) - has -
+ HtmlAttribute - (229:5,14 [9] x:\dir\subdir\Test\TestComponent.cshtml) - multiple -
+ HtmlAttribute - (238:5,23 [30] x:\dir\subdir\Test\TestComponent.cshtml) - attributes=" - "
+ HtmlAttributeValue - (251:5,36 [4] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (251:5,36 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - some
+ HtmlAttributeValue - (255:5,40 [5] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (256:5,41 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - with
+ HtmlAttributeValue - (260:5,45 [7] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (261:5,46 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - values
+ HtmlContent - (269:5,54 [9] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (269:5,54 [9] x:\dir\subdir\Test\TestComponent.cshtml) - Html - With text
+ HtmlContent - (286:5,71 [6] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (286:5,71 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ Component - (292:6,4 [133] x:\dir\subdir\Test\TestComponent.cshtml) - TemplatedComponent
+ ComponentChildContent - - ChildContent - context
+ HtmlContent - (340:6,52 [10] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (340:6,52 [10] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ MarkupElement - (350:7,8 [48] x:\dir\subdir\Test\TestComponent.cshtml) - span
+ HtmlAttribute - (355:7,13 [11] x:\dir\subdir\Test\TestComponent.cshtml) - id=" - "
+ HtmlAttributeValue - (360:7,18 [5] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (360:7,18 [5] x:\dir\subdir\Test\TestComponent.cshtml) - Html - hello
+ HtmlContent - (367:7,25 [24] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (367:7,25 [24] x:\dir\subdir\Test\TestComponent.cshtml) - Html - This is in child content
+ HtmlContent - (398:7,56 [6] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (398:7,56 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ ReferenceCapture - (318:6,30 [20] x:\dir\subdir\Test\TestComponent.cshtml) - myComponentReference
+ HtmlContent - (425:8,25 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (425:8,25 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ HtmlContent - (436:9,9 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (436:9,9 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ CSharpCode - (439:10,1 [38] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (439:10,1 [38] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - if (DateTime.Now.Year > 1950)\n{\n
+ MarkupElement - (477:12,4 [80] x:\dir\subdir\Test\TestComponent.cshtml) - with-ref-capture
+ HtmlContent - (531:12,58 [7] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (531:12,58 [7] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Content
+ HtmlAttribute - - some-attr -
+ ReferenceCapture - (511:12,38 [18] x:\dir\subdir\Test\TestComponent.cshtml) - myElementReference
+ CSharpCode - (557:12,84 [6] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (557:12,84 [6] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n
+ MarkupElement - (563:13,4 [74] x:\dir\subdir\Test\TestComponent.cshtml) - input
+ HtmlAttribute - - id=" - "
+ HtmlAttributeValue - (574:13,15 [6] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (574:13,15 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - myElem
+ HtmlAttribute - - another-attr=" - "
+ HtmlAttributeValue - (615:13,56 [18] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (615:13,56 [18] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Another attr value
+ HtmlAttribute - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - value=" - "
+ CSharpExpressionAttributeValue - -
+ IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.BindConverter.FormatValue(
+ LazyIntermediateToken - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - myVariable
+ IntermediateToken - - CSharp - )
+ HtmlAttribute - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - onchange=" - "
+ CSharpExpressionAttributeValue - -
+ IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.EventCallback.Factory.CreateBinder(this, __value => myVariable = __value,
+ IntermediateToken - - CSharp - myVariable
+ IntermediateToken - - CSharp - )
+ CSharpCode - (637:13,78 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (637:13,78 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n}
+ HtmlContent - (640:14,1 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (640:14,1 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n
+ HtmlContent - (1098:32,1 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (1098:32,1 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ CSharpCode - (651:16,7 [245] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (651:16,7 [245] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n ElementReference myElementReference;\n TemplatedComponent myComponentReference;\n string myVariable;\n\n void MethodRenderingMarkup(RenderTreeBuilder __builder)\n {\n for (var i = 0; i < 10; i++)\n {\n
+ MarkupElement - (896:25,12 [35] x:\dir\subdir\Test\TestComponent.cshtml) - li
+ HtmlAttribute - (899:25,15 [14] x:\dir\subdir\Test\TestComponent.cshtml) - data-index= -
+ CSharpExpressionAttributeValue - (911:25,27 [2] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (912:25,28 [1] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - i
+ HtmlContent - (914:25,30 [10] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (914:25,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Something
+ CSharpExpression - (925:25,41 [1] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (925:25,41 [1] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - i
+ CSharpCode - (931:25,47 [166] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (931:25,47 [166] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n }\n\n System.GC.KeepAlive(myElementReference);\n System.GC.KeepAlive(myComponentReference);\n System.GC.KeepAlive(myVariable);\n }\n
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithCssScope/TestComponent.mappings.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithCssScope/TestComponent.mappings.txt
new file mode 100644
index 0000000000..f3d9de1293
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithCssScope/TestComponent.mappings.txt
@@ -0,0 +1,105 @@
+Source Location: (1:0,1 [41] x:\dir\subdir\Test\TestComponent.cshtml)
+|using Microsoft.AspNetCore.Components.Web|
+Generated Location: (320:12,0 [41] )
+|using Microsoft.AspNetCore.Components.Web|
+
+Source Location: (45:1,1 [47] x:\dir\subdir\Test\TestComponent.cshtml)
+|using Microsoft.AspNetCore.Components.Rendering|
+Generated Location: (484:19,0 [47] )
+|using Microsoft.AspNetCore.Components.Rendering|
+
+Source Location: (192:3,61 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+|123|
+Generated Location: (1267:39,61 [3] )
+|123|
+
+Source Location: (318:6,30 [20] x:\dir\subdir\Test\TestComponent.cshtml)
+|myComponentReference|
+Generated Location: (1592:50,30 [20] )
+|myComponentReference|
+
+Source Location: (439:10,1 [38] x:\dir\subdir\Test\TestComponent.cshtml)
+|if (DateTime.Now.Year > 1950)
+{
+ |
+Generated Location: (1927:64,1 [38] )
+|if (DateTime.Now.Year > 1950)
+{
+ |
+
+Source Location: (511:12,38 [18] x:\dir\subdir\Test\TestComponent.cshtml)
+|myElementReference|
+Generated Location: (2126:73,38 [18] )
+|myElementReference|
+
+Source Location: (557:12,84 [6] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ |
+Generated Location: (2353:78,96 [6] )
+|
+ |
+
+Source Location: (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml)
+|myVariable|
+Generated Location: (2540:83,30 [10] )
+|myVariable|
+
+Source Location: (637:13,78 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+}|
+Generated Location: (2905:92,78 [3] )
+|
+}|
+
+Source Location: (651:16,7 [245] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ ElementReference myElementReference;
+ TemplatedComponent myComponentReference;
+ string myVariable;
+
+ void MethodRenderingMarkup(RenderTreeBuilder __builder)
+ {
+ for (var i = 0; i < 10; i++)
+ {
+ |
+Generated Location: (3087:102,7 [245] )
+|
+ ElementReference myElementReference;
+ TemplatedComponent myComponentReference;
+ string myVariable;
+
+ void MethodRenderingMarkup(RenderTreeBuilder __builder)
+ {
+ for (var i = 0; i < 10; i++)
+ {
+ |
+
+Source Location: (912:25,28 [1] x:\dir\subdir\Test\TestComponent.cshtml)
+|i|
+Generated Location: (3499:119,28 [1] )
+|i|
+
+Source Location: (925:25,41 [1] x:\dir\subdir\Test\TestComponent.cshtml)
+|i|
+Generated Location: (3675:127,41 [1] )
+|i|
+
+Source Location: (931:25,47 [166] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ }
+
+ System.GC.KeepAlive(myElementReference);
+ System.GC.KeepAlive(myComponentReference);
+ System.GC.KeepAlive(myVariable);
+ }
+|
+Generated Location: (3847:134,47 [166] )
+|
+ }
+
+ System.GC.KeepAlive(myElementReference);
+ System.GC.KeepAlive(myComponentReference);
+ System.GC.KeepAlive(myVariable);
+ }
+|
+
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithCssScope/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithCssScope/TestComponent.codegen.cs
new file mode 100644
index 0000000000..6e2c5dbff4
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithCssScope/TestComponent.codegen.cs
@@ -0,0 +1,162 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using Microsoft.AspNetCore.Components;
+#nullable restore
+#line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
+using Microsoft.AspNetCore.Components.Web;
+
+#line default
+#line hidden
+#nullable disable
+#nullable restore
+#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
+using Microsoft.AspNetCore.Components.Rendering;
+
+#line default
+#line hidden
+#nullable disable
+ public partial class TestComponent : Microsoft.AspNetCore.Components.ComponentBase
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
+ {
+ __builder.AddMarkupContent(0, "Element with no attributes
\r\n");
+ __builder.OpenElement(1, "parent");
+ __builder.AddAttribute(2, "with-attributes", "yes");
+ __builder.AddAttribute(3, "with-csharp-attribute-value",
+#nullable restore
+#line 4 "x:\dir\subdir\Test\TestComponent.cshtml"
+ 123
+
+#line default
+#line hidden
+#nullable disable
+ );
+ __builder.AddAttribute(4, "TestCssScope");
+ __builder.AddMarkupContent(5, "\r\n ");
+ __builder.AddMarkupContent(6, "With text\r\n ");
+ __builder.OpenComponent(7);
+ __builder.AddAttribute(8, "ChildContent", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
+ __builder2.AddMarkupContent(9, "This is in child content");
+ }
+ ));
+ __builder.AddComponentReferenceCapture(10, (__value) => {
+#nullable restore
+#line 7 "x:\dir\subdir\Test\TestComponent.cshtml"
+ myComponentReference = (Test.TemplatedComponent)__value;
+
+#line default
+#line hidden
+#nullable disable
+ }
+ );
+ __builder.CloseComponent();
+ __builder.CloseElement();
+#nullable restore
+#line 11 "x:\dir\subdir\Test\TestComponent.cshtml"
+ if (DateTime.Now.Year > 1950)
+{
+
+#line default
+#line hidden
+#nullable disable
+ __builder.OpenElement(11, "with-ref-capture");
+ __builder.AddAttribute(12, "some-attr");
+ __builder.AddAttribute(13, "TestCssScope");
+ __builder.AddElementReferenceCapture(14, (__value) => {
+#nullable restore
+#line 13 "x:\dir\subdir\Test\TestComponent.cshtml"
+ myElementReference = __value;
+
+#line default
+#line hidden
+#nullable disable
+ }
+ );
+ __builder.AddContent(15, "Content");
+ __builder.CloseElement();
+ __builder.AddMarkupContent(16, "\r\n ");
+ __builder.OpenElement(17, "input");
+ __builder.AddAttribute(18, "id", "myElem");
+ __builder.AddAttribute(19, "another-attr", "Another attr value");
+ __builder.AddAttribute(20, "value", Microsoft.AspNetCore.Components.BindConverter.FormatValue(
+#nullable restore
+#line 14 "x:\dir\subdir\Test\TestComponent.cshtml"
+ myVariable
+
+#line default
+#line hidden
+#nullable disable
+ ));
+ __builder.AddAttribute(21, "onchange", Microsoft.AspNetCore.Components.EventCallback.Factory.CreateBinder(this, __value => myVariable = __value, myVariable));
+ __builder.SetUpdatesAttributeName("value");
+ __builder.AddAttribute(22, "TestCssScope");
+ __builder.CloseElement();
+#nullable restore
+#line 15 "x:\dir\subdir\Test\TestComponent.cshtml"
+}
+
+#line default
+#line hidden
+#nullable disable
+ }
+ #pragma warning restore 1998
+#nullable restore
+#line 17 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+ ElementReference myElementReference;
+ TemplatedComponent myComponentReference;
+ string myVariable;
+
+ void MethodRenderingMarkup(RenderTreeBuilder __builder)
+ {
+ for (var i = 0; i < 10; i++)
+ {
+
+#line default
+#line hidden
+#nullable disable
+ __builder.OpenElement(23, "li");
+ __builder.AddAttribute(24, "data-index",
+#nullable restore
+#line 26 "x:\dir\subdir\Test\TestComponent.cshtml"
+ i
+
+#line default
+#line hidden
+#nullable disable
+ );
+ __builder.AddAttribute(25, "TestCssScope");
+ __builder.AddContent(26, "Something ");
+ __builder.AddContent(27,
+#nullable restore
+#line 26 "x:\dir\subdir\Test\TestComponent.cshtml"
+ i
+
+#line default
+#line hidden
+#nullable disable
+ );
+ __builder.CloseElement();
+#nullable restore
+#line 27 "x:\dir\subdir\Test\TestComponent.cshtml"
+ }
+
+ System.GC.KeepAlive(myElementReference);
+ System.GC.KeepAlive(myComponentReference);
+ System.GC.KeepAlive(myVariable);
+ }
+
+#line default
+#line hidden
+#nullable disable
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithCssScope/TestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithCssScope/TestComponent.ir.txt
new file mode 100644
index 0000000000..e0f558f3cb
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithCssScope/TestComponent.ir.txt
@@ -0,0 +1,70 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [14] ) - System
+ UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [19] ) - System.Linq
+ UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
+ UsingDirective - (104:5,1 [39] ) - Microsoft.AspNetCore.Components
+ UsingDirective - (1:0,1 [43] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Web
+ UsingDirective - (45:1,1 [49] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components.Rendering
+ ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase -
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ MarkupBlock - - Element with no attributes
\n
+ MarkupElement - (131:3,0 [305] x:\dir\subdir\Test\TestComponent.cshtml) - parent
+ HtmlAttribute - (138:3,7 [22] x:\dir\subdir\Test\TestComponent.cshtml) - with-attributes=" - "
+ HtmlAttributeValue - (156:3,25 [3] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (156:3,25 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - yes
+ HtmlAttribute - (160:3,29 [37] x:\dir\subdir\Test\TestComponent.cshtml) - with-csharp-attribute-value=" - "
+ CSharpExpressionAttributeValue - (190:3,59 [6] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (192:3,61 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 123
+ MarkupBlock - - \n
+ MarkupBlock - - With text\n
+ Component - (292:6,4 [133] x:\dir\subdir\Test\TestComponent.cshtml) - TemplatedComponent
+ ComponentChildContent - - ChildContent - context
+ MarkupBlock - - This is in child content
+ ReferenceCapture - (318:6,30 [20] x:\dir\subdir\Test\TestComponent.cshtml) - myComponentReference
+ HtmlAttribute - - TestCssScope -
+ CSharpCode - (439:10,1 [34] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (439:10,1 [34] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - if (DateTime.Now.Year > 1950)\n{\n
+ MarkupElement - (477:12,4 [80] x:\dir\subdir\Test\TestComponent.cshtml) - with-ref-capture
+ HtmlContent - (531:12,58 [7] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (531:12,58 [7] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Content
+ HtmlAttribute - - some-attr -
+ ReferenceCapture - (511:12,38 [18] x:\dir\subdir\Test\TestComponent.cshtml) - myElementReference
+ HtmlAttribute - - TestCssScope -
+ HtmlContent - (557:12,84 [6] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (557:12,84 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ LazyIntermediateToken - (559:13,0 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html -
+ MarkupElement - (563:13,4 [74] x:\dir\subdir\Test\TestComponent.cshtml) - input
+ HtmlAttribute - - id=" - "
+ HtmlAttributeValue - (574:13,15 [6] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (574:13,15 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - myElem
+ HtmlAttribute - - another-attr=" - "
+ HtmlAttributeValue - (615:13,56 [18] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (615:13,56 [18] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Another attr value
+ HtmlAttribute - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - value=" - "
+ CSharpExpressionAttributeValue - -
+ IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.BindConverter.FormatValue(
+ LazyIntermediateToken - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - myVariable
+ IntermediateToken - - CSharp - )
+ HtmlAttribute - (589:13,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - onchange=" - "
+ CSharpExpressionAttributeValue - -
+ IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.EventCallback.Factory.CreateBinder(this, __value => myVariable = __value,
+ IntermediateToken - - CSharp - myVariable
+ IntermediateToken - - CSharp - )
+ HtmlAttribute - - TestCssScope -
+ CSharpCode - (639:14,0 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (639:14,0 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - }\n
+ CSharpCode - (651:16,7 [233] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (651:16,7 [233] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n ElementReference myElementReference;\n TemplatedComponent myComponentReference;\n string myVariable;\n\n void MethodRenderingMarkup(RenderTreeBuilder __builder)\n {\n for (var i = 0; i < 10; i++)\n {\n
+ MarkupElement - (896:25,12 [35] x:\dir\subdir\Test\TestComponent.cshtml) - li
+ HtmlAttribute - (899:25,15 [14] x:\dir\subdir\Test\TestComponent.cshtml) - data-index= -
+ CSharpExpressionAttributeValue - (911:25,27 [2] x:\dir\subdir\Test\TestComponent.cshtml) -
+ LazyIntermediateToken - (912:25,28 [1] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - i
+ HtmlContent - (914:25,30 [10] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (914:25,30 [10] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Something
+ CSharpExpression - (925:25,41 [1] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (925:25,41 [1] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - i
+ HtmlAttribute - - TestCssScope -
+ CSharpCode - (933:26,0 [164] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (933:26,0 [164] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - }\n\n System.GC.KeepAlive(myElementReference);\n System.GC.KeepAlive(myComponentReference);\n System.GC.KeepAlive(myVariable);\n }\n
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithCssScope/TestComponent.mappings.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithCssScope/TestComponent.mappings.txt
new file mode 100644
index 0000000000..1dd0bdefa2
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithCssScope/TestComponent.mappings.txt
@@ -0,0 +1,66 @@
+Source Location: (318:6,30 [20] x:\dir\subdir\Test\TestComponent.cshtml)
+|myComponentReference|
+Generated Location: (2121:62,30 [20] )
+|myComponentReference|
+
+Source Location: (439:10,1 [34] x:\dir\subdir\Test\TestComponent.cshtml)
+|if (DateTime.Now.Year > 1950)
+{
+|
+Generated Location: (2412:73,1 [34] )
+|if (DateTime.Now.Year > 1950)
+{
+|
+
+Source Location: (511:12,38 [18] x:\dir\subdir\Test\TestComponent.cshtml)
+|myElementReference|
+Generated Location: (2845:85,38 [18] )
+|myElementReference|
+
+Source Location: (639:14,0 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+|}
+|
+Generated Location: (3972:113,0 [3] )
+|}
+|
+
+Source Location: (651:16,7 [233] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ ElementReference myElementReference;
+ TemplatedComponent myComponentReference;
+ string myVariable;
+
+ void MethodRenderingMarkup(RenderTreeBuilder __builder)
+ {
+ for (var i = 0; i < 10; i++)
+ {
+|
+Generated Location: (4152:122,7 [233] )
+|
+ ElementReference myElementReference;
+ TemplatedComponent myComponentReference;
+ string myVariable;
+
+ void MethodRenderingMarkup(RenderTreeBuilder __builder)
+ {
+ for (var i = 0; i < 10; i++)
+ {
+|
+
+Source Location: (933:26,0 [164] x:\dir\subdir\Test\TestComponent.cshtml)
+| }
+
+ System.GC.KeepAlive(myElementReference);
+ System.GC.KeepAlive(myComponentReference);
+ System.GC.KeepAlive(myVariable);
+ }
+|
+Generated Location: (5112:159,0 [164] )
+| }
+
+ System.GC.KeepAlive(myElementReference);
+ System.GC.KeepAlive(myComponentReference);
+ System.GC.KeepAlive(myVariable);
+ }
+|
+
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/DuplicateMarkupAttributes_IsAnError/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/DuplicateMarkupAttributes_IsAnError/TestComponent.codegen.cs
index af3808fed1..69f1edaf96 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/DuplicateMarkupAttributes_IsAnError/TestComponent.codegen.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/DuplicateMarkupAttributes_IsAnError/TestComponent.codegen.cs
@@ -16,8 +16,8 @@ namespace Test
__builder.OpenElement(0, "div");
__builder.OpenElement(1, "a");
__builder.AddAttribute(2, "href", "/cool-url");
- __builder.AddAttribute(3, "style", true);
- __builder.AddAttribute(4, "disabled", true);
+ __builder.AddAttribute(3, "style");
+ __builder.AddAttribute(4, "disabled");
__builder.AddAttribute(5, "href", "/even-cooler-url");
__builder.AddContent(6, "Learn the ten cool tricks your compiler author will hate!");
__builder.CloseElement();
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/DuplicateMarkupAttributes_Multiple_IsAnError/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/DuplicateMarkupAttributes_Multiple_IsAnError/TestComponent.codegen.cs
index 4ee5c736c6..3e1eac8fe2 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/DuplicateMarkupAttributes_Multiple_IsAnError/TestComponent.codegen.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/DuplicateMarkupAttributes_Multiple_IsAnError/TestComponent.codegen.cs
@@ -16,10 +16,10 @@ namespace Test
__builder.OpenElement(0, "div");
__builder.OpenElement(1, "a");
__builder.AddAttribute(2, "href", "/cool-url");
- __builder.AddAttribute(3, "style", true);
- __builder.AddAttribute(4, "disabled", true);
+ __builder.AddAttribute(3, "style");
+ __builder.AddAttribute(4, "disabled");
__builder.AddAttribute(5, "href", "/even-cooler-url");
- __builder.AddAttribute(6, "href", true);
+ __builder.AddAttribute(6, "href");
__builder.AddContent(7, "Learn the ten cool tricks your compiler author will hate!");
__builder.CloseElement();
__builder.CloseElement();
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/EventHandler_PreventDefault_Duplicates/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/EventHandler_PreventDefault_Duplicates/TestComponent.codegen.cs
index 42db467644..c234bb73ba 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/EventHandler_PreventDefault_Duplicates/TestComponent.codegen.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/EventHandler_PreventDefault_Duplicates/TestComponent.codegen.cs
@@ -30,7 +30,7 @@ using Microsoft.AspNetCore.Components.Web;
#line hidden
#nullable disable
);
- __builder.AddAttribute(2, "@onclick:preventDefault", true);
+ __builder.AddAttribute(2, "@onclick:preventDefault");
__builder.CloseElement();
}
#pragma warning restore 1998
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ScriptTag_WithErrorSuppressed/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ScriptTag_WithErrorSuppressed/TestComponent.codegen.cs
index a4085edb4a..3f0e7d9727 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ScriptTag_WithErrorSuppressed/TestComponent.codegen.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ScriptTag_WithErrorSuppressed/TestComponent.codegen.cs
@@ -16,7 +16,7 @@ namespace Test
__builder.OpenElement(0, "div");
__builder.OpenElement(1, "script");
__builder.AddAttribute(2, "src", "some/url.js");
- __builder.AddAttribute(3, "anotherattribute", true);
+ __builder.AddAttribute(3, "anotherattribute");
__builder.AddMarkupContent(4, "\r\n some text\r\n some more text\r\n ");
__builder.CloseElement();
__builder.CloseElement();
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/GenerateCommand.cs b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/GenerateCommand.cs
index 0406225fc8..6bcf622d1d 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/GenerateCommand.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/GenerateCommand.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
+using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.CSharp;
@@ -25,6 +26,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
Outputs = Option("-o", "Generated output file path", CommandOptionType.MultipleValue);
RelativePaths = Option("-r", "Relative path", CommandOptionType.MultipleValue);
FileKinds = Option("-k", "File kind", CommandOptionType.MultipleValue);
+ CssScopeSources = Option("-cssscopedinput", ".razor file with scoped CSS", CommandOptionType.MultipleValue);
+ CssScopeValues = Option("-cssscopevalue", "CSS scope value for .razor file with scoped CSS", CommandOptionType.MultipleValue);
ProjectDirectory = Option("-p", "project root directory", CommandOptionType.SingleValue);
TagHelperManifest = Option("-t", "tag helper manifest file", CommandOptionType.SingleValue);
Version = Option("-v|--version", "Razor language version", CommandOptionType.SingleValue);
@@ -44,6 +47,10 @@ namespace Microsoft.AspNetCore.Razor.Tools
public CommandOption FileKinds { get; }
+ public CommandOption CssScopeSources { get; }
+
+ public CommandOption CssScopeValues { get; }
+
public CommandOption ProjectDirectory { get; }
public CommandOption TagHelperManifest { get; }
@@ -81,7 +88,9 @@ namespace Microsoft.AspNetCore.Razor.Tools
var version = RazorLanguageVersion.Parse(Version.Value());
var configuration = RazorConfiguration.Create(version, Configuration.Value(), extensions);
- var sourceItems = GetSourceItems(ProjectDirectory.Value(), Sources.Values, Outputs.Values, RelativePaths.Values, FileKinds.Values);
+ var sourceItems = GetSourceItems(
+ Sources.Values, Outputs.Values, RelativePaths.Values,
+ FileKinds.Values, CssScopeSources.Values, CssScopeValues.Values);
var result = ExecuteCore(
configuration: configuration,
@@ -120,6 +129,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
return false;
}
+ if (CssScopeSources.Values.Count != CssScopeValues.Values.Count)
+ {
+ // CssScopeSources and CssScopeValues arguments must appear as matched pairs
+ Error.WriteLine($"{CssScopeSources.Description} has {CssScopeSources.Values.Count}, but {CssScopeValues.Description} has {CssScopeValues.Values.Count} values.");
+ return false;
+ }
+
if (string.IsNullOrEmpty(ProjectDirectory.Value()))
{
ProjectDirectory.Values.Add(Environment.CurrentDirectory);
@@ -256,7 +272,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
filePath: item.FilePath,
relativePhysicalPath: item.RelativePhysicalPath,
fileKind: item.FileKind,
- file: new FileInfo(item.SourcePath));
+ file: new FileInfo(item.SourcePath),
+ cssScope: item.CssScope);
project.Add(projectItem);
}
@@ -284,19 +301,28 @@ namespace Microsoft.AspNetCore.Razor.Tools
}
}
- private SourceItem[] GetSourceItems(string projectDirectory, List sources, List outputs, List relativePath, List fileKinds)
+ private static SourceItem[] GetSourceItems(List sources, List outputs, List relativePath, List fileKinds, List cssScopeSources, List cssScopeValues)
{
+ var cssScopeAssociations = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ for (var cssScopeSourceIndex = 0; cssScopeSourceIndex < cssScopeSources.Count; cssScopeSourceIndex++)
+ {
+ cssScopeAssociations.Add(cssScopeSources[cssScopeSourceIndex], cssScopeSourceIndex);
+ }
+
var items = new SourceItem[sources.Count];
for (var i = 0; i < items.Length; i++)
{
- var outputPath = Path.Combine(projectDirectory, outputs[i]);
var fileKind = fileKinds.Count > 0 ? fileKinds[i] : "mvc";
if (Language.FileKinds.IsComponent(fileKind))
{
fileKind = Language.FileKinds.GetComponentFileKindFromFilePath(sources[i]);
}
- items[i] = new SourceItem(sources[i], outputs[i], relativePath[i], fileKind);
+ var cssScopeValue = cssScopeAssociations.TryGetValue(sources[i], out var cssScopeIndex)
+ ? cssScopeValues[cssScopeIndex]
+ : null;
+
+ items[i] = new SourceItem(sources[i], outputs[i], relativePath[i], fileKind, cssScopeValue);
}
return items;
@@ -334,7 +360,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
private readonly struct SourceItem
{
- public SourceItem(string sourcePath, string outputPath, string physicalRelativePath, string fileKind)
+ public SourceItem(string sourcePath, string outputPath, string physicalRelativePath, string fileKind, string cssScope)
{
SourcePath = sourcePath;
OutputPath = outputPath;
@@ -343,6 +369,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
.Replace(Path.DirectorySeparatorChar, '/')
.Replace("//", "/");
FileKind = fileKind;
+ CssScope = cssScope;
}
public string SourcePath { get; }
@@ -354,6 +381,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
public string FilePath { get; }
public string FileKind { get; }
+
+ public string CssScope { get; }
}
private class StaticTagHelperFeature : ITagHelperFeature
diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/RazorGenerate.cs b/src/Razor/Microsoft.NET.Sdk.Razor/src/RazorGenerate.cs
index bee0df6816..36875942b0 100644
--- a/src/Razor/Microsoft.NET.Sdk.Razor/src/RazorGenerate.cs
+++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/RazorGenerate.cs
@@ -23,6 +23,7 @@ namespace Microsoft.AspNetCore.Razor.Tasks
private const string Identity = "Identity";
private const string AssemblyName = "AssemblyName";
private const string AssemblyFilePath = "AssemblyFilePath";
+ private const string CssScope = "CssScope";
public string RootNamespace { get; set; }
@@ -127,6 +128,26 @@ namespace Microsoft.AspNetCore.Razor.Tasks
}
}
+ // Added in 5.0: CSS scopes
+ if (parsedVersion.Major >= 5)
+ {
+ for (var i = 0; i < Sources.Length; i++)
+ {
+ // Most inputs won't have an associated CSS scope, so we only want to generate
+ // a scope parameter for those that do. Hence we need to specify in the parameter
+ // which one we're talking about.
+ var input = Sources[i];
+ var cssScope = input.GetMetadata(CssScope);
+ if (!string.IsNullOrEmpty(cssScope))
+ {
+ builder.AppendLine("-cssscopedinput");
+ builder.AppendLine(input.GetMetadata(FullPath));
+ builder.AppendLine("-cssscopevalue");
+ builder.AppendLine(cssScope);
+ }
+ }
+ }
+
builder.AppendLine("-p");
builder.AppendLine(ProjectRoot);
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/RazorIntegrationTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/RazorIntegrationTestBase.cs
index 5266adac10..ddd1b5dbd1 100644
--- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/RazorIntegrationTestBase.cs
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/IntegrationTests/RazorIntegrationTestBase.cs
@@ -140,7 +140,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
});
}
- internal RazorProjectItem CreateProjectItem(string cshtmlRelativePath, string cshtmlContent, string fileKind = null)
+ internal RazorProjectItem CreateProjectItem(string cshtmlRelativePath, string cshtmlContent, string fileKind = null, string cssScope = null)
{
var fullPath = WorkingDirectory + PathSeparator + cshtmlRelativePath;
@@ -161,18 +161,19 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
physicalPath: fullPath,
relativePhysicalPath: cshtmlRelativePath,
basePath: WorkingDirectory,
- fileKind: fileKind ?? FileKind)
+ fileKind: fileKind ?? FileKind,
+ cssScope: cssScope)
{
Content = cshtmlContent.TrimStart(),
};
}
- protected CompileToCSharpResult CompileToCSharp(string cshtmlContent, bool throwOnFailure=true)
+ protected CompileToCSharpResult CompileToCSharp(string cshtmlContent, bool throwOnFailure=true, string cssScope = null)
{
- return CompileToCSharp(DefaultFileName, cshtmlContent, throwOnFailure);
+ return CompileToCSharp(DefaultFileName, cshtmlContent, throwOnFailure, cssScope: cssScope);
}
- protected CompileToCSharpResult CompileToCSharp(string cshtmlRelativePath, string cshtmlContent, bool throwOnFailure = true, string fileKind = null)
+ protected CompileToCSharpResult CompileToCSharp(string cshtmlRelativePath, string cshtmlContent, bool throwOnFailure = true, string fileKind = null, string cssScope = null)
{
if (DeclarationOnly && DesignTime)
{
@@ -202,7 +203,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
}
// Result of generating declarations
- var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind);
+ var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind, cssScope);
codeDocument = projectEngine.ProcessDeclarationOnly(projectItem);
var declaration = new CompileToCSharpResult
{
@@ -248,7 +249,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
// This will include the built-in components.
var projectEngine = CreateProjectEngine(Configuration, BaseCompilation.References.ToArray());
- var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind);
+ var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind, cssScope);
RazorCodeDocument codeDocument;
if (DeclarationOnly)
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestRazorProjectItem.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestRazorProjectItem.cs
index e811043206..407169e646 100644
--- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestRazorProjectItem.cs
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestRazorProjectItem.cs
@@ -15,12 +15,14 @@ namespace Microsoft.AspNetCore.Razor.Language
string physicalPath = null,
string relativePhysicalPath = null,
string basePath = "/",
- string fileKind = null)
+ string fileKind = null,
+ string cssScope = null)
{
FilePath = filePath;
PhysicalPath = physicalPath;
RelativePhysicalPath = relativePhysicalPath;
BasePath = basePath;
+ CssScope = cssScope;
_fileKind = fileKind;
}
@@ -34,6 +36,8 @@ namespace Microsoft.AspNetCore.Razor.Language
public override string RelativePhysicalPath { get; }
+ public override string CssScope { get; }
+
public override bool Exists { get; } = true;
public string Content { get; set; } = "Default content";
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Components.netstandard2.0.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Components.netstandard2.0.cs
index c244065999..6a5ff2c2e3 100644
--- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Components.netstandard2.0.cs
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Components.netstandard2.0.cs
@@ -385,6 +385,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
{
public RenderTreeBuilder() { }
public void AddAttribute(int sequence, in Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrame frame) { }
+ public void AddAttribute(int sequence, string name) { }
public void AddAttribute(int sequence, string name, Microsoft.AspNetCore.Components.EventCallback value) { }
public void AddAttribute(int sequence, string name, bool value) { }
public void AddAttribute(int sequence, string name, System.MulticastDelegate value) { }