Move CFX_XMLNode::EncodeEntities() to WideString.

This doesn't require any node-specific fields. Down the road,
the CFX_XMLNode may become a template itself, and this avoids
more code in the header.

-- forward declare CFX_XMLElement and fix IWYU cascade.

Change-Id: I45aace05607c27a46bc32e21f076d98b9383d4d0
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/71752
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcrt/widestring.cpp b/core/fxcrt/widestring.cpp
index 2855cc9..b51ed68 100644
--- a/core/fxcrt/widestring.cpp
+++ b/core/fxcrt/widestring.cpp
@@ -694,6 +694,16 @@
   return result;
 }
 
+WideString WideString::EncodeEntities() const {
+  WideString ret = *this;
+  ret.Replace(L"&", L"&amp;");
+  ret.Replace(L"<", L"&lt;");
+  ret.Replace(L">", L"&gt;");
+  ret.Replace(L"\'", L"&apos;");
+  ret.Replace(L"\"", L"&quot;");
+  return ret;
+}
+
 WideString WideString::Substr(size_t first, size_t count) const {
   if (!m_pData)
     return WideString();
diff --git a/core/fxcrt/widestring.h b/core/fxcrt/widestring.h
index 58e7544..ff53684 100644
--- a/core/fxcrt/widestring.h
+++ b/core/fxcrt/widestring.h
@@ -216,6 +216,9 @@
   // so GetLength() will include them.
   ByteString ToUTF16LE() const;
 
+  // Replace the characters &<>'" with HTML entities.
+  WideString EncodeEntities() const;
+
  protected:
   using StringData = StringDataTemplate<wchar_t>;
 
diff --git a/core/fxcrt/widestring_unittest.cpp b/core/fxcrt/widestring_unittest.cpp
index 02c25c1..419328a 100644
--- a/core/fxcrt/widestring_unittest.cpp
+++ b/core/fxcrt/widestring_unittest.cpp
@@ -1132,6 +1132,11 @@
   }
 }
 
+TEST(WideString, EncodeEntities) {
+  EXPECT_EQ(WideString(L"Symbols &<>'\".").EncodeEntities(),
+            L"Symbols &amp;&lt;&gt;&apos;&quot;.");
+}
+
 TEST(WideString, IsASCII) {
   EXPECT_TRUE(WideString(L"xy\u007fz").IsASCII());
   EXPECT_FALSE(WideString(L"xy\u0080z").IsASCII());
diff --git a/core/fxcrt/xml/cfx_xmldocument.cpp b/core/fxcrt/xml/cfx_xmldocument.cpp
index 1c6656d..d8fae38 100644
--- a/core/fxcrt/xml/cfx_xmldocument.cpp
+++ b/core/fxcrt/xml/cfx_xmldocument.cpp
@@ -5,6 +5,7 @@
 #include "core/fxcrt/xml/cfx_xmldocument.h"
 
 #include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/xml/cfx_xmlelement.h"
 #include "core/fxcrt/xml/cfx_xmlinstruction.h"
 
 CFX_XMLDocument::CFX_XMLDocument() {
diff --git a/core/fxcrt/xml/cfx_xmldocument.h b/core/fxcrt/xml/cfx_xmldocument.h
index 51634db..8eafcca 100644
--- a/core/fxcrt/xml/cfx_xmldocument.h
+++ b/core/fxcrt/xml/cfx_xmldocument.h
@@ -10,8 +10,8 @@
 #include <vector>
 
 #include "core/fxcrt/unowned_ptr.h"
-#include "core/fxcrt/xml/cfx_xmlelement.h"
 
+class CFX_XMLElement;
 class CFX_XMLNode;
 
 class CFX_XMLDocument {
diff --git a/core/fxcrt/xml/cfx_xmlelement.cpp b/core/fxcrt/xml/cfx_xmlelement.cpp
index 4745507..eb54dd2 100644
--- a/core/fxcrt/xml/cfx_xmlelement.cpp
+++ b/core/fxcrt/xml/cfx_xmlelement.cpp
@@ -150,7 +150,7 @@
   WideString ret = L" ";
   ret += name;
   ret += L"=\"";
-  ret += EncodeEntities(value);
+  ret += value.EncodeEntities();
   ret += L"\"";
   return ret;
 }
diff --git a/core/fxcrt/xml/cfx_xmlnode.cpp b/core/fxcrt/xml/cfx_xmlnode.cpp
index 94b035b..27c1ed8 100644
--- a/core/fxcrt/xml/cfx_xmlnode.cpp
+++ b/core/fxcrt/xml/cfx_xmlnode.cpp
@@ -21,13 +21,3 @@
 
   return pParent;
 }
-
-WideString CFX_XMLNode::EncodeEntities(const WideString& value) {
-  WideString ret = value;
-  ret.Replace(L"&", L"&amp;");
-  ret.Replace(L"<", L"&lt;");
-  ret.Replace(L">", L"&gt;");
-  ret.Replace(L"\'", L"&apos;");
-  ret.Replace(L"\"", L"&quot;");
-  return ret;
-}
diff --git a/core/fxcrt/xml/cfx_xmlnode.h b/core/fxcrt/xml/cfx_xmlnode.h
index d4d48b1..283fa71 100644
--- a/core/fxcrt/xml/cfx_xmlnode.h
+++ b/core/fxcrt/xml/cfx_xmlnode.h
@@ -32,9 +32,6 @@
 
   CFX_XMLNode* GetRoot();
   void InsertChildNode(CFX_XMLNode* pNode, int32_t index);
-
- protected:
-  WideString EncodeEntities(const WideString& value);
 };
 
 #endif  // CORE_FXCRT_XML_CFX_XMLNODE_H_
