diff --git a/src/Microsoft.AspNetCore.Mvc.TagHelpers/LinkTagHelper.cs b/src/Microsoft.AspNetCore.Mvc.TagHelpers/LinkTagHelper.cs index 6c1f59f515..f54b613e9c 100644 --- a/src/Microsoft.AspNetCore.Mvc.TagHelpers/LinkTagHelper.cs +++ b/src/Microsoft.AspNetCore.Mvc.TagHelpers/LinkTagHelper.cs @@ -25,6 +25,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers [HtmlTargetElement("link", Attributes = HrefIncludeAttributeName, TagStructure = TagStructure.WithoutEndTag)] [HtmlTargetElement("link", Attributes = HrefExcludeAttributeName, TagStructure = TagStructure.WithoutEndTag)] [HtmlTargetElement("link", Attributes = FallbackHrefAttributeName, TagStructure = TagStructure.WithoutEndTag)] + [HtmlTargetElement("link", Attributes = FallbackHrefIntegrityCheckAttributeName, TagStructure = TagStructure.WithoutEndTag)] [HtmlTargetElement("link", Attributes = FallbackHrefIncludeAttributeName, TagStructure = TagStructure.WithoutEndTag)] [HtmlTargetElement("link", Attributes = FallbackHrefExcludeAttributeName, TagStructure = TagStructure.WithoutEndTag)] [HtmlTargetElement("link", Attributes = FallbackTestClassAttributeName, TagStructure = TagStructure.WithoutEndTag)] @@ -40,6 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers private const string HrefIncludeAttributeName = "asp-href-include"; private const string HrefExcludeAttributeName = "asp-href-exclude"; private const string FallbackHrefAttributeName = "asp-fallback-href"; + private const string FallbackHrefIntegrityCheckAttributeName = "asp-fallback-href-integrity-check"; private const string FallbackHrefIncludeAttributeName = "asp-fallback-href-include"; private const string FallbackHrefExcludeAttributeName = "asp-fallback-href-exclude"; private const string FallbackTestClassAttributeName = "asp-fallback-test-class"; @@ -147,6 +149,14 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers [HtmlAttributeName(FallbackHrefAttributeName)] public string FallbackHref { get; set; } + /// + /// Boolean value that determines if Integrity Hash will be compared with value. + /// Value defaults to true if not provided. + /// Must be used in conjunction with . + /// + [HtmlAttributeName(FallbackHrefIntegrityCheckAttributeName)] + public bool? FallbackHrefIntegrityCheck { get; set; } + /// /// Value indicating if file version should be appended to the href urls. /// @@ -367,6 +377,12 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers continue; } + // do not write integrity attribute when FallbackHrefIntegrityCheck is false + if (attribute.Name.Equals("integrity", StringComparison.OrdinalIgnoreCase) && FallbackHrefIntegrityCheck == false) + { + continue; + } + attribute.WriteTo(StringWriter, HtmlEncoder); StringWriter.Write(' '); } diff --git a/src/Microsoft.AspNetCore.Mvc.TagHelpers/ScriptTagHelper.cs b/src/Microsoft.AspNetCore.Mvc.TagHelpers/ScriptTagHelper.cs index 271aa289d8..b0e8289426 100644 --- a/src/Microsoft.AspNetCore.Mvc.TagHelpers/ScriptTagHelper.cs +++ b/src/Microsoft.AspNetCore.Mvc.TagHelpers/ScriptTagHelper.cs @@ -27,6 +27,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers [HtmlTargetElement("script", Attributes = FallbackSrcIncludeAttributeName)] [HtmlTargetElement("script", Attributes = FallbackSrcExcludeAttributeName)] [HtmlTargetElement("script", Attributes = FallbackTestExpressionAttributeName)] + [HtmlTargetElement("script", Attributes = FallbackIntegrityCheckAttributeName)] [HtmlTargetElement("script", Attributes = AppendVersionAttributeName)] public class ScriptTagHelper : UrlResolutionTagHelper { @@ -34,6 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers private const string SrcExcludeAttributeName = "asp-src-exclude"; private const string FallbackSrcAttributeName = "asp-fallback-src"; private const string FallbackSrcIncludeAttributeName = "asp-fallback-src-include"; + private const string FallbackIntegrityCheckAttributeName = "asp-fallback-integrity-check"; private const string FallbackSrcExcludeAttributeName = "asp-fallback-src-exclude"; private const string FallbackTestExpressionAttributeName = "asp-fallback-test"; private const string SrcAttributeName = "src"; @@ -129,6 +131,14 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers [HtmlAttributeName(FallbackSrcAttributeName)] public string FallbackSrc { get; set; } + /// + /// Boolean value that determines if Integrity Hash will be compared with value. + /// Value defaults to true if not provided. + /// Must be used in conjunction with . + /// + [HtmlAttributeName(FallbackIntegrityCheckAttributeName)] + public bool? FallbackIntegrityCheck { get; set; } + /// /// Value indicating if file version should be appended to src urls. /// @@ -312,6 +322,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers var attribute = attributes[i]; if (!attribute.Name.Equals(SrcAttributeName, StringComparison.OrdinalIgnoreCase)) { + // do not write integrity attribute when fallbackintegrityCheck is false + if (attribute.Name.Equals("integrity", StringComparison.OrdinalIgnoreCase) && FallbackIntegrityCheck == false) continue; + StringWriter.Write(' '); attribute.WriteTo(StringWriter, HtmlEncoder); } diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.Encoded.html b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.Encoded.html index 680a5729a0..08d2e6d60a 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.Encoded.html +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.Encoded.html @@ -19,11 +19,27 @@ // Fallback to globbed src ]]")); + + +]]")); + + +]]")); + + +]]")); -]]")); +]]")); - + - + @@ -110,9 +126,9 @@ - + - + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.html b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.html index 12b71d6555..ea0f2da3ac 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.html +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.html @@ -19,11 +19,27 @@ // Fallback to globbed src + + + + + + + + + - + - + - + @@ -110,9 +126,9 @@ - + - + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/RazorPagesWebSite.SimpleForms.html b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/RazorPagesWebSite.SimpleForms.html index ef06135e61..27ca37082a 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/RazorPagesWebSite.SimpleForms.html +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/RazorPagesWebSite.SimpleForms.html @@ -3,5 +3,4 @@
-
-
\ No newline at end of file +
\ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/LinkTagHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/LinkTagHelperTest.cs index ed843fe9e6..4fa536e096 100644 --- a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/LinkTagHelperTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/LinkTagHelperTest.cs @@ -263,7 +263,49 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers tagHelper.FallbackTestValue = "hidden"; tagHelper.AppendVersion = true; } - } + }, + // asp-fallback-href-integrity-check Attribute true + { + new TagHelperAttributeList + { + new TagHelperAttribute("asp-fallback-href", "test.css"), + new TagHelperAttribute("asp-fallback-test-class", "hidden"), + new TagHelperAttribute("asp-fallback-test-property", "visibility"), + new TagHelperAttribute("asp-fallback-test-value", "hidden"), + new TagHelperAttribute("asp-append-version", "true"), + new TagHelperAttribute("asp-fallback-href-integrity-check", "true") + }, + tagHelper => + { + tagHelper.FallbackHref = "test.css"; + tagHelper.FallbackTestClass = "hidden"; + tagHelper.FallbackTestProperty = "visibility"; + tagHelper.FallbackTestValue = "hidden"; + tagHelper.AppendVersion = true; + tagHelper.FallbackHrefIntegrityCheck = true; + } + }, + // asp-fallback-href-integrity-check Attribute false + { + new TagHelperAttributeList + { + new TagHelperAttribute("asp-fallback-href", "test.css"), + new TagHelperAttribute("asp-fallback-test-class", "hidden"), + new TagHelperAttribute("asp-fallback-test-property", "visibility"), + new TagHelperAttribute("asp-fallback-test-value", "hidden"), + new TagHelperAttribute("asp-append-version", "true"), + new TagHelperAttribute("asp-fallback-href-integrity-check", "false") + }, + tagHelper => + { + tagHelper.FallbackHref = "test.css"; + tagHelper.FallbackTestClass = "hidden"; + tagHelper.FallbackTestProperty = "visibility"; + tagHelper.FallbackTestValue = "hidden"; + tagHelper.AppendVersion = true; + tagHelper.FallbackHrefIntegrityCheck = false; + } + }, }; } } diff --git a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs index 97a4214606..a30ee40535 100644 --- a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs @@ -156,6 +156,20 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers tagHelper.FallbackTestExpression = "isavailable()"; } }, + { + new TagHelperAttributeList + { + new TagHelperAttribute("asp-fallback-src", "test.js"), + new TagHelperAttribute("asp-fallback-test", "isavailable()"), + new TagHelperAttribute("asp-fallback-integrity-check", "false") + }, + tagHelper => + { + tagHelper.FallbackSrc = "test.js"; + tagHelper.FallbackTestExpression = "isavailable()"; + tagHelper.FallbackIntegrityCheck = false; + } + }, { new TagHelperAttributeList { @@ -182,6 +196,22 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers tagHelper.FallbackTestExpression = "isavailable()"; } }, + { + new TagHelperAttributeList + { + new TagHelperAttribute("asp-fallback-src", "test.js"), + new TagHelperAttribute("asp-fallback-src-include", "*.js"), + new TagHelperAttribute("asp-fallback-test", "isavailable()"), + new TagHelperAttribute("asp-fallback-integrity-check", "false") + }, + tagHelper => + { + tagHelper.FallbackSrc = "test.js"; + tagHelper.FallbackSrcInclude = "*.css"; + tagHelper.FallbackTestExpression = "isavailable()"; + tagHelper.FallbackIntegrityCheck = false; + } + }, { new TagHelperAttributeList { diff --git a/test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/Link.cshtml b/test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/Link.cshtml index 09f614154a..26acbf3b51 100644 --- a/test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/Link.cshtml +++ b/test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/Link.cshtml @@ -46,6 +46,35 @@ asp-fallback-test-property="visibility" asp-fallback-test-value="hidden" /> + + + + + + + + + // Fallback to globbed src + + + + + +