public void AddHtmlAttribute_MaintainsHtmlAttributes_VariousStyles()
        {
            // Arrange
            var executionContext   = new TagHelperExecutionContext("input", tagMode: TagMode.SelfClosing);
            var expectedAttributes = new TagHelperAttributeList
            {
                { "class", "btn" },
                { "foo", "bar" }
            };

            expectedAttributes.Add(new TagHelperAttribute("valid", "true", HtmlAttributeValueStyle.NoQuotes));
            expectedAttributes.Add(new TagHelperAttribute("type", "text", HtmlAttributeValueStyle.SingleQuotes));
            expectedAttributes.Add(new TagHelperAttribute(name: "checked"));
            expectedAttributes.Add(new TagHelperAttribute(name: "visible"));

            // Act
            executionContext.AddHtmlAttribute("class", "btn", HtmlAttributeValueStyle.DoubleQuotes);
            executionContext.AddHtmlAttribute("foo", "bar", HtmlAttributeValueStyle.DoubleQuotes);
            executionContext.AddHtmlAttribute("valid", "true", HtmlAttributeValueStyle.NoQuotes);
            executionContext.AddHtmlAttribute("type", "text", HtmlAttributeValueStyle.SingleQuotes);
            executionContext.AddHtmlAttribute(new TagHelperAttribute("checked"));
            executionContext.AddHtmlAttribute(new TagHelperAttribute("visible"));
            var output = executionContext.Output;

            // Assert
            Assert.Equal(
                expectedAttributes,
                output.Attributes,
                CaseSensitiveTagHelperAttributeComparer.Default);
        }
示例#2
0
        protected virtual TagHelperAttributeList GetInputAttributes(TagHelperContext context, TagHelperOutput output)
        {
            var groupPrefix = "group-";

            var tagHelperAttributes = output.Attributes.Where(a => !a.Name.StartsWith(groupPrefix)).ToList();

            var attrList = new TagHelperAttributeList();

            foreach (var tagHelperAttribute in tagHelperAttributes)
            {
                attrList.Add(tagHelperAttribute);
            }

            if (!TagHelper.InputTypeName.IsNullOrEmpty() && !attrList.ContainsName("type"))
            {
                attrList.Add("type", TagHelper.InputTypeName);
            }

            if (!TagHelper.Name.IsNullOrEmpty() && !attrList.ContainsName("name"))
            {
                attrList.Add("name", TagHelper.Name);
            }

            if (!TagHelper.Value.IsNullOrEmpty() && !attrList.ContainsName("value"))
            {
                attrList.Add("value", TagHelper.Value);
            }

            return(attrList);
        }
示例#3
0
        private async Task <string> RenderTextInputAsync()
        {
            var inputTagHelper = new InputTagHelper(this.HtmlGenerator);

            inputTagHelper.For           = this.DataModel;
            inputTagHelper.InputTypeName = this.Type;
            inputTagHelper.Format        = "{0}";
            inputTagHelper.Value         = this.DataModel.Model == null ? string.Empty : this.DataModel.Model.ToString();
            inputTagHelper.ViewContext   = this.ViewContext;

            TagHelperAttributeList attributes = new TagHelperAttributeList();

            attributes.Add(new TagHelperAttribute("class", "form-control"));
            attributes.Add(new TagHelperAttribute("type", inputTagHelper.InputTypeName));
            if (this.Type != "password")
            {
                attributes.Add(new TagHelperAttribute("value", inputTagHelper.Value));
            }
            else
            {
                attributes.Add(new TagHelperAttribute("value", string.Empty));
            }

            attributes.Add(new TagHelperAttribute("placeholder", this.Placeholder));

            return(await this.RenderTagHelperAsync("input", TagMode.SelfClosing, inputTagHelper, attributes));
        }
        public void AddMinimizedHtmlAttribute_MaintainsHtmlAttributes_SomeMinimized()
        {
            // Arrange
            var executionContext   = new TagHelperExecutionContext("input", tagMode: TagMode.SelfClosing);
            var expectedAttributes = new TagHelperAttributeList
            {
                { "class", "btn" },
                { "foo", "bar" }
            };

            expectedAttributes.Add(new TagHelperAttribute(name: "checked"));
            expectedAttributes.Add(new TagHelperAttribute(name: "visible"));

            // Act
            executionContext.AddHtmlAttribute("class", "btn");
            executionContext.AddHtmlAttribute("foo", "bar");
            executionContext.AddMinimizedHtmlAttribute("checked");
            executionContext.AddMinimizedHtmlAttribute("visible");
            var output = executionContext.Output;

            // Assert
            Assert.Equal(
                expectedAttributes,
                output.Attributes,
                CaseSensitiveTagHelperAttributeComparer.Default);
        }
        /// <summary>
        /// Tracks the HTML attribute.
        /// </summary>
        /// <param name="attribute">The <see cref="TagHelperAttribute"/> to track.</param>
        public void AddHtmlAttribute(TagHelperAttribute attribute)
        {
            if (attribute == null)
            {
                throw new ArgumentNullException(nameof(attribute));
            }

            Output.Attributes.Add(attribute);
            _allAttributes.Add(attribute);
        }
 static public void AddHtmlStringAttribute(this TagHelperAttributeList attributes, string name, object value)
 {
     if (value?.GetType() == typeof(string))
     {
         attributes.Add(name, new HtmlString((string)value));
     }
     else
     {
         attributes.Add(name, value);
     }
 }