diff --git a/core/fxcrt/xml/cfx_xmltext.cpp b/core/fxcrt/xml/cfx_xmltext.cpp
index 67c35a5..0790b15 100644
--- a/core/fxcrt/xml/cfx_xmltext.cpp
+++ b/core/fxcrt/xml/cfx_xmltext.cpp
@@ -21,5 +21,5 @@
 }
 
 void CFX_XMLText::Save(const RetainPtr<IFX_SeekableWriteStream>& pXMLStream) {
-  pXMLStream->WriteString(EncodeEntities(GetText()).ToUTF8().AsStringView());
+  pXMLStream->WriteString(GetText().EncodeEntities().ToUTF8().AsStringView());
 }
diff --git a/fxjs/xfa/cjx_node.cpp b/fxjs/xfa/cjx_node.cpp
index 8e0927f..1c2b772 100644
--- a/fxjs/xfa/cjx_node.cpp
+++ b/fxjs/xfa/cjx_node.cpp
@@ -13,7 +13,7 @@
 #include "core/fxcrt/cfx_memorystream.h"
 #include "core/fxcrt/fx_codepage.h"
 #include "core/fxcrt/xml/cfx_xmldocument.h"
-#include "core/fxcrt/xml/cfx_xmlnode.h"
+#include "core/fxcrt/xml/cfx_xmlelement.h"
 #include "fxjs/js_resources.h"
 #include "fxjs/xfa/cfxjse_engine.h"
 #include "fxjs/xfa/cfxjse_value.h"
diff --git a/fxjs/xfa/cjx_packet.cpp b/fxjs/xfa/cjx_packet.cpp
index f7bb538..ab1b478 100644
--- a/fxjs/xfa/cjx_packet.cpp
+++ b/fxjs/xfa/cjx_packet.cpp
@@ -10,6 +10,7 @@
 #include <vector>
 
 #include "core/fxcrt/xml/cfx_xmldocument.h"
+#include "core/fxcrt/xml/cfx_xmlelement.h"
 #include "core/fxcrt/xml/cfx_xmltext.h"
 #include "fxjs/cfx_v8.h"
 #include "fxjs/js_resources.h"
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp
index 98d65c0..4a6a51d 100644
--- a/xfa/fxfa/parser/cxfa_document.cpp
+++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -11,6 +11,7 @@
 
 #include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/xml/cfx_xmldocument.h"
+#include "core/fxcrt/xml/cfx_xmlelement.h"
 #include "fxjs/xfa/cfxjse_engine.h"
 #include "fxjs/xfa/cjx_object.h"
 #include "third_party/base/compiler_specific.h"