private void BuildFallbackBlock(TagHelperAttributeList attributes, DefaultTagHelperContent builder) { EnsureGlobbingUrlBuilder(); var fallbackSrcs = GlobbingUrlBuilder.BuildUrlList(FallbackSrc, FallbackSrcInclude, FallbackSrcExclude); if (fallbackSrcs.Any()) { // Build the <script> tag that checks the test method and if it fails, renders the extra script. builder.Append(Environment.NewLine) .Append("<script>(") .Append(FallbackTestExpression) .Append("||document.write(\""); // May have no "src" attribute in the dictionary e.g. if Src and SrcInclude were not bound. if (!attributes.ContainsName(SrcAttributeName)) { // Need this entry to place each fallback source. attributes.Add(new TagHelperAttribute(SrcAttributeName, value: null)); } foreach (var src in fallbackSrcs) { // Fallback "src" values come from bound attributes and globbing. Must always be non-null. Debug.Assert(src != null); builder.Append("<script"); foreach (var attribute in attributes) { if (!attribute.Name.Equals(SrcAttributeName, StringComparison.OrdinalIgnoreCase)) { var encodedKey = JavaScriptEncoder.JavaScriptStringEncode(attribute.Name); var attributeValue = attribute.Value.ToString(); var encodedValue = JavaScriptEncoder.JavaScriptStringEncode(attributeValue); AppendAttribute(builder, encodedKey, encodedValue, escapeQuotes: true); } else { // Ignore attribute.Value; use src instead. var attributeValue = src; if (AppendVersion == true) { attributeValue = _fileVersionProvider.AddFileVersionToPath(attributeValue); } // attribute.Key ("src") does not need to be JavaScript-encoded. var encodedValue = JavaScriptEncoder.JavaScriptStringEncode(attributeValue); AppendAttribute(builder, attribute.Name, encodedValue, escapeQuotes: true); } } builder.Append("><\\/script>"); } builder.Append("\"));</script>"); } }
private void BuildFallbackBlock(TagHelperContent builder) { EnsureGlobbingUrlBuilder(); var fallbackHrefs = GlobbingUrlBuilder.BuildUrlList(FallbackHref, FallbackHrefInclude, FallbackHrefExclude).ToArray(); if (fallbackHrefs.Length > 0) { if (AppendVersion == true) { for (var i = 0; i < fallbackHrefs.Length; i++) { // fallbackHrefs come from bound attributes and globbing. Must always be non-null. Debug.Assert(fallbackHrefs[i] != null); fallbackHrefs[i] = _fileVersionProvider.AddFileVersionToPath(fallbackHrefs[i]); } } builder.Append(HtmlString.NewLine); // Build the <meta /> tag that's used to test for the presence of the stylesheet builder .AppendEncoded("<meta name=\"x-stylesheet-fallback-test\" class=\"") .Append(FallbackTestClass) .AppendEncoded("\" />"); // Build the <script /> tag that checks the effective style of <meta /> tag above and renders the extra // <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. builder .AppendEncoded("<script>") .AppendEncoded( string.Format( CultureInfo.InvariantCulture, JavaScriptResources.GetEmbeddedJavaScript(FallbackJavaScriptResourceName), JavaScriptEncoder.JavaScriptStringEncode(FallbackTestProperty), JavaScriptEncoder.JavaScriptStringEncode(FallbackTestValue), JavaScriptStringArrayEncoder.Encode(JavaScriptEncoder, fallbackHrefs))) .AppendEncoded("</script>"); } }