示例#7
0
        protected TagHelperOutput ProcessTag <TTag>(
            TTag tag,
            string html,
            object attributes,
            string childContent = "") where TTag : TagHelper
        {
            var context = new TagHelperContext(
                new TagHelperAttributeList(),
                new Dictionary <object, object>(),
                Guid.NewGuid().ToString("N"));

            var dictionary          = HtmlHelper.AnonymousObjectToHtmlAttributes(attributes);
            var tagHelperAttributes = new TagHelperAttributeList();

            dictionary.ForEach(item => tagHelperAttributes.Add(item.Key, item.Value));

            var output = new TagHelperOutput(
                html,
                tagHelperAttributes,
                (result, encoder) =>
            {
                var tagHelperContent = new DefaultTagHelperContent();
                tagHelperContent.SetHtmlContent(childContent);
                return(Task.FromResult <TagHelperContent>(tagHelperContent));
            });

            tag.Process(context, output);

            return(output);
        }
 public static void Add(this TagHelperAttributeList tagHelperAttributeList, TagHelperAttributeList newTagHelperAttributeList)
 {
     foreach (TagHelperAttribute attr in newTagHelperAttributeList)
     {
         tagHelperAttributeList.Add(attr);
     }
 }
示例#9
0
        /// <summary>
        ///     Sets an attribute value by name to 'value.ToString()'. If 'replace' is false, the attribute is only set if not
        ///     already set. If 'value' is null, the entry is removed from the list instead.
        /// </summary>
        /// <exception cref="ArgumentException"> Thrown if 'name' is null or empty. </exception>
        /// <param name="list"> The TagHelperAttributeList to merge an attribute value with. </param>
        /// <param name="name"> The key to set a value for. </param>
        /// <param name="value">
        ///     The value to set for the specified key, which will be converted to a string first. If null, any existing entry is
        ///     removed instead (if 'replace' is true).
        /// </param>
        /// <param name="replace">
        ///     (Optional) If true (the default) adds a new entry or replaces an existing entry, otherwise the request is ignored.
        ///     If this is false, nothing is removed, and any merge requests with existing keys will be ignored.
        /// </param>
        /// <param name="removeOnEmptyOrWhitespace">
        ///     (Optional) If true (default) any empty or whitespace-only values will remove the attribute. This is in addition to
        ///     'null', which always removes values.
        /// </param>
        /// <param name="replaceIfValueNotEmpty">
        ///     (Optional) If true, any existing entry is only replaced if the given value is not empty or whitespace only. Default
        ///     is false. This setting has no affect if the 'replace' parameter is false.
        /// </param>
        public static void MergeAttribute(this TagHelperAttributeList list, string name, object value, bool replace = true, bool removeOnEmptyOrWhitespace = true, bool replaceIfValueNotEmpty = false)
        {
            if (name == null)
            {
                throw new ArgumentException("Value cannot be null.", nameof(name));
            }
            else if (name is string && string.IsNullOrEmpty((string)(object)name))
            {
                throw new ArgumentException("Value cannot be null or empty.", nameof(name));
            }

            if (replace || value != null && !list.ContainsName(name))
            {
                var valueStr = value?.ToString().Trim();
                var isEmpty  = string.IsNullOrWhiteSpace(valueStr);
                if (valueStr == null || removeOnEmptyOrWhitespace && isEmpty)
                {
                    list.RemoveAll(name);
                }
                else if (!replaceIfValueNotEmpty || !isEmpty)
                {
                    list.Add(name, valueStr);
                }
            }
        }
