Skip to content

Commit

Permalink
Merge pull request #554 from POFerro/quote_type
Browse files Browse the repository at this point in the history
Review Attribute QuoteType Behavior vs InternalQuoteType fixes #552, #516
  • Loading branch information
JonathanMagnan authored Jul 31, 2024
2 parents 8efd5da + 045421a commit 814af63
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 25 deletions.
22 changes: 13 additions & 9 deletions src/HtmlAgilityPack.Shared/HtmlAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ public class HtmlAttribute : IComparable
internal int _namestartindex;
internal HtmlDocument _ownerdocument; // attribute can exists without a node
internal HtmlNode _ownernode;
private AttributeValueQuote _quoteType = AttributeValueQuote.DoubleQuote;
private AttributeValueQuote? _quoteType;
internal int _streamposition;
internal string _value;
internal int _valuelength;
internal int _valuestartindex;
internal bool _isFromParse;
internal bool _hasEqual;
//internal bool _isFromParse;
//internal bool _hasEqual;
private bool? _localUseOriginalName;

#endregion
Expand Down Expand Up @@ -168,14 +168,14 @@ public HtmlNode OwnerNode
/// </summary>
public AttributeValueQuote QuoteType
{
get { return _quoteType; }
set { _quoteType = value; }
get { return _quoteType ?? this.InternalQuoteType ?? this.OwnerDocument.GlobalAttributeValueQuote ?? AttributeValueQuote.DoubleQuote; }
set { _quoteType = value != AttributeValueQuote.Initial ? (AttributeValueQuote?)value : null; }
}

/// <summary>
/// Specifies what type of quote the data should be wrapped in (internal to keep backward compatibility)
/// </summary>
internal AttributeValueQuote InternalQuoteType { get; set; }
internal AttributeValueQuote? InternalQuoteType { get; set; }

/// <summary>
/// Gets the stream position of this attribute in the document, relative to the start of the document.
Expand Down Expand Up @@ -213,6 +213,10 @@ public string Value
set
{
_value = value;
if (!string.IsNullOrEmpty(_value) && this.QuoteType == AttributeValueQuote.WithoutValue)
{
this.InternalQuoteType = this.OwnerDocument.GlobalAttributeValueQuote ?? AttributeValueQuote.DoubleQuote;
}

if (_ownernode != null)
{
Expand Down Expand Up @@ -284,11 +288,11 @@ public HtmlAttribute Clone()
HtmlAttribute att = new HtmlAttribute(_ownerdocument);
att.Name = OriginalName;
att.Value = Value;
att.QuoteType = QuoteType;
att._quoteType = _quoteType;
att.InternalQuoteType = InternalQuoteType;

att._isFromParse = _isFromParse;
att._hasEqual = _hasEqual;
//att._isFromParse = _isFromParse;
//att._hasEqual = _hasEqual;
return att;
}

Expand Down
15 changes: 9 additions & 6 deletions src/HtmlAgilityPack.Shared/HtmlDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1503,7 +1503,7 @@ private void Parse()
if (NewCheck())
continue;

_currentattribute._isFromParse = true;
//_currentattribute._isFromParse = true;


// Add !,?,% and other special?
Expand All @@ -1525,7 +1525,7 @@ private void Parse()
if (_c == '=')
{
PushAttributeNameEnd(_index - 1);
_currentattribute._hasEqual = true;
//_currentattribute._hasEqual = true;
_state = ParseState.AttributeAfterEquals;
continue;
}
Expand Down Expand Up @@ -1573,7 +1573,7 @@ private void Parse()

if (_c == '=')
{
_currentattribute._hasEqual = true;
//_currentattribute._hasEqual = true;
_state = ParseState.AttributeAfterEquals;
continue;
}
Expand Down Expand Up @@ -1822,6 +1822,7 @@ private void PushAttributeNameStart(int index, int lineposition)
_currentattribute.Line = _line;
_currentattribute._lineposition = lineposition;
_currentattribute._streamposition = index;
_currentattribute.InternalQuoteType = AttributeValueQuote.WithoutValue;
}

