Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f66003c
Supporting pseudo-element attribute in css link fallback (#38146)
Oct 15, 2023
28f9c32
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Oct 17, 2023
30216b1
Added non-minified version of the fallback script
Oct 18, 2023
836d3a8
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Oct 18, 2023
daf540e
Merge branch 'pseudo-elements-in-fallback-#38146' of https://github.c…
Oct 18, 2023
802c64b
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Oct 26, 2023
8f482de
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Nov 3, 2023
bdd9236
Merge branch 'main' of https://github.com/dasblinkenlight/aspnetcore
Nov 20, 2023
f1c8569
Merge branch 'main' into pseudo-elements-in-fallback-#38146
Nov 20, 2023
622cbbe
Merge branch 'main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Nov 21, 2023
c9d598c
Updated PublicAPI.Unshipped
Nov 21, 2023
1648136
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Nov 21, 2023
699e4d6
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Nov 29, 2023
85aca85
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 2, 2023
e06f215
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 4, 2023
c717d52
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 5, 2023
a5e750f
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 9, 2023
c4fc65a
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 13, 2023
336db71
Fixed the non-minified javascript file
Dec 16, 2023
688a130
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 16, 2023
4a6b96a
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 17, 2023
466450c
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 20, 2023
765b01b
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 24, 2023
6125d39
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 25, 2023
8113ffb
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 26, 2023
8c9663c
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Dec 29, 2023
5bc4c0a
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Jan 12, 2024
49385c4
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Jan 12, 2024
b0bd7f6
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Jan 26, 2024
3eb37cb
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Jan 26, 2024
1e5c5df
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Feb 5, 2024
5498ce8
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Feb 20, 2024
a44a052
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Feb 27, 2024
492edaa
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Feb 27, 2024
778a48b
Merge branch 'dotnet:main' into pseudo-elements-in-fallback-#38146
dasblinkenlight Mar 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions src/Mvc/Mvc.TagHelpers/src/LinkTagHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers;
[HtmlTargetElement("link", Attributes = FallbackHrefExcludeAttributeName, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("link", Attributes = FallbackTestClassAttributeName, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("link", Attributes = FallbackTestPropertyAttributeName, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("link", Attributes = FallbackTestPseudoElementAttributeName, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("link", Attributes = FallbackTestValueAttributeName, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("link", Attributes = AppendVersionAttributeName, TagStructure = TagStructure.WithoutEndTag)]
public class LinkTagHelper : UrlResolutionTagHelper
{
private static readonly string FallbackJavaScriptResourceName =
typeof(LinkTagHelper).Namespace + ".compiler.resources.LinkTagHelper_FallbackJavaScript.js";
private static readonly string FallbackWithPseudoJavaScriptResourceName =
typeof(LinkTagHelper).Namespace + ".compiler.resources.LinkTagHelper_FallbackWithPseudoJavaScript.js";

private const string HrefIncludeAttributeName = "asp-href-include";
private const string HrefExcludeAttributeName = "asp-href-exclude";
Expand All @@ -44,6 +47,7 @@ public class LinkTagHelper : UrlResolutionTagHelper
private const string FallbackHrefExcludeAttributeName = "asp-fallback-href-exclude";
private const string FallbackTestClassAttributeName = "asp-fallback-test-class";
private const string FallbackTestPropertyAttributeName = "asp-fallback-test-property";
private const string FallbackTestPseudoElementAttributeName = "asp-fallback-test-pseudo-element";
private const string FallbackTestValueAttributeName = "asp-fallback-test-value";
private const string AppendVersionAttributeName = "asp-append-version";
private const string HrefAttributeName = "href";
Expand Down Expand Up @@ -199,6 +203,14 @@ public LinkTagHelper(
[HtmlAttributeName(FallbackTestPropertyAttributeName)]
public string FallbackTestProperty { get; set; }

/// <summary>
/// The CSS pseudo-element name to use for the fallback test.
/// May be used in conjunction with <see cref="FallbackTestClass"/> and <see cref="FallbackTestValue"/>,
/// and either <see cref="FallbackHref"/> or <see cref="FallbackHrefInclude"/>.
/// </summary>
[HtmlAttributeName(FallbackTestPseudoElementAttributeName)]
public string FallbackTestPseudoElement { get; set; }

/// <summary>
/// The CSS property value to use for the fallback test.
/// Must be used in conjunction with <see cref="FallbackTestClass"/> and <see cref="FallbackTestProperty"/>,
Expand Down Expand Up @@ -358,9 +370,12 @@ private void BuildFallbackBlock(TagHelperAttributeList attributes, TagHelperCont
// <link /> tag to load the fallback stylesheet if the test CSS property value is found to be false,
// indicating that the primary stylesheet failed to load.
// GetEmbeddedJavaScript returns JavaScript to which we add '"{0}","{1}",{2});'
// or '"{0}","{1}",{2},{3});' depending an optional pseudo-element parameter.
var usePseudoElement = FallbackTestPseudoElement != null;
builder
.AppendHtml("<script>")
.AppendHtml(JavaScriptResources.GetEmbeddedJavaScript(FallbackJavaScriptResourceName))
.AppendHtml(JavaScriptResources.GetEmbeddedJavaScript(usePseudoElement ?
FallbackWithPseudoJavaScriptResourceName : FallbackJavaScriptResourceName))
.AppendHtml("\"")
.AppendHtml(JavaScriptEncoder.Encode(FallbackTestProperty))
.AppendHtml("\",\"")
Expand Down Expand Up @@ -395,8 +410,15 @@ private void BuildFallbackBlock(TagHelperAttributeList attributes, TagHelperCont
stringBuilder.Clear();
var encodedScriptTags = JavaScriptEncoder.Encode(scriptTags);
builder.AppendHtml(encodedScriptTags);

builder.AppendHtml("\");</script>");
builder.AppendHtml("\"");
if (usePseudoElement)
{
builder
.AppendHtml(", \"")
.AppendHtml(JavaScriptEncoder.Encode(FallbackTestPseudoElement))
.AppendHtml("\"");
}
builder.AppendHtml(");</script>");
}

private bool HasStyleSheetLinkType(TagHelperAttributeList attributes)
Expand Down
2 changes: 2 additions & 0 deletions src/Mvc/Mvc.TagHelpers/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#nullable enable
~Microsoft.AspNetCore.Mvc.TagHelpers.LinkTagHelper.FallbackTestPseudoElement.get -> string
~Microsoft.AspNetCore.Mvc.TagHelpers.LinkTagHelper.FallbackTestPseudoElement.set -> void

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
(
/**
* This function finds the previous element (assumed to be meta) and tests its current CSS style using the passed
* values and pseudo-element, to determine if a stylesheet was loaded. If not, this function loads
* the fallback stylesheet via document.write.
*
* @param {string} cssTestPropertyName - The name of the CSS property to test.
* @param {string} cssTestPropertyValue - The value to test the specified CSS property for.
* @param {string[]} fallbackHrefs - The URLs to the stylesheets to load in the case the test fails.
* @param {string} extraAttributes - The extra attributes string that should be included on the generated link tags.
* @param {string} pseudoElement - An optional string specifying the CSS pseudo-element to match.
*/
function loadFallbackStylesheet(cssTestPropertyName, cssTestPropertyValue, fallbackHrefs, extraAttributes, pseudoElement) {
var doc = document,
// Find the last script tag on the page which will be this one, as JS executes as it loads
scriptElements = doc.getElementsByTagName("SCRIPT"),
// Find the meta tag before this script tag, that's the element we're going to test the CSS property on
meta = scriptElements[scriptElements.length - 1].previousElementSibling,
// Get the current style of the meta tag starting with standards-based API and falling back to <=IE8 API
metaStyle = (doc.defaultView && doc.defaultView.getComputedStyle) ?
doc.defaultView.getComputedStyle(meta, pseudoElement) : meta.currentStyle,
i;

if (metaStyle && metaStyle[cssTestPropertyName] !== cssTestPropertyValue) {
for (i = 0; i < fallbackHrefs.length; i++) {
doc.write('<link href="' + fallbackHrefs[i] + '" ' + extraAttributes + '/>');
}
}
})();
Loading