示例#10
0
 public static void AddIfNotContains(this TagHelperAttributeList attributes, string name, object value)
 {
     if (!attributes.ContainsName(name))
     {
         attributes.Add(name, value);
     }
 }
示例#11
0
        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>");
            }
        }
 public static void AddIfNotContains(this TagHelperAttributeList attributes, string name, object value)
 {
     if (!attributes.ContainsName("method"))
     {
         attributes.Add("method", "post");
     }
 }
示例#13
0
        public static void AddOrIgnore(this TagHelperAttributeList attrs, string name, object value)
        {
            if (attrs.ContainsName(name))
            {
                return;
            }

            attrs.Add(name, value);
        }
示例#14
0
        public static void AddAttribute(this TagHelperAttributeList attributes, string attributeName, string valueToAdd)
        {
            TagHelperAttribute attr = attributes[attributeName];

            if (attr == null)
            {
                attributes.Add(attributeName, valueToAdd);
            }
        }
        private async Task <string> RenderCheckboxInputAsync()
        {
            var inputTagHelper = new InputTagHelper(this.HtmlGenerator);

            inputTagHelper.For           = this.DataModel;
            inputTagHelper.InputTypeName = "checkbox";
            inputTagHelper.Format        = "{0}";
            inputTagHelper.Value         = this.DataModel.Model == null ? string.Empty : this.DataModel.Model.ToString();
            inputTagHelper.ViewContext   = this.ViewContext;

            TagHelperAttributeList attributes = new TagHelperAttributeList();

            attributes.Add(new TagHelperAttribute("class", new HtmlString("form-check-input")));
            attributes.Add(new TagHelperAttribute("type", new HtmlString(inputTagHelper.InputTypeName)));
            attributes.Add(new TagHelperAttribute("value", new HtmlString(inputTagHelper.Value)));

            return(await this.RenderTagHelperAsync("input", TagMode.SelfClosing, inputTagHelper, attributes));
        }
示例#16
0
 public override void Process(TagHelperContext context, TagHelperOutput output)
 {
     if (ShouldAddActive())
     {
         TagHelperAttributeList attrs = output.Attributes;
         attrs.RemoveAll("active-if-route");
         attrs.Add("class", "active");
     }
 }
