/// <summary> /// Gets the value of a given attribute by its name. /// </summary> /// <param name="chunk">The HTML chunk.</param> /// <param name="attributeName">Name of the attribute.</param> /// <returns></returns> protected virtual string GetAttributeValue(HtmlChunk chunk, string attributeName) { var idx = Array.FindIndex(chunk.Attributes, 0, chunk.ParamsCount, i => i.Equals(attributeName, StringComparison.OrdinalIgnoreCase)); if (idx != -1) return chunk.Values[idx]; else return null; }
private void HandleCloseTag(Stack<Control> container, HtmlChunk chunk, StringBuilder currentLiteralText) { if (chunk.TagName.Equals("title", StringComparison.OrdinalIgnoreCase)) { if (container.Peek() is HtmlTitle) { ((HtmlTitle)container.Pop()).Text = currentLiteralText.ToString(); } else { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Pop()); } currentLiteralText.Clear(); } else if (chunk.TagName.Equals("head", StringComparison.OrdinalIgnoreCase)) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Pop()); currentLiteralText.Clear(); } else if (chunk.TagName.Equals("form", StringComparison.OrdinalIgnoreCase)) { if (container.Peek() is HtmlForm) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Pop()); currentLiteralText.Clear(); } else { currentLiteralText.Append(chunk.Html); } } else if (chunk.TagName.Equals("asp:ContentPlaceHolder", StringComparison.OrdinalIgnoreCase)) { //// Ignore } else if (chunk.TagName.Equals(LayoutsHelpers.SectionTag, StringComparison.OrdinalIgnoreCase)) { //// Ignore } else { currentLiteralText.Append(chunk.Html); } }
/// <inheritdoc /> public string PublicGetAttributeValue(HtmlChunk chunk, string attributeName) { return this.GetAttributeValue(chunk, attributeName); }
/// <summary> /// Gets the value of a given attribute by its name. /// </summary> /// <param name="chunk">The chunk.</param> /// <param name="attributeName">Name of the attribute.</param> /// <returns></returns> public string PublicGetAttributeValue(HtmlChunk chunk, string attributeName) { return(this.GetAttributeValue(chunk, attributeName)); }
/// <summary> /// Asserts that the expected tags exists on the page and that not expected tags do not exists on the page. /// </summary> /// <param name="pageContent">Content of the page.</param> /// <param name="expectedTags">The expected tags.</param> /// <param name="notExpectedTags">The not expected tags.</param> /// <param name="showCount">The show count.</param> private void AssertTagsLinks(string pageContent, List <Tag> expectedTags, List <Tag> notExpectedTags, bool showCount) { pageContent = pageContent.Replace(Environment.NewLine, string.Empty); using (HtmlParser parser = new HtmlParser(pageContent)) { HtmlChunk chunk = null; parser.SetChunkHashMode(false); parser.AutoExtractBetweenTagsOnly = true; parser.CompressWhiteSpaceBeforeTag = true; parser.KeepRawHTML = true; while ((chunk = parser.ParseNext()) != null) { if (chunk.TagName.Equals("a") && !chunk.IsClosure) { var linkHref = chunk.GetParamValue("href"); chunk = parser.ParseNext(); var linkText = chunk.Html; foreach (var tag in notExpectedTags) { if (linkHref != null) { Assert.IsFalse( linkHref.EndsWith(tag.Url, StringComparison.Ordinal), string.Format(CultureInfo.InvariantCulture, "The tag's url {0} is found but is not expected.", linkHref)); Assert.AreNotEqual( tag.Name, linkText, string.Format(CultureInfo.InvariantCulture, "The tag's name {0} is found but is not expected.", linkText)); } } if (expectedTags.Count == 0) { continue; } var currentTag = expectedTags.First(); Assert.IsTrue( linkHref.EndsWith(currentTag.Url, StringComparison.Ordinal), string.Format(CultureInfo.InvariantCulture, "The expected tag url {0} is not found.", currentTag.Url)); Assert.AreEqual( currentTag.Name, linkText, string.Format(CultureInfo.InvariantCulture, "The tag's name {0} is not correct.", linkText)); if (showCount) { parser.ParseNext(); // gets the closing tag </a> var countChunk = parser.ParseNext(); // gets the chunk that contains the tag's count var count = countChunk.Html.Trim(); Assert.AreEqual( "(" + currentTag.Count + ")", count, string.Format(CultureInfo.InstalledUICulture, "The tag's count {0} is not correct.", count)); } else { parser.ParseNext(); // gets the closing tag </a> parser.ParseNext(); // gets an empty line var listChunk = parser.ParseNext(); // gets the closing </li> // Verifies there is no count before the closing li tag Assert.IsTrue(listChunk.TagName.Equals("li")); Assert.IsTrue(listChunk.IsClosure); } expectedTags.RemoveAt(0); } } } }
private void HandleOpenTag(Stack <Control> container, HtmlChunk chunk, StringBuilder currentLiteralText) { if (chunk.TagName.Equals("title", StringComparison.OrdinalIgnoreCase) && isCurrentlyInHeadTag) { // if we are not currently parsing the <head> tag, then this title must be in the body and we should skip it this.AddIfNotEmpty(currentLiteralText.ToString(), container.Peek()); var title = new HtmlTitle(); container.Peek().Controls.Add(title); container.Push(title); } else if (chunk.TagName.Equals("head", StringComparison.OrdinalIgnoreCase)) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Peek()); currentLiteralText.Clear(); var head = new HtmlHead(); container.Peek().Controls.Add(head); container.Push(head); isCurrentlyInHeadTag = true; } else if (chunk.TagName.Equals("asp:ContentPlaceHolder", StringComparison.OrdinalIgnoreCase)) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Peek()); currentLiteralText.Clear(); if (chunk.HasAttribute("ID")) { var id = chunk.AttributesMap["ID"] as string; var placeHolder = new ContentPlaceHolder() { ID = id }; container.Peek().Controls.Add(placeHolder); this.AddContentPlaceHolder(id); this.InstantiateControls(placeHolder); } } else if (chunk.TagName.Equals("form", StringComparison.OrdinalIgnoreCase) && chunk.HasAttribute("runat")) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Peek()); currentLiteralText.Clear(); var form = new HtmlForm(); if (chunk.HasAttribute("id")) { form.ID = chunk.AttributesMap["id"] as string; } else { form.ID = "aspnetForm"; } container.Peek().Controls.Add(form); container.Push(form); } else if (chunk.TagName.Equals(LayoutsHelpers.SectionTag, StringComparison.OrdinalIgnoreCase)) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Peek()); currentLiteralText.Clear(); var sectionRenderer = new SectionRenderer(); if (chunk.HasAttribute("name")) { sectionRenderer.Name = chunk.AttributesMap["name"].ToString(); } container.Peek().Controls.Add(sectionRenderer); } else if (chunk.TagName.Equals("meta", StringComparison.OrdinalIgnoreCase)) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Peek()); currentLiteralText.Clear(); this.AddIfNotEmpty(chunk.Html, container.Peek()); } else if (chunk.TagName == "%@") { //// Ignore } else { currentLiteralText.Append(chunk.Html); } }
/// <summary> /// Processes the layout string adding the required attributes to the head tag /// and also adding the required form tag. /// </summary> /// <param name="targetTemplate">The template.</param> /// <returns></returns> public virtual string ProcessLayoutString(string targetTemplate) { var includeFormTag = MasterPageBuilder.IsFormTagRequired(); StringBuilder outPut = new StringBuilder(); HtmlChunk chunk = null; using (HtmlParser parser = new HtmlParser(targetTemplate)) { parser.SetChunkHashMode(false); parser.AutoExtractBetweenTagsOnly = false; parser.CompressWhiteSpaceBeforeTag = false; parser.KeepRawHTML = true; bool setTitle = true; bool modified; bool isOpenBodyTag; bool isCloseBodyTag; bool isClosedHeadTag; while ((chunk = parser.ParseNext()) != null) { modified = false; isOpenBodyTag = false; isCloseBodyTag = false; isClosedHeadTag = false; if (chunk.Type == HtmlChunkType.OpenTag) { if (chunk.TagName.Equals("head", StringComparison.OrdinalIgnoreCase)) { if (!chunk.HasAttribute("runat")) { chunk.SetAttribute("runat", "server"); modified = true; } } else if (chunk.TagName.Equals("body", StringComparison.OrdinalIgnoreCase)) { isOpenBodyTag = true; } else if (chunk.TagName.Equals("title", StringComparison.OrdinalIgnoreCase)) { setTitle = false; } } else if (chunk.Type == HtmlChunkType.CloseTag) { if (chunk.TagName.Equals("body", StringComparison.OrdinalIgnoreCase)) { isCloseBodyTag = true; } if (chunk.TagName.Equals("head", StringComparison.OrdinalIgnoreCase)) { isClosedHeadTag = true; } } if (includeFormTag && isCloseBodyTag) { outPut.Append("</form>"); } else if (!includeFormTag && isClosedHeadTag) { this.AppendRequiredHeaderContent(outPut, setTitle); } if (modified) { outPut.Append(chunk.GenerateHtml()); } else { outPut.Append(chunk.Html); } if (includeFormTag && isOpenBodyTag) { outPut.Append("<form runat='server'>"); } } } return(outPut.ToString()); }
/// <summary> /// Extracts the components. /// </summary> /// <param name="fileStream">The file stream.</param> /// <returns></returns> public static IList <string> ExtractComponents(Stream fileStream) { var candidateComponents = new HashSet <string>(); using (var reader = new StreamReader(fileStream)) { var readerString = reader.ReadToEnd(); // Removing the @* Comments *@ readerString = Regex.Replace(readerString, @"@\*([^\*@]*)\*@", string.Empty); using (HtmlParser parser = new HtmlParser(readerString)) { HtmlChunk chunk = null; parser.SetChunkHashMode(false); parser.AutoExtractBetweenTagsOnly = false; parser.CompressWhiteSpaceBeforeTag = false; parser.KeepRawHTML = true; parser.AutoKeepComments = false; while ((chunk = parser.ParseNext()) != null) { if (chunk.Type == HtmlChunkType.OpenTag) { //// Angular directives can be tag name (E) var tagName = chunk.TagName.ToLower(); //// The parser can't handle tag names containing '-' if (string.IsNullOrEmpty(tagName)) { var match = Regex.Match(chunk.Html, @"<\W*([a-zA-Z_-]+)").Groups[1]; if (match.Success) { tagName = match.Value.ToLower(); } } candidateComponents.Add(tagName); for (int i = 0; i < chunk.Attributes.Length; i++) { //// The html parser has no more attributes if (chunk.Values[i] == null) { break; } //// Angular directives can be class attribute value (C) if (chunk.Attributes[i].ToLower() == "class") { candidateComponents.Add(chunk.Values[i].ToLower()); } else { //// Angular directives can be attribute name (A) candidateComponents.Add(chunk.Attributes[i].ToLower()); } } } } } } candidateComponents.IntersectWith(ComponentsDependencyResolver.AvailableComponents.Value.Keys); return(candidateComponents.Select(key => ComponentsDependencyResolver.AvailableComponents.Value[key]).ToList()); }
private void HandleOpenTag(Stack<Control> container, HtmlChunk chunk, StringBuilder currentLiteralText) { if (chunk.TagName.Equals("title", StringComparison.OrdinalIgnoreCase)) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Peek()); var title = new HtmlTitle(); container.Peek().Controls.Add(title); container.Push(title); } else if (chunk.TagName.Equals("head", StringComparison.OrdinalIgnoreCase)) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Peek()); currentLiteralText.Clear(); var head = new HtmlHead(); container.Peek().Controls.Add(head); container.Push(head); } else if (chunk.TagName.Equals("asp:ContentPlaceHolder", StringComparison.OrdinalIgnoreCase)) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Peek()); currentLiteralText.Clear(); if (chunk.HasAttribute("ID")) { var id = chunk.AttributesMap["ID"] as string; var placeHolder = new ContentPlaceHolder() { ID = id }; container.Peek().Controls.Add(placeHolder); this.AddContentPlaceHolder(id); this.InstantiateControls(placeHolder); } } else if (chunk.TagName.Equals("form", StringComparison.OrdinalIgnoreCase) && chunk.HasAttribute("runat")) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Peek()); currentLiteralText.Clear(); var form = new HtmlForm(); if (chunk.HasAttribute("id")) form.ID = chunk.AttributesMap["id"] as string; else form.ID = "aspnetForm"; container.Peek().Controls.Add(form); container.Push(form); } else if (chunk.TagName.Equals(LayoutsHelpers.SectionTag, StringComparison.OrdinalIgnoreCase)) { this.AddIfNotEmpty(currentLiteralText.ToString(), container.Peek()); currentLiteralText.Clear(); var sectionRenderer = new SectionRenderer(); if (chunk.HasAttribute("name")) { sectionRenderer.Name = chunk.AttributesMap["name"].ToString(); } container.Peek().Controls.Add(sectionRenderer); } else if (chunk.TagName == "%@") { //// Ignore } else { currentLiteralText.Append(chunk.Html); } }
private void AssertLanguageLinks(string pageContent, Dictionary <CultureInfo, string> links, Dictionary <CultureInfo, string> notVisiblelinks) { using (HtmlParser parser = new HtmlParser(pageContent)) { HtmlChunk chunk = null; parser.SetChunkHashMode(false); parser.AutoExtractBetweenTagsOnly = true; parser.CompressWhiteSpaceBeforeTag = true; parser.KeepRawHTML = true; var initialLinks = new Dictionary <CultureInfo, string>(links); while ((chunk = parser.ParseNext()) != null) { if (chunk.TagName.Equals("a") && !chunk.IsClosure && chunk.GetParamValue("onclick") != null) { var linkOnClickAttribute = chunk.GetParamValue("onclick"); chunk = parser.ParseNext(); var linkText = chunk.Html; foreach (var link in notVisiblelinks) { Assert.IsFalse( linkOnClickAttribute.Contains(link.Key.Name), string.Format(CultureInfo.InvariantCulture, "The anchor tag for culture {0} is found, but is not expected.", linkOnClickAttribute)); Assert.AreNotEqual( link.Key.NativeName, linkText, string.Format(CultureInfo.InvariantCulture, "The link display name {0} is found, but is not expected.", linkText)); } var foundlanguageCulture = new CultureInfo(string.Empty); foreach (var link in links) { Assert.IsTrue( linkOnClickAttribute.Contains(link.Key.Name), string.Format(CultureInfo.InvariantCulture, "The expected link's culture {0} is not found.", link.Value)); Assert.AreEqual( HttpUtility.HtmlEncode(link.Key.NativeName), linkText, string.Format(CultureInfo.InvariantCulture, "The link display name {0} is not correct.", linkText)); foundlanguageCulture = link.Key; break; } Assert.IsFalse( string.IsNullOrEmpty(foundlanguageCulture.Name), string.Format(CultureInfo.InvariantCulture, "The anchor tag for culture {0} is not expected.", linkOnClickAttribute)); links.Remove(foundlanguageCulture); } else if (chunk.TagName.Equals("input") && chunk.GetParamValue("type") == "hidden" && chunk.GetParamValue("value") != null && chunk.GetParamValue("value").StartsWith("http://", StringComparison.Ordinal)) { var dataSfRole = chunk.GetParamValue("data-sf-role"); if (dataSfRole != null) { var currentCulture = new CultureInfo(dataSfRole); Assert.IsTrue(initialLinks.ContainsKey(currentCulture), string.Format(CultureInfo.InvariantCulture, "The found hidden input field {0} is not expected", currentCulture)); var expectedLink = initialLinks[currentCulture]; var hiddenInputValue = chunk.GetParamValue("value"); Assert.IsTrue(hiddenInputValue.EndsWith(expectedLink, StringComparison.Ordinal)); initialLinks.Remove(currentCulture); } } } Assert.AreEqual(0, links.Count(), "Not all expected languages are found."); Assert.AreEqual(0, initialLinks.Count(), "Not all expected hidden fields of languages are found."); } }