Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize HtmlNode.WriteAttribute #556

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
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
60 changes: 48 additions & 12 deletions src/HtmlAgilityPack.Shared/HtmlNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2032,7 +2032,9 @@ public virtual void WriteTo(TextWriter outText, int level = 0)
break;
}

outText.Write("<" + name);
outText.Write("<");
outText.Write(name);

WriteAttributes(outText, false);

if (HasChildNodes)
Expand Down Expand Up @@ -2060,7 +2062,9 @@ public virtual void WriteTo(TextWriter outText, int level = 0)

if (_ownerdocument.OptionOutputAsXml || !_isImplicitEnd)
{
outText.Write("</" + name);
outText.Write("</");
outText.Write(name);

if (!_ownerdocument.OptionOutputAsXml)
WriteAttributes(outText, true);

Expand Down Expand Up @@ -2095,7 +2099,9 @@ public virtual void WriteTo(TextWriter outText, int level = 0)
{
if (!_isImplicitEnd)
{
outText.Write("></" + name + ">");
outText.Write("></");
outText.Write(name);
outText.Write(">");
}
else
{
Expand Down Expand Up @@ -2346,6 +2352,8 @@ internal void SetId(string id)
SetChanged();
}

private static readonly char[] optimizeAttributesCheckedChars = {(char) 10, (char) 13, (char) 9, ' '};

internal void WriteAttribute(TextWriter outText, HtmlAttribute att)
{
if (att.Value == null)
Expand Down Expand Up @@ -2377,8 +2385,14 @@ internal void WriteAttribute(TextWriter outText, HtmlAttribute att)
if (_ownerdocument.OptionOutputOriginalCase)
name = att.OriginalName;

outText.Write(" " + name + "=" + quote + HtmlDocument.HtmlEncodeWithCompatibility(att.XmlValue, _ownerdocument.BackwardCompatibility) + quote);
// There is a major breaking change started with changes in https://github.com/zzzprojects/html-agility-pack/releases/tag/v1.11.62
outText.Write(" ");
outText.Write(name);
outText.Write("=");
outText.Write(quote);
outText.Write(HtmlDocument.HtmlEncodeWithCompatibility(att.XmlValue, _ownerdocument.BackwardCompatibility));
outText.Write(quote);

// There is a major breaking change started with changes in https://github.com/zzzprojects/html-agility-pack/releases/tag/v1.11.62
// Before, the attribute had a default "DoubleQuote" but that's no longer the case
// At this moment, the easiest way to fix it is assuming we always need to close an attribute in xml
// However, even this fix cause a breaking change as we cannot longer output without a quote
Expand All @@ -2401,7 +2415,8 @@ internal void WriteAttribute(TextWriter outText, HtmlAttribute att)
if ((att.Name[0] == '<') && (att.Name[1] == '%') &&
(att.Name[att.Name.Length - 1] == '>') && (att.Name[att.Name.Length - 2] == '%'))
{
outText.Write(" " + name);
outText.Write(" ");
outText.Write(name);
return;
}
}
Expand All @@ -2411,18 +2426,39 @@ internal void WriteAttribute(TextWriter outText, HtmlAttribute att)
var value = quoteType == AttributeValueQuote.DoubleQuote ? !att.Value.StartsWith("@") ? att.Value.Replace("\"", "&quot;") :
att.Value : quoteType == AttributeValueQuote.SingleQuote ? att.Value.Replace("'", "&#39;") : att.Value;
if (_ownerdocument.OptionOutputOptimizeAttributeValues)
if (att.Value.IndexOfAny(new char[] {(char) 10, (char) 13, (char) 9, ' '}) < 0)
outText.Write(" " + name + "=" + att.Value);
{
if (att.Value.IndexOfAny(optimizeAttributesCheckedChars) < 0)
{
outText.Write(" ");
outText.Write(name);
outText.Write("=");
outText.Write(att.Value);
}
else
outText.Write(" " + name + "=" + quote + value + quote);
{
outText.Write(" ");
outText.Write(name);
outText.Write("=");
outText.Write(quote);
outText.Write(value);
outText.Write(quote);
}
}
else
outText.Write(" " + name + "=" + quote + value + quote);
{
outText.Write(" ");
outText.Write(name);
outText.Write("=");
outText.Write(quote);
outText.Write(value);
outText.Write(quote);;
}
}
else
{
outText.Write(" " + name);
outText.Write(" ");
outText.Write(name);
}

}
}

Expand Down