示例#17
0
        private async Task <TabTagHelper> ConvertToTagHelper(TabItem item)
        {
            var tagHelper = new TabTagHelper
            {
                ViewContext = TabStrip.ViewContext,
                Selected    = item.Selected,
                Disabled    = !item.Enabled,
                Visible     = item.Visible,
                Ajax        = item.Ajax,
                Title       = item.Text,
                Name        = item.Name,
                BadgeStyle  = (BadgeStyle)item.BadgeStyle,
                BadgeText   = item.BadgeText,
                Icon        = item.Icon,
                ImageUrl    = item.ImageUrl,
                Summary     = item.Summary
            };

            // Create TagHelperContext for tab passing it parent context's items dictionary (that's what Razor does)
            var context = new TagHelperContext("tab", new TagHelperAttributeList(), Context.Items, CommonHelper.GenerateRandomDigitCode(10));

            // Must init tab, otherwise "Tabs" list is empty inside tabstrip helper.
            tagHelper.Init(context);

            var outputAttrList = new TagHelperAttributeList();

            item.HtmlAttributes.CopyTo(outputAttrList);
            item.LinkHtmlAttributes.CopyTo(outputAttrList);

            if (!item.HasContent && item.HasRoute)
            {
                outputAttrList.Add("href", item.GenerateUrl(tagHelper.UrlHelper));
            }

            var output = new TagHelperOutput("tab", outputAttrList, async(_, _) =>
            {
                var content = item.HasContent
                    ? await item.GetContentAsync(tagHelper.ViewContext)
                    : HtmlString.Empty;

                var contentTag = new TagBuilder("div");
                contentTag.MergeAttributes(item.ContentHtmlAttributes, false);

                TagHelperContent tabContent = new DefaultTagHelperContent()
                                              .AppendHtml(contentTag.Attributes.Count > 0 ? contentTag.RenderStartTag() : HtmlString.Empty)
                                              .AppendHtml(content)
                                              .AppendHtml(contentTag.Attributes.Count > 0 ? contentTag.RenderEndTag() : HtmlString.Empty);

                return(tabContent);
            });

            // Process tab
            await tagHelper.ProcessAsync(context, output);

            return(tagHelper);
        }
        public TagHelperContext CreateContext(bool hasMarkdownAttribute)
        {
            if (hasMarkdownAttribute)
            {
                _inputAttributes.Add(new TagHelperAttribute("markdown", ""));
            }
            var context = new TagHelperContext(_inputAttributes, _items, Guid.NewGuid().ToString());

            return(context);
        }
    public static void Merge(this TagHelperAttributeList attributes, string name, object value)
    {
        var attr = attributes.FirstOrDefault(a => a.Name == name);

        if (attr != null)
        {
            attributes.Remove(attr);
        }
        attributes.Add(name, $"{value} {attr?.Value}");
    }
示例#20
0
        private async Task <string> RenderTextInputAsync()
        {
            var inputTagHelper = new InputTagHelper(this.htmlGenerator);

            inputTagHelper.For           = DataModel;
            inputTagHelper.InputTypeName = Type;
            inputTagHelper.Format        = "{0}";
            inputTagHelper.Value         = DataModel.Model == null ? string.Empty : DataModel.Model.ToString();
            inputTagHelper.ViewContext   = ViewContext;

            TagHelperAttributeList attributes = new TagHelperAttributeList();

            attributes.Add(new TagHelperAttribute("class", new HtmlString("form-control")));
            attributes.Add(new TagHelperAttribute("type", new HtmlString(inputTagHelper.InputTypeName)));
            attributes.Add(new TagHelperAttribute("value", new HtmlString(inputTagHelper.Value)));
            attributes.Add(new TagHelperAttribute("placeholder", new HtmlString(Placeholder)));

            return(await RenderTagHelperAsync("input", TagMode.SelfClosing, inputTagHelper, attributes));
        }
    public static void Merge(this TagHelperAttributeList attributes, string name, string value)
    {
        if (attributes == null)
        {
            throw new ArgumentNullException(nameof(attributes));
        }

        var curr = attributes.FirstOrDefault(att => string.Equals(att.Name, name, StringComparison.Ordinal));

        if (curr == null)
        {
            attributes.Add(name, value);
        }
        else
        {
            attributes.Remove(curr);
            attributes.Add(name, $"{curr.Value} {value}");
        }
    }
        protected virtual TagHelperAttributeList GetAttributesForMainButton(TagHelperContext context, TagHelperOutput output)
        {
            var attributes = new TagHelperAttributeList();

            foreach (var tagHelperAttribute in output.Attributes)
            {
                attributes.Add(tagHelperAttribute);
            }

            if (TagHelper.DropdownStyle != DropdownStyle.Split)
            {
                attributes.AddClass("dropdown-toggle");
                attributes.Add("data-toggle", "dropdown");
                attributes.Add("aria-haspopup", "true");
                attributes.Add("aria-expanded", "false");
            }

            return(attributes);
        }
示例#23
0
        public static void AddClass(this TagHelperAttributeList attrList, string cssClass)
        {
            var attrs = attrList.Where(a => a.Name.Equals("class"));

            if (attrs.Count() == 1)
            {
                TagHelperAttribute classAttr = attrs.First();
                attrList.Remove(classAttr);
                attrList.Add(new TagHelperAttribute("class", $"{classAttr.Value} autocomplete"));
            }
        }
 public static void AddOrUpdate(this TagHelperAttributeList attributes, string name, object value)
 {
     if (attributes.ContainsName(name))
     {
         attributes.SetAttribute(name, value);
     }
     else
     {
         attributes.Add(name, value);
     }
 }
