@@ -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" ​" ;
@@ -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