private void PushAttributeValueEnd(int index)
Expand Down Expand Up @@ -2044,11 +2045,13 @@ private void PushAttributeValueStart(int index, int quote)
_currentattribute._valuestartindex = index;
if (quote == '\'')
{
_currentattribute.QuoteType = AttributeValueQuote.SingleQuote;
_currentattribute.InternalQuoteType = AttributeValueQuote.SingleQuote;
}
if (quote == '"')
{
_currentattribute.InternalQuoteType = AttributeValueQuote.DoubleQuote;
}

_currentattribute.InternalQuoteType = _currentattribute.QuoteType;

if (quote == 0)
{
_currentattribute.InternalQuoteType = AttributeValueQuote.None;
Expand Down
11 changes: 6 additions & 5 deletions src/HtmlAgilityPack.Shared/HtmlNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2346,15 +2346,16 @@ internal void WriteAttribute(TextWriter outText, HtmlAttribute att)
}

var quoteType = OwnerDocument.GlobalAttributeValueQuote ?? att.QuoteType;
var isWithoutValue = quoteType == AttributeValueQuote.WithoutValue
|| (quoteType == AttributeValueQuote.Initial && att._isFromParse && !att._hasEqual && string.IsNullOrEmpty(att.XmlValue));
//var isWithoutValue = quoteType == AttributeValueQuote.WithoutValue
// || (quoteType == AttributeValueQuote.Initial && att._isFromParse && !att._hasEqual && string.IsNullOrEmpty(att.XmlValue));

if (quoteType == AttributeValueQuote.Initial && !(att._isFromParse && !att._hasEqual && string.IsNullOrEmpty(att.XmlValue)))
if (quoteType == AttributeValueQuote.Initial/* && !(att._isFromParse && !att._hasEqual && string.IsNullOrEmpty(att.XmlValue))*/)
{
quoteType = att.InternalQuoteType;
quoteType = att.QuoteType;
}
var isWithoutValue = quoteType == AttributeValueQuote.WithoutValue;

string name;
string name;
string quote = quoteType == AttributeValueQuote.DoubleQuote ? "\"" : quoteType == AttributeValueQuote.SingleQuote ? "'" : "";
if (_ownerdocument.OptionOutputAsXml)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using NUnit.Framework;
using System;
using System.IO;
using System.Linq;
using System.Xml.XPath;

namespace HtmlAgilityPack.Tests.fx._4._5
namespace HtmlAgilityPack.Tests
{
[TestFixture]
public class HtmlDocumentPreserveOriginalTest
Expand Down Expand Up @@ -168,5 +169,18 @@ public void PreserveClonedEmptyAttributesTest()

Assert.AreEqual(@"<list-counter formErrorsCounter></list-counter>", cloned.OuterHtml);
}

[Test]
public void PreserveQuoteTypeForLoadedAttributes()
{
var input = HtmlNode.CreateNode("<input checked></input>");
var checkedAttribute = input.Attributes.First();

// Result is: Value: '' (empty string)
Assert.AreEqual("", checkedAttribute.Value);

// Result is: QuoteType: WithoutValue
Assert.AreEqual(AttributeValueQuote.WithoutValue, checkedAttribute.QuoteType);
}
}
}
2 changes: 1 addition & 1 deletion src/Tests/HtmlAgilityPack.Tests.Net45/UnitTest1.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace HtmlAgilityPack.Tests.fx._4._5
namespace HtmlAgilityPack.Tests
{
[TestClass]
public class UnitTest1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
 <form xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<form xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<page>

<page-body>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<form xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<form xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<page>

<page-body>
Expand All @@ -22,7 +22,7 @@
{{ dimension.code }} - {{ dimension.description }}
</mat-option>
</mat-select>
<span readOnlyValue> {{ simulationRequest.categoriaBemId | commonData:lea546CATBEM$:'id':'code-desc' }} </span>
<span readOnlyValue>{{ simulationRequest.categoriaBemId | commonData:lea546CATBEM$:'id':'code-desc' }}</span>
<field-error-alert matSuffix></field-error-alert>
<mat-error></mat-error>
</mat-form-field>
Expand Down

0 comments on commit 814af63

Please sign in to comment.