示例#25
0
        public static void Merge(this TagHelperAttributeList attributes, string name, string value)
        {
            var attr   = attributes[name];
            var _value = (value + " " + attr?.Value ?? "").Trim();

            if (attr != null)
            {
                attributes.Remove(attr);
            }

            attributes.Add(name, _value);
        }
        public TagHelperOutput CreateOutput(string tagName, bool hasMarkdownAttribute, string tagContent)
        {
            var childContent = GetChildContent(tagContent);

            if (hasMarkdownAttribute)
            {
                _outputAttributes.Add(new TagHelperAttribute("markdown", ""));
            }

            return(new TagHelperOutput(tagName,
                                       _outputAttributes, GetChildContent(tagContent)));
        }
示例#27
0
        private async Task <string> buildInputHtml(ModelExplorer property, TweakingConfiguration tweakingConfig,
                                                   string inputType = "", string inputValue = "", bool radioChecked = false)
        {
            PropertyTweakingConfiguration propertyConfig = tweakingConfig.GetByPropertyFullName(property.GetFullName());

            if (propertyConfig == null || string.IsNullOrEmpty(propertyConfig.InputTemplatePath))
            {
                InputTagHelper input = new InputTagHelper(_htmlGenerator)
                {
                    For         = new ModelExpression(property.GetFullName(), property),
                    ViewContext = _viewContext
                };
                var attrs = new TagHelperAttributeList {
                    new TagHelperAttribute("class", $"form-control {propertyConfig?.InputClasses}")
                };

                if (!string.IsNullOrEmpty(inputType))
                {
                    input.InputTypeName = inputType;
                    input.Value         = inputValue;
                    // Setting the Type attributes requires providing an initialized
                    // AttributeList with the type attribute
                    attrs = new TagHelperAttributeList()
                    {
                        new TagHelperAttribute("class", $"{propertyConfig?.InputClasses}"),
                        new TagHelperAttribute("type", inputType),
                        new TagHelperAttribute("value", inputValue)
                    };
                    if (radioChecked)
                    {
                        attrs.Add(new TagHelperAttribute("checked", "checked"));
                    }
                }

                AutoCompleteAttribute autoComplete;
                if (property.HasAutoComplete(out autoComplete))
                {
                    attrs.AddClass("autocomplete");
                    attrs.Add(getAutoCompleteDataAttribute(autoComplete, property.Container));
                }

                return(await GetGeneratedContentFromTagHelper("input",
                                                              TagMode.SelfClosing,
                                                              input,
                                                              attributes : attrs
                                                              ));
            }
            else
            {
                return(renderInputTemplate(property, propertyConfig.InputTemplatePath));
            }
        }
示例#28
0
        public void HandlesMultipleAttributesSameNameCorrectly(TagHelperAttributeList outputAttributes)
        {
            // Arrange
            var allAttributes = new TagHelperAttributeList(
                outputAttributes.Concat(
                    new TagHelperAttributeList
            {
                { "rel", new HtmlString("stylesheet") },
                { "href", "test.css" },
                { "asp-fallback-href", "test.css" },
                { "asp-fallback-test-class", "hidden" },
                { "asp-fallback-test-property", "visibility" },
                { "asp-fallback-test-value", "hidden" },
            }));
            var context = MakeTagHelperContext(allAttributes);
            var combinedOutputAttributes = new TagHelperAttributeList(
                outputAttributes.Concat(
                    new[]
            {
                new TagHelperAttribute("rel", new HtmlString("stylesheet"))
            }));
            var output             = MakeTagHelperOutput("link", combinedOutputAttributes);
            var logger             = new Mock <ILogger <LinkTagHelper> >();
            var hostingEnvironment = MakeHostingEnvironment();
            var viewContext        = MakeViewContext();

            var helper = new LinkTagHelper(
                logger.Object,
                hostingEnvironment,
                MakeCache(),
                new CommonTestEncoder(),
                new CommonTestEncoder(),
                MakeUrlHelper())
            {
                ViewContext          = viewContext,
                FallbackHref         = "test.css",
                FallbackTestClass    = "hidden",
                FallbackTestProperty = "visibility",
                FallbackTestValue    = "hidden",
                Href = "test.css",
            };
            var expectedAttributes = new TagHelperAttributeList(output.Attributes);

            expectedAttributes.Add(new TagHelperAttribute("href", "test.css"));

            // Act
            helper.Process(context, output);

            // Assert
            Assert.Equal(expectedAttributes, output.Attributes);
        }
