Skip to content

Commit 8ffa2b2

Browse files
authored
[Blazor] ImportMap fixes (#57282)
* [Blazor] ImportMap fixes * Support passing additional attributes to the import map Component * This allows passing a nonce for Content Security Policies. * Fix an issue with the paths on the integrity attribute not being valid relative links. * This caused certain importmap entries to be ignored. * Fixes the Blazor United Sample.
1 parent a03b790 commit 8ffa2b2

File tree

7 files changed

+21
-27
lines changed

7 files changed

+21
-27
lines changed

src/Components/Endpoints/src/Assets/ImportMap.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ public sealed class ImportMap : IComponent
2929
[Parameter]
3030
public ImportMapDefinition? ImportMapDefinition { get; set; }
3131

32+
/// <summary>
33+
/// Gets or sets a collection of additional attributes that will be applied to the created <c>script</c> element.
34+
/// </summary>
35+
[Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object>? AdditionalAttributes { get; set; }
36+
3237
void IComponent.Attach(RenderHandle renderHandle)
3338
{
3439
_renderHandle = renderHandle;
@@ -57,7 +62,8 @@ private void RenderImportMap(RenderTreeBuilder builder)
5762
{
5863
builder.OpenElement(0, "script");
5964
builder.AddAttribute(1, "type", "importmap");
60-
builder.AddMarkupContent(2, _computedImportMapDefinition!.ToJson());
65+
builder.AddMultipleAttributes(2, AdditionalAttributes);
66+
builder.AddMarkupContent(3, _computedImportMapDefinition!.ToJson());
6167
builder.CloseElement();
6268
}
6369
}

src/Components/Endpoints/src/Assets/ImportMapDefinition.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public static ImportMapDefinition FromResourceCollection(ResourceAssetCollection
6969
if (integrity != null)
7070
{
7171
importMap._integrity ??= [];
72-
importMap._integrity[asset.Url] = integrity;
72+
importMap._integrity[$"./{asset.Url}"] = integrity;
7373
}
7474

7575
if (label != null)

src/Components/Endpoints/src/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#nullable enable
22
Microsoft.AspNetCore.Components.ImportMap
3+
Microsoft.AspNetCore.Components.ImportMap.AdditionalAttributes.get -> System.Collections.Generic.IReadOnlyDictionary<string!, object!>?
4+
Microsoft.AspNetCore.Components.ImportMap.AdditionalAttributes.set -> void
35
Microsoft.AspNetCore.Components.ImportMap.HttpContext.get -> Microsoft.AspNetCore.Http.HttpContext?
46
Microsoft.AspNetCore.Components.ImportMap.HttpContext.set -> void
57
Microsoft.AspNetCore.Components.ImportMap.ImportMap() -> void

src/Components/Endpoints/test/Assets/ImportMapDefinitionTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public void CanBuildImportMap_FromResourceCollection()
116116
"./jquery.js": "./jquery.fingerprint.js"
117117
},
118118
"integrity": {
119-
"jquery.fingerprint.js": "sha384-abc123"
119+
"./jquery.fingerprint.js": "sha384-abc123"
120120
}
121121
}
122122
""".Replace("\r\n", "\n");

src/Components/Endpoints/test/ImportMapTest.cs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,6 @@ public ImportMapTest()
3030
_importMap = (ImportMap)_renderer.InstantiateComponent<ImportMap>();
3131
}
3232

33-
//[Fact]
34-
//public async Task CanRunOnNavigateAsync()
35-
//{
36-
// // Arrange
37-
// var called = false;
38-
// Action<NavigationContext> OnNavigateAsync = async (NavigationContext args) =>
39-
// {
40-
// await Task.CompletedTask;
41-
// called = true;
42-
// };
43-
// _importMap.OnNavigateAsync = new EventCallback<NavigationContext>(null, OnNavigateAsync);
44-
45-
// // Act
46-
// await _renderer.Dispatcher.InvokeAsync(() => _importMap.RunOnNavigateAsync("http://example.com/jan", false));
47-
48-
// // Assert
49-
// Assert.True(called);
50-
//}
51-
5233
[Fact]
5334
public async Task CanRenderImportMap()
5435
{
@@ -75,20 +56,24 @@ public async Task CanRenderImportMap()
7556
});
7657

7758
importMap.ImportMapDefinition = importMapDefinition;
59+
importMap.AdditionalAttributes = new Dictionary<string, object> { ["nonce"] = "random" }.AsReadOnly();
60+
7861
var id = _renderer.AssignRootComponentId(importMap);
7962
// Act
8063
await _renderer.Dispatcher.InvokeAsync(() => _renderer.RenderRootComponent(id));
8164

8265
// Assert
8366
var frames = _renderer.GetCurrentRenderTreeFrames(id);
84-
Assert.Equal(3, frames.Count);
67+
Assert.Equal(4, frames.Count);
8568
Assert.Equal(RenderTreeFrameType.Element, frames.Array[0].FrameType);
8669
Assert.Equal("script", frames.Array[0].ElementName);
8770
Assert.Equal(RenderTreeFrameType.Attribute, frames.Array[1].FrameType);
8871
Assert.Equal("type", frames.Array[1].AttributeName);
8972
Assert.Equal("importmap", frames.Array[1].AttributeValue);
90-
Assert.Equal(RenderTreeFrameType.Markup, frames.Array[2].FrameType);
91-
Assert.Equal(importMapDefinition.ToJson(), frames.Array[2].TextContent);
73+
Assert.Equal("nonce", frames.Array[2].AttributeName);
74+
Assert.Equal("random", frames.Array[2].AttributeValue);
75+
Assert.Equal(RenderTreeFrameType.Markup, frames.Array[3].FrameType);
76+
Assert.Equal(importMapDefinition.ToJson(), frames.Array[3].TextContent);
9277
}
9378

9479
[Fact]

src/Components/Samples/BlazorUnitedApp/App.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
<link href="@Assets["BlazorUnitedApp.styles.css"]" rel="stylesheet" />
1111
<link rel="icon" type="image/png" href="favicon.png" />
1212

13-
<ImportMap />
13+
<ImportMap nonce="my-value" />
1414
<HeadOutlet />
1515
</head>
1616
<body>
1717
<Routes />
18-
<script src=""_framework/blazor.web.js"></script>
18+
<script src="_framework/blazor.web.js"></script>
1919
</body>
2020
</html>

src/Components/Samples/BlazorUnitedApp/appsettings.Development.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"EnableStaticAssetsDevelopmentCaching": true,
3+
"EnableStaticAssetsDevelopmentIntegrity": true,
34
"DetailedErrors": true,
45
"Logging": {
56
"LogLevel": {

0 commit comments

Comments
 (0)