Skip to content

Commit 0a7baad

Browse files
committed
DiffHighlighter.hpp: Fix an issue where differences on separate lines within a PRE element could be displayed concatenated
1 parent c09f2d5 commit 0a7baad

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

src/WinWebDiffLib/DiffHighlighter.hpp

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,15 @@ class Highlighter
878878
}
879879
}
880880

881-
static std::wstring modifiedNodesToHTMLs(const WValue& tree, std::list<ModifiedNode>& nodes)
881+
struct Context
882+
{
883+
explicit struct Context(bool inPreElement, std::list<ModifiedNode>& nodes)
884+
: inPreElement(inPreElement), nodes(nodes) { }
885+
bool inPreElement;
886+
std::list<ModifiedNode>& nodes;
887+
};
888+
889+
static std::wstring modifiedNodesToHTMLsInternal(Context& ctxt, const WValue& tree)
882890
{
883891
std::wstring html;
884892
NodeType nodeType = static_cast<NodeType>(tree[L"nodeType"].GetInt());
@@ -896,7 +904,7 @@ class Highlighter
896904
if (tree.HasMember(L"children"))
897905
{
898906
for (const auto& child : tree[L"children"].GetArray())
899-
html += modifiedNodesToHTMLs(child, nodes);
907+
html += modifiedNodesToHTMLsInternal(ctxt, child);
900908
}
901909
break;
902910
}
@@ -912,10 +920,10 @@ class Highlighter
912920
if (tree.HasMember(L"insertedNodes"))
913921
{
914922
for (const auto& child : tree[L"insertedNodes"].GetArray())
915-
html += modifiedNodesToHTMLs(child, nodes);
923+
html += modifiedNodesToHTMLsInternal(ctxt, child);
916924
}
917925
std::wstring h = utils::EncodeHTMLEntities(tree[L"nodeValue"].GetString());
918-
if (!h.empty() && std::all_of(h.begin(), h.end(), [](wchar_t ch) { return iswspace(ch); }))
926+
if (!ctxt.inPreElement && !h.empty() && std::all_of(h.begin(), h.end(), [](wchar_t ch) { return iswspace(ch); }))
919927
{
920928
h.pop_back();
921929
h += L"&nbsp;&#8203;";
@@ -924,14 +932,14 @@ class Highlighter
924932
if (tree.HasMember(L"appendedNodes"))
925933
{
926934
for (const auto& child : tree[L"appendedNodes"].GetArray())
927-
html += modifiedNodesToHTMLs(child, nodes);
935+
html += modifiedNodesToHTMLsInternal(ctxt, child);
928936
}
929937
if (tree.HasMember(L"modified"))
930938
{
931939
ModifiedNode node;
932940
node.nodeId = tree[L"nodeId"].GetInt();
933941
node.outerHTML = html;
934-
nodes.emplace_back(std::move(node));
942+
ctxt.nodes.emplace_back(std::move(node));
935943
}
936944
break;
937945
}
@@ -940,10 +948,11 @@ class Highlighter
940948
if (tree.HasMember(L"insertedNodes"))
941949
{
942950
for (const auto& child : tree[L"insertedNodes"].GetArray())
943-
html += modifiedNodesToHTMLs(child, nodes);
951+
html += modifiedNodesToHTMLsInternal(ctxt, child);
944952
}
953+
const std::wstring nodeName = tree[L"nodeName"].GetString();
945954
html += L'<';
946-
html += tree[L"nodeName"].GetString();
955+
html += nodeName;
947956
if (tree.HasMember(L"attributes"))
948957
{
949958
const auto& attributes = tree[L"attributes"].GetArray();
@@ -960,18 +969,21 @@ class Highlighter
960969
html += L'>';
961970
if (tree.HasMember(L"children"))
962971
{
972+
const bool oldInPreElement = ctxt.inPreElement;
973+
ctxt.inPreElement = ctxt.inPreElement || (nodeName == L"PRE");
963974
for (const auto& child : tree[L"children"].GetArray())
964-
html += modifiedNodesToHTMLs(child, nodes);
975+
html += modifiedNodesToHTMLsInternal(ctxt, child);
976+
ctxt.inPreElement = oldInPreElement;
965977
}
966978
if (tree.HasMember(L"appendedNodes"))
967979
{
968980
for (const auto& child : tree[L"appendedNodes"].GetArray())
969-
html += modifiedNodesToHTMLs(child, nodes);
981+
html += modifiedNodesToHTMLsInternal(ctxt, child);
970982
}
971983
if (tree.HasMember(L"contentDocument"))
972984
{
973985
for (const auto& child : tree[L"contentDocument"][L"children"].GetArray())
974-
modifiedNodesToHTMLs(child, nodes);
986+
modifiedNodesToHTMLsInternal(ctxt, child);
975987
}
976988
if (!utils::IsVoidElement(tree[L"nodeName"].GetString()))
977989
{
@@ -984,14 +996,20 @@ class Highlighter
984996
ModifiedNode node;
985997
node.nodeId = tree[L"nodeId"].GetInt();
986998
node.outerHTML = html;
987-
nodes.emplace_back(std::move(node));
999+
ctxt.nodes.emplace_back(std::move(node));
9881000
}
9891001
break;
9901002
}
9911003
}
9921004
return html;
9931005
}
9941006

1007+
static std::wstring modifiedNodesToHTMLs(const WValue& tree, std::list<ModifiedNode>& nodes)
1008+
{
1009+
Context ctxt(false, nodes);
1010+
return modifiedNodesToHTMLsInternal(ctxt, tree);
1011+
}
1012+
9951013
static void getDiffNodes(WValue& tree, std::map<int, int>& nodes)
9961014
{
9971015
NodeType nodeType = static_cast<NodeType>(tree[L"nodeType"].GetInt());

0 commit comments

Comments
 (0)