示例#29
0
        protected virtual TagHelperAttributeList GetInputAttributes(TagHelperContext context, TagHelperOutput output)
        {
            var groupPrefix = "group-";

            var tagHelperAttributes = output.Attributes.Where(a => !a.Name.StartsWith(groupPrefix)).ToList();
            var attrList            = new TagHelperAttributeList();

            foreach (var tagHelperAttribute in tagHelperAttributes)
            {
                attrList.Add(tagHelperAttribute);
            }

            return(attrList);
        }
        }                                                                // B

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            const string appendVersion = "asp-append-version";

            if (!context.AllAttributes.Any(a => a.Name == appendVersion))
            {
                var attributes = new TagHelperAttributeList(context.AllAttributes);
                attributes.Add(appendVersion, true);
                context = new TagHelperContext(attributes, context.Items, context.UniqueId);
            } // E

            base.AppendVersion = true; // C
            base.Process(context, output); // D
        }
示例#31
0
        public async Task HandlesMultipleAttributesSameNameCorrectly(TagHelperAttributeList outputAttributes)
        {
            // Arrange
            var allAttributes = new TagHelperAttributeList(
                outputAttributes.Concat(
                    new TagHelperAttributeList
                    {
                        ["data-extra"] = "something",
                        ["src"] = "/blank.js",
                        ["asp-fallback-src"] = "http://www.example.com/blank.js",
                        ["asp-fallback-test"] = "isavailable()",
                    }));
            var tagHelperContext = MakeTagHelperContext(allAttributes);
            var viewContext = MakeViewContext();
            var combinedOutputAttributes = new TagHelperAttributeList(
                outputAttributes.Concat(
                    new[]
                    {
                        new TagHelperAttribute("data-extra", new HtmlString("something"))
                    }));
            var output = MakeTagHelperOutput("script", combinedOutputAttributes);
            var hostingEnvironment = MakeHostingEnvironment();

            var helper = new ScriptTagHelper(
                CreateLogger(),
                hostingEnvironment,
                MakeCache(),
                new CommonTestEncoder(),
                new CommonTestEncoder(),
                MakeUrlHelper())
            {
                ViewContext = viewContext,
                FallbackSrc = "~/blank.js",
                FallbackTestExpression = "http://www.example.com/blank.js",
                Src = "/blank.js",
            };
            var expectedAttributes = new TagHelperAttributeList(output.Attributes);
            expectedAttributes.Add(new TagHelperAttribute("src", "/blank.js"));

            // Act
            await helper.ProcessAsync(tagHelperContext, output);

            // Assert
            Assert.Equal(expectedAttributes, output.Attributes);
        }
        public async Task ProcessAsync_GeneratesExpectedOutput(
            string originalContent,
            string selected,
            string value,
            IEnumerable<string> selectedValues,
            TagHelperOutput expectedTagHelperOutput)
        {
            // Arrange
            var originalAttributes = new TagHelperAttributeList
            {
                { "label", "my-label" },
            };
            if (selected != null)
            {
                originalAttributes.Add("selected", selected);
            }

            var contextAttributes = new TagHelperAttributeList(originalAttributes);
            if (value != null)
            {
                contextAttributes.Add("value", value);
            }

            var tagHelperContext = new TagHelperContext(
                contextAttributes,
                items: new Dictionary<object, object>(),
                uniqueId: "test",
                getChildContentAsync: () =>
                {
                    // GetChildContentAsync should not be invoked since we are setting the content below.
                    Assert.True(false);
                    return Task.FromResult<TagHelperContent>(null);
                });

            var output = new TagHelperOutput(expectedTagHelperOutput.TagName, originalAttributes)
            {
                SelfClosing = false,
            };

            output.Content.SetContent(originalContent);

            var metadataProvider = new EmptyModelMetadataProvider();
            var htmlGenerator = new TestableHtmlGenerator(metadataProvider);
            var viewContext = TestableHtmlGenerator.GetViewContext(
                model: null,
                htmlGenerator: htmlGenerator,
                metadataProvider: metadataProvider);
            viewContext.FormContext.FormData[SelectTagHelper.SelectedValuesFormDataKey] = selectedValues;
            var tagHelper = new OptionTagHelper(htmlGenerator)
            {
                Value = value,
                ViewContext = viewContext,
            };

            // Act
            await tagHelper.ProcessAsync(tagHelperContext, output);

            // Assert
            Assert.Equal(expectedTagHelperOutput.TagName, output.TagName);
            Assert.Equal(expectedTagHelperOutput.Content.GetContent(), output.Content.GetContent());
            Assert.Equal(expectedTagHelperOutput.Attributes.Count, output.Attributes.Count);
            foreach (var attribute in output.Attributes)
            {
                Assert.Contains(attribute, expectedTagHelperOutput.Attributes);
            }
        }
        public void Add_ThrowsWhenNameIsNull()
        {
            // Arrange
            var attributes = new TagHelperAttributeList();
            var expectedMessage = $"Cannot add a '{typeof(TagHelperAttribute).FullName}' with a null " +
                $"'{nameof(TagHelperAttribute.Name)}'.{Environment.NewLine}Parameter name: attribute";

            // Act & Assert
            var exception = Assert.Throws<ArgumentException>("attribute",
                () => attributes.Add(new TagHelperAttribute
                {
                    Value = "Anything"
                }));
            Assert.Equal(expectedMessage, exception.Message);
        }
