/// <inheritdoc /> public override void Process(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } // Pass through attribute that is also a well-known HTML attribute. if (Src != null) { output.CopyHtmlAttribute(SrcAttributeName, context); } // If there's no "src" attribute in output.Attributes this will noop. ProcessUrlAttribute(SrcAttributeName, output); // Retrieve the TagHelperOutput variation of the "src" attribute in case other TagHelpers in the // pipeline have touched the value. If the value is already encoded this ScriptTagHelper may // not function properly. Src = output.Attributes[SrcAttributeName]?.Value as string; var modeResult = AttributeMatcher.DetermineMode(context, ModeDetails); modeResult.LogDetails(Logger, this, context.UniqueId, ViewContext.View.Path); if (!modeResult.FullMatches.Any()) { // No attributes matched so we have nothing to do return; } // NOTE: Values in TagHelperOutput.Attributes may already be HTML-encoded. var attributes = new TagHelperAttributeList(output.Attributes); if (AppendVersion == true) { EnsureFileVersionProvider(); if (Src != null) { output.Attributes[SrcAttributeName].Value = _fileVersionProvider.AddFileVersionToPath(Src); } } var builder = new DefaultTagHelperContent(); // Get the highest matched mode var mode = modeResult.FullMatches.Select(match => match.Mode).Max(); if (mode == Mode.GlobbedSrc || mode == Mode.Fallback && !string.IsNullOrEmpty(SrcInclude)) { BuildGlobbedScriptTags(attributes, builder); if (string.IsNullOrEmpty(Src)) { // Only SrcInclude is specified. Don't render the original tag. output.TagName = null; output.Content.SetContent(string.Empty); } } if (mode == Mode.Fallback) { string resolvedUrl; if (TryResolveUrl(FallbackSrc, encodeWebRoot: false, resolvedUrl: out resolvedUrl)) { FallbackSrc = resolvedUrl; } BuildFallbackBlock(attributes, builder); } output.PostElement.SetContent(builder); }
/// <inheritdoc /> /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks> /// <exception cref="InvalidOperationException"> /// Thrown if <see cref="Format"/> is non-<c>null</c> but <see cref="For"/> is <c>null</c>. /// </exception> public override void Process(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } // Pass through attributes that are also well-known HTML attributes. Must be done prior to any copying // from a TagBuilder. if (InputTypeName != null) { output.CopyHtmlAttribute("type", context); } if (Value != null) { output.CopyHtmlAttribute(nameof(Value), context); } // Note null or empty For.Name is allowed because TemplateInfo.HtmlFieldPrefix may be sufficient. // IHtmlGenerator will enforce name requirements. var metadata = For.Metadata; var modelExplorer = For.ModelExplorer; if (metadata == null) { throw new InvalidOperationException(Resources.FormatTagHelpers_NoProvidedMetadata( "<input>", ForAttributeName, nameof(IModelMetadataProvider), For.Name)); } string inputType; string inputTypeHint; if (string.IsNullOrEmpty(InputTypeName)) { // Note GetInputType never returns null. inputType = GetInputType(modelExplorer, out inputTypeHint); } else { inputType = InputTypeName.ToLowerInvariant(); inputTypeHint = null; } // inputType may be more specific than default the generator chooses below. if (!output.Attributes.ContainsName("type")) { output.Attributes["type"] = inputType; } TagBuilder tagBuilder; switch (inputType) { case "checkbox": GenerateCheckBox(modelExplorer, output); return; case "hidden": tagBuilder = Generator.GenerateHidden( ViewContext, modelExplorer, For.Name, value: For.Model, useViewData: false, htmlAttributes: null); break; case "password": tagBuilder = Generator.GeneratePassword( ViewContext, modelExplorer, For.Name, value: null, htmlAttributes: null); break; case "radio": tagBuilder = GenerateRadio(modelExplorer); break; default: tagBuilder = GenerateTextBox(modelExplorer, inputTypeHint, inputType); break; } if (tagBuilder != null) { // This TagBuilder contains the one <input/> element of interest. Since this is not the "checkbox" // special-case, output is a self-closing element no longer guaranteed. output.MergeAttributes(tagBuilder); output.Content.AppendHtml(tagBuilder.InnerHtml); } }
/// <inheritdoc /> public override void Process(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } // Pass through attribute that is also a well-known HTML attribute. if (Href != null) { output.CopyHtmlAttribute(HrefAttributeName, context); } // If there's no "href" attribute in output.Attributes this will noop. ProcessUrlAttribute(HrefAttributeName, output); // Retrieve the TagHelperOutput variation of the "href" attribute in case other TagHelpers in the // pipeline have touched the value. If the value is already encoded this LinkTagHelper may // not function properly. Href = output.Attributes[HrefAttributeName]?.Value as string; // NOTE: Values in TagHelperOutput.Attributes may already be HTML-encoded. var attributes = new TagHelperAttributeList(output.Attributes); var builder = new DefaultTagHelperContent(); if (!string.IsNullOrEmpty(HrefInclude)) { BuildGlobbedLinkTags(attributes, builder); if (string.IsNullOrEmpty(Href)) { // Only HrefInclude is specified. Don't render the original tag. output.TagName = null; output.Content.SetContent(HtmlString.Empty); } } output.PostElement.SetContent(builder); }
// public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { bool useSiteMinJs = UseSiteMinJs?.Contains(HostingEnvironment.EnvironmentName, StringComparison.OrdinalIgnoreCase) == true; if (WarnIfTestIsInvalid?.Contains(HostingEnvironment.EnvironmentName, StringComparison.OrdinalIgnoreCase) == true) { var x = await output.GetChildContentAsync(); if (!useSiteMinJs) output.PreElement.AppendHtml(string.Format(_preTest, FallbackTest, $"Script `{RemotePath}` already loaded. Did you create the correct test")); output.PostElement.AppendHtml(string.Format(_postTest, FallbackTest, $"Script `{RemotePath}` still not loaded. Did you create the correct test")); } var LocalRelPath = ""; if (CopySrcToFallback?.Contains(HostingEnvironment.EnvironmentName, StringComparison.OrdinalIgnoreCase) == true) { try { var scheme = Context.HttpContext.Request.Scheme; RemotePath = RemotePath.StartsWith("//") ? scheme + ":" + RemotePath : RemotePath.ToLower().StartsWith("/") || RemotePath.ToLower().StartsWith("~/") ? scheme + "://" + Context.HttpContext.Request.Host + RemotePath.Replace("~", "") : RemotePath; LocalRelPath = (useSiteMinJs == false) ? "/js/" + new Uri(RemotePath).Segments.Last() : FallbackSrc ?? "/fallback/js/" + new Uri(RemotePath).Segments.Last(); var localPath = HostingEnvironment.MapPath(LocalRelPath.TrimStart('/')); var pathHelper = new PathHelper(RemotePath, localPath); if (!File.Exists(localPath)) { using (var webClient = new HttpClient()) { var file = await webClient.GetStringAsync(new Uri(RemotePath)); Directory.CreateDirectory(pathHelper.LocalDirectory); File.WriteAllText(localPath, file); if (RemotePath.Contains(".min.") && UseSiteMinJs != null)//copy full version to let gulp minify this verion to site.css { file = await webClient.GetStringAsync(new Uri(RemotePath.Replace(".min", ""))); File.WriteAllText(localPath, file); } if (!RemotePath.Contains(".min.") && UseMinified != null) { file = await webClient.GetStringAsync(new Uri(RemotePath.Replace(".js", ".min.js"))); File.WriteAllText(localPath, file); } } } } catch (HttpRequestException ex) { throw new FileNotFoundException($"The remote file:{RemotePath} cannot be found.", ex); } } if (context.AllAttributes.ContainsName("src")) { output.CopyHtmlAttribute("src", context); if (UseLocal?.Contains(HostingEnvironment.EnvironmentName, StringComparison.OrdinalIgnoreCase) == true) output.Attributes["src"].Value = LocalRelPath; string href = output.Attributes["src"].Value.ToString(); if (UseMinified?.Contains(HostingEnvironment.EnvironmentName, StringComparison.OrdinalIgnoreCase) == true && !href.Contains(".min.")) output.Attributes["src"] = href.Replace(".js", ".min.js"); if (useSiteMinJs) output.Attributes["src"].Value = ""; } }
/// <inheritdoc /> public override void Process(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } output.CopyHtmlAttribute(SrcAttributeName, context); ProcessUrlAttribute(SrcAttributeName, output); if (AppendVersion) { EnsureFileVersionProvider(); // Retrieve the TagHelperOutput variation of the "src" attribute in case other TagHelpers in the // pipeline have touched the value. If the value is already encoded this ImageTagHelper may // not function properly. Src = output.Attributes[SrcAttributeName].Value as string; output.Attributes[SrcAttributeName] = _fileVersionProvider.AddFileVersionToPath(Src); } }
/// <inheritdoc /> public override void Process(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } // Pass through attribute that is also a well-known HTML attribute. if (Href != null) { output.CopyHtmlAttribute(HrefAttributeName, context); } // If there's no "href" attribute in output.Attributes this will noop. ProcessUrlAttribute(HrefAttributeName, output); // Retrieve the TagHelperOutput variation of the "href" attribute in case other TagHelpers in the // pipeline have touched the value. If the value is already encoded this LinkTagHelper may // not function properly. Href = output.Attributes[HrefAttributeName]?.Value as string; Mode mode; if (!AttributeMatcher.TryDetermineMode(context, ModeDetails, Compare, out mode)) { // No attributes matched so we have nothing to do return; } // NOTE: Values in TagHelperOutput.Attributes may already be HTML-encoded. var attributes = new TagHelperAttributeList(output.Attributes); if (AppendVersion == true) { EnsureFileVersionProvider(); if (Href != null) { output.Attributes[HrefAttributeName].Value = _fileVersionProvider.AddFileVersionToPath(Href); } } var builder = new DefaultTagHelperContent(); if (mode == Mode.GlobbedHref || mode == Mode.Fallback && !string.IsNullOrEmpty(HrefInclude)) { BuildGlobbedLinkTags(attributes, builder); if (string.IsNullOrEmpty(Href)) { // Only HrefInclude is specified. Don't render the original tag. output.TagName = null; output.Content.SetContent(HtmlString.Empty); } } if (mode == Mode.Fallback) { string resolvedUrl; if (TryResolveUrl(FallbackHref, resolvedUrl: out resolvedUrl)) { FallbackHref = resolvedUrl; } BuildFallbackBlock(builder); } output.PostElement.SetContent(builder); }
/// <inheritdoc /> /// <remarks> /// Does nothing unless <see cref="TagHelperContext.Items"/> contains a /// <see cref="SelectTagHelper"/> <see cref="Type"/> entry and that entry is a non-empty /// <see cref="ICollection{string}"/> instance. Also does nothing if the associated <option> is already /// selected. /// </remarks> public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } // Pass through attributes that are also well-known HTML attributes. if (Value != null) { output.CopyHtmlAttribute(nameof(Value), context); } // Nothing to do if this <option/> is already selected. if (!output.Attributes.ContainsName("selected")) { // Is this <option/> element a child of a <select/> element the SelectTagHelper targeted? object formDataEntry; context.Items.TryGetValue(typeof(SelectTagHelper), out formDataEntry); // ... And did the SelectTagHelper determine any selected values? var selectedValues = formDataEntry as ICollection<string>; if (selectedValues != null && selectedValues.Count != 0) { // Encode all selected values for comparison with element content. var encodedValues = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (var selectedValue in selectedValues) { encodedValues.Add(Generator.Encode(selectedValue)); } // Select this <option/> element if value attribute or content matches a selected value. Callers // encode values as-needed while executing child content. But TagHelperOutput itself // encodes attribute values later, when start tag is generated. bool selected; if (Value != null) { selected = selectedValues.Contains(Value); } else if (output.IsContentModified) { selected = encodedValues.Contains(output.Content.GetContent()); } else { var childContent = await output.GetChildContentAsync(); selected = encodedValues.Contains(childContent.GetContent()); } if (selected) { output.Attributes.Add("selected", "selected"); } } } }