示例#34
0
        public void HandlesMultipleAttributesSameNameCorrectly(TagHelperAttributeList outputAttributes)
        {
            // Arrange
            var allAttributes = new TagHelperAttributeList(
                outputAttributes.Concat(
                    new TagHelperAttributeList
                    {
                        { "rel", new HtmlString("stylesheet") },
                        { "href", "test.css" },
                        { "asp-fallback-href", "test.css" },
                        { "asp-fallback-test-class", "hidden" },
                        { "asp-fallback-test-property", "visibility" },
                        { "asp-fallback-test-value", "hidden" },
                    }));
            var context = MakeTagHelperContext(allAttributes);
            var combinedOutputAttributes = new TagHelperAttributeList(
                outputAttributes.Concat(
                    new[]
                    {
                        new TagHelperAttribute("rel", new HtmlString("stylesheet"))
                    }));
            var output = MakeTagHelperOutput("link", combinedOutputAttributes);
            var logger = new Mock<ILogger<LinkTagHelper>>();
            var hostingEnvironment = MakeHostingEnvironment();
            var viewContext = MakeViewContext();

            var helper = new LinkTagHelper(
                logger.Object,
                hostingEnvironment,
                MakeCache(),
                new CommonTestEncoder(),
                new CommonTestEncoder(),
                MakeUrlHelper())
            {
                ViewContext = viewContext,
                FallbackHref = "test.css",
                FallbackTestClass = "hidden",
                FallbackTestProperty = "visibility",
                FallbackTestValue = "hidden",
                Href = "test.css",
            };
            var expectedAttributes = new TagHelperAttributeList(output.Attributes);
            expectedAttributes.Add(new TagHelperAttribute("href", "test.css"));

            // Act
            helper.Process(context, output);

            // Assert
            Assert.Equal(expectedAttributes, output.Attributes);
        }
        public void Add_AppendsAttributes(
            IEnumerable<TagHelperAttribute> initialAttributes,
            TagHelperAttribute attributeToAdd,
            IEnumerable<TagHelperAttribute> expectedAttributes)
        {
            // Arrange
            var attributes = new TagHelperAttributeList(initialAttributes);

            // Act
            attributes.Add(attributeToAdd);

            // Assert
            Assert.Equal(expectedAttributes, attributes, CaseSensitiveTagHelperAttributeComparer.Default);
        }
        public void AddMinimizedHtmlAttribute_MaintainsHTMLAttributes_SomeMinimized()
        {
            // Arrange
            var executionContext = new TagHelperExecutionContext("input", tagMode: TagMode.SelfClosing);
            var expectedAttributes = new TagHelperAttributeList
            {
                { "class", "btn" },
                { "foo", "bar" }
            };
            expectedAttributes.Add(new TagHelperAttribute { Name = "checked", Minimized = true });
            expectedAttributes.Add(new TagHelperAttribute { Name = "visible", Minimized = true });

            // Act
            executionContext.AddHtmlAttribute("class", "btn");
            executionContext.AddHtmlAttribute("foo", "bar");
            executionContext.AddMinimizedHtmlAttribute("checked");
            executionContext.AddMinimizedHtmlAttribute("visible");

            // Assert
            Assert.Equal(
                expectedAttributes,
                executionContext.HTMLAttributes,
                CaseSensitiveTagHelperAttributeComparer.Default);
        }
        public void TagHelperExecutionContext_MaintainsAllAttributes()
        {
            // Arrange
            var executionContext = new TagHelperExecutionContext("p", TagMode.StartTagAndEndTag);
            var expectedAttributes = new TagHelperAttributeList
            {
                { "class", "btn" },
            };
            expectedAttributes.Add(new TagHelperAttribute("something", true, HtmlAttributeValueStyle.SingleQuotes));
            expectedAttributes.Add(new TagHelperAttribute("type", "text", HtmlAttributeValueStyle.NoQuotes));

            // Act
            executionContext.AddHtmlAttribute("class", "btn", HtmlAttributeValueStyle.DoubleQuotes);
            executionContext.AddTagHelperAttribute("something", true, HtmlAttributeValueStyle.SingleQuotes);
            executionContext.AddHtmlAttribute("type", "text", HtmlAttributeValueStyle.NoQuotes);
            var context = executionContext.Context;

            // Assert
            Assert.Equal(
                expectedAttributes,
                context.AllAttributes,
                CaseSensitiveTagHelperAttributeComparer.Default);
        }
示例#38
0
        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.AppendHtml(Environment.NewLine)
                       .AppendHtml("<script>(")
                       .AppendHtml(FallbackTestExpression)
                       .AppendHtml("||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.AppendHtml("<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.AppendHtml("><\\/script>");
                }

                builder.AppendHtml("\"));</script>");
            }
        }
        public void AddHtmlAttribute_MaintainsHtmlAttributes_VariousStyles()
        {
            // Arrange
            var executionContext = new TagHelperExecutionContext("input", tagMode: TagMode.SelfClosing);
            var expectedAttributes = new TagHelperAttributeList
            {
                { "class", "btn" },
                { "foo", "bar" }
            };
            expectedAttributes.Add(new TagHelperAttribute("valid", "true", HtmlAttributeValueStyle.NoQuotes));
            expectedAttributes.Add(new TagHelperAttribute("type", "text", HtmlAttributeValueStyle.SingleQuotes));
            expectedAttributes.Add(new TagHelperAttribute(name: "checked"));
            expectedAttributes.Add(new TagHelperAttribute(name: "visible"));

            // Act
            executionContext.AddHtmlAttribute("class", "btn", HtmlAttributeValueStyle.DoubleQuotes);
            executionContext.AddHtmlAttribute("foo", "bar", HtmlAttributeValueStyle.DoubleQuotes);
            executionContext.AddHtmlAttribute("valid", "true", HtmlAttributeValueStyle.NoQuotes);
            executionContext.AddHtmlAttribute("type", "text", HtmlAttributeValueStyle.SingleQuotes);
            executionContext.AddHtmlAttribute(new TagHelperAttribute("checked"));
            executionContext.AddHtmlAttribute(new TagHelperAttribute("visible"));
            var output = executionContext.Output;

            // Assert
            Assert.Equal(
                expectedAttributes,
                output.Attributes,
                CaseSensitiveTagHelperAttributeComparer.Default);
        }