Move Script_Som_Border{Width|Color} to CJX_Object

The CJX_Node isn't the root of the CJX hierarchy. This causes issues
now that CJX_Object has child objects which don't inherit from CJX_Node.
This CL moves Script_Som_Border{Width|Color} from CJX_Node to CJX_Object.

Change-Id: I07ba9ef2af675993c9f4d14cb74f48252a907569
Reviewed-on: https://pdfium-review.googlesource.com/20990
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
diff --git a/fxjs/xfa/cjx_exclgroup.cpp b/fxjs/xfa/cjx_exclgroup.cpp
index e24be80..1041e3f 100644
--- a/fxjs/xfa/cjx_exclgroup.cpp
+++ b/fxjs/xfa/cjx_exclgroup.cpp
@@ -86,7 +86,7 @@
   if (!params.empty())
     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
 
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
   if (!pWidgetData)
     return CJS_Return(runtime->NewNull());
 
diff --git a/fxjs/xfa/cjx_field.cpp b/fxjs/xfa/cjx_field.cpp
index 4b5f840..857aa50 100644
--- a/fxjs/xfa/cjx_field.cpp
+++ b/fxjs/xfa/cjx_field.cpp
@@ -40,7 +40,7 @@
 CJS_Return CJX_Field::clearItems(
     CJS_V8* runtime,
     const std::vector<v8::Local<v8::Value>>& params) {
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
   if (pWidgetData)
     pWidgetData->DeleteItem(-1, true, false);
   return CJS_Return(true);
@@ -81,7 +81,7 @@
   if (params.size() != 1)
     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
 
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
   if (!pWidgetData)
     return CJS_Return(true);
 
@@ -100,7 +100,7 @@
   if (iIndex < 0)
     return CJS_Return(runtime->NewNull());
 
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
   if (!pWidgetData)
     return CJS_Return(runtime->NewNull());
 
@@ -118,7 +118,7 @@
   if (params.size() != 1)
     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
 
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
   if (!pWidgetData)
     return CJS_Return(true);
 
@@ -133,7 +133,7 @@
   if (params.size() != 1)
     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
 
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
   if (!pWidgetData)
     return CJS_Return(true);
 
@@ -165,7 +165,7 @@
   if (iIndex < 0)
     return CJS_Return(runtime->NewNull());
 
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
   if (!pWidgetData)
     return CJS_Return(runtime->NewNull());
 
@@ -183,7 +183,7 @@
   if (params.size() != 2)
     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
 
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
   if (!pWidgetData)
     return CJS_Return(true);
 
@@ -203,7 +203,7 @@
   if (params.size() != 1 && params.size() != 2)
     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
 
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
   if (!pWidgetData)
     return CJS_Return(true);
 
diff --git a/fxjs/xfa/cjx_manifest.cpp b/fxjs/xfa/cjx_manifest.cpp
index 0f48b1d..d5c986a 100644
--- a/fxjs/xfa/cjx_manifest.cpp
+++ b/fxjs/xfa/cjx_manifest.cpp
@@ -27,6 +27,6 @@
   if (!params.empty())
     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
 
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
   return CJS_Return(runtime->NewBoolean(!!pWidgetData));
 }
diff --git a/fxjs/xfa/cjx_node.cpp b/fxjs/xfa/cjx_node.cpp
index 8234fa6..c0a7f37 100644
--- a/fxjs/xfa/cjx_node.cpp
+++ b/fxjs/xfa/cjx_node.cpp
@@ -789,58 +789,6 @@
   SetContent(wsNewValue, wsFormatValue, true, true, true);
 }
 
-void CJX_Node::Script_Som_BorderColor(CFXJSE_Value* pValue,
-                                      bool bSetting,
-                                      XFA_Attribute eAttribute) {
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
-  if (!pWidgetData)
-    return;
-
-  CXFA_BorderData borderData = pWidgetData->GetBorderData(true);
-  int32_t iSize = borderData.CountEdges();
-  if (bSetting) {
-    int32_t r = 0;
-    int32_t g = 0;
-    int32_t b = 0;
-    std::tie(r, g, b) = StrToRGB(pValue->ToWideString());
-    FX_ARGB rgb = ArgbEncode(100, r, g, b);
-    for (int32_t i = 0; i < iSize; ++i)
-      borderData.GetEdgeData(i).SetColor(rgb);
-
-    return;
-  }
-
-  FX_ARGB color = borderData.GetEdgeData(0).GetColor();
-  int32_t a;
-  int32_t r;
-  int32_t g;
-  int32_t b;
-  std::tie(a, r, g, b) = ArgbDecode(color);
-  pValue->SetString(
-      WideString::Format(L"%d,%d,%d", r, g, b).UTF8Encode().AsStringView());
-}
-
-void CJX_Node::Script_Som_BorderWidth(CFXJSE_Value* pValue,
-                                      bool bSetting,
-                                      XFA_Attribute eAttribute) {
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
-  if (!pWidgetData)
-    return;
-
-  CXFA_BorderData borderData = pWidgetData->GetBorderData(true);
-  if (bSetting) {
-    CXFA_Measurement thickness = borderData.GetEdgeData(0).GetMSThickness();
-    pValue->SetString(thickness.ToString().UTF8Encode().AsStringView());
-    return;
-  }
-
-  WideString wsThickness = pValue->ToWideString();
-  for (int32_t i = 0; i < borderData.CountEdges(); ++i) {
-    borderData.GetEdgeData(i).SetMSThickness(
-        CXFA_Measurement(wsThickness.AsStringView()));
-  }
-}
-
 void CJX_Node::Script_Som_FillColor(CFXJSE_Value* pValue,
                                     bool bSetting,
                                     XFA_Attribute eAttribute) {
@@ -1343,10 +1291,6 @@
                                      bool bSetting,
                                      XFA_Attribute eAttribute) {}
 
-void CJX_Node::SetWidgetData(std::unique_ptr<CXFA_WidgetData> data) {
-  widget_data_ = std::move(data);
-}
-
 pdfium::Optional<WideString> CJX_Node::TryNamespace() {
   if (GetXFANode()->IsModelNode() ||
       GetXFANode()->GetElementType() == XFA_Element::Packet) {
diff --git a/fxjs/xfa/cjx_node.h b/fxjs/xfa/cjx_node.h
index 2cf41a0..8c42b34 100644
--- a/fxjs/xfa/cjx_node.h
+++ b/fxjs/xfa/cjx_node.h
@@ -8,7 +8,6 @@
 #define FXJS_XFA_CJX_NODE_H_
 
 #include <memory>
-#include <utility>
 #include <vector>
 
 #include "core/fxcrt/unowned_ptr.h"
@@ -47,9 +46,6 @@
                   bool bSyncData);
   WideString GetContent(bool bScriptModify);
 
-  void SetWidgetData(std::unique_ptr<CXFA_WidgetData> data);
-  CXFA_WidgetData* GetWidgetData() const { return widget_data_.get(); }
-
   void SetLayoutItem(CXFA_LayoutItem* item) { layout_item_ = item; }
   CXFA_LayoutItem* GetLayoutItem() const { return layout_item_.Get(); }
 
@@ -126,12 +122,6 @@
   void Script_Som_Message(CFXJSE_Value* pValue,
                           bool bSetting,
                           XFA_SOM_MESSAGETYPE iMessageType);
-  void Script_Som_BorderColor(CFXJSE_Value* pValue,
-                              bool bSetting,
-                              XFA_Attribute eAttribute);
-  void Script_Som_BorderWidth(CFXJSE_Value* pValue,
-                              bool bSetting,
-                              XFA_Attribute eAttribute);
   void Script_Som_FillColor(CFXJSE_Value* pValue,
                             bool bSetting,
                             XFA_Attribute eAttribute);
@@ -239,7 +229,6 @@
                                 XFA_Element eType);
 
  private:
-  std::unique_ptr<CXFA_WidgetData> widget_data_;
   UnownedPtr<CXFA_LayoutItem> layout_item_;
   size_t calc_recursion_count_ = 0;
   static const CJX_MethodSpec MethodSpecs[];
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index 4ba1d39..5b21730 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -6,7 +6,7 @@
 
 #include "fxjs/xfa/cjx_object.h"
 
-#include <utility>
+#include <tuple>
 
 #include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/xml/cfx_xmltext.h"
@@ -57,6 +57,37 @@
 XFA_MAPDATABLOCKCALLBACKINFO gs_XFADefaultFreeData = {XFA_DefaultFreeData,
                                                       nullptr};
 
+std::tuple<int32_t, int32_t, int32_t> StrToRGB(const WideString& strRGB) {
+  int32_t r = 0;
+  int32_t g = 0;
+  int32_t b = 0;
+
+  size_t iIndex = 0;
+  for (size_t i = 0; i < strRGB.GetLength(); ++i) {
+    wchar_t ch = strRGB[i];
+    if (ch == L',')
+      ++iIndex;
+    if (iIndex > 2)
+      break;
+
+    int32_t iValue = ch - L'0';
+    if (iValue >= 0 && iValue <= 9) {
+      switch (iIndex) {
+        case 0:
+          r = r * 10 + iValue;
+          break;
+        case 1:
+          g = g * 10 + iValue;
+          break;
+        default:
+          b = b * 10 + iValue;
+          break;
+      }
+    }
+  }
+  return {r, g, b};
+}
+
 }  // namespace
 
 struct XFA_MAPDATABLOCK {
@@ -893,3 +924,53 @@
   }
   pValue->SetInteger(GetInteger(eAttribute));
 }
+
+void CJX_Object::Script_Som_BorderColor(CFXJSE_Value* pValue,
+                                        bool bSetting,
+                                        XFA_Attribute eAttribute) {
+  if (!widget_data_)
+    return;
+
+  CXFA_BorderData borderData = widget_data_->GetBorderData(true);
+  int32_t iSize = borderData.CountEdges();
+  if (bSetting) {
+    int32_t r = 0;
+    int32_t g = 0;
+    int32_t b = 0;
+    std::tie(r, g, b) = StrToRGB(pValue->ToWideString());
+    FX_ARGB rgb = ArgbEncode(100, r, g, b);
+    for (int32_t i = 0; i < iSize; ++i)
+      borderData.GetEdgeData(i).SetColor(rgb);
+
+    return;
+  }
+
+  FX_ARGB color = borderData.GetEdgeData(0).GetColor();
+  int32_t a;
+  int32_t r;
+  int32_t g;
+  int32_t b;
+  std::tie(a, r, g, b) = ArgbDecode(color);
+  pValue->SetString(
+      WideString::Format(L"%d,%d,%d", r, g, b).UTF8Encode().AsStringView());
+}
+
+void CJX_Object::Script_Som_BorderWidth(CFXJSE_Value* pValue,
+                                        bool bSetting,
+                                        XFA_Attribute eAttribute) {
+  if (!widget_data_)
+    return;
+
+  CXFA_BorderData borderData = widget_data_->GetBorderData(true);
+  if (bSetting) {
+    CXFA_Measurement thickness = borderData.GetEdgeData(0).GetMSThickness();
+    pValue->SetString(thickness.ToString().UTF8Encode().AsStringView());
+    return;
+  }
+
+  WideString wsThickness = pValue->ToWideString();
+  for (int32_t i = 0; i < borderData.CountEdges(); ++i) {
+    borderData.GetEdgeData(i).SetMSThickness(
+        CXFA_Measurement(wsThickness.AsStringView()));
+  }
+}
diff --git a/fxjs/xfa/cjx_object.h b/fxjs/xfa/cjx_object.h
index c191dcf..dfd2bbc 100644
--- a/fxjs/xfa/cjx_object.h
+++ b/fxjs/xfa/cjx_object.h
@@ -9,6 +9,7 @@
 
 #include <map>
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "core/fxcrt/unowned_ptr.h"
@@ -16,6 +17,7 @@
 #include "core/fxcrt/xml/cfx_xmlelement.h"
 #include "third_party/base/optional.h"
 #include "xfa/fxfa/fxfa_basic.h"
+#include "xfa/fxfa/parser/cxfa_widgetdata.h"
 
 class CFXJSE_Value;
 class CJS_V8;
@@ -51,6 +53,11 @@
 
   CXFA_Document* GetDocument() const;
 
+  void SetWidgetData(std::unique_ptr<CXFA_WidgetData> data) {
+    widget_data_ = std::move(data);
+  }
+  CXFA_WidgetData* GetWidgetData() const { return widget_data_.get(); }
+
   bool HasMethod(const WideString& func) const;
   CJS_Return RunMethod(const WideString& func,
                        const std::vector<v8::Local<v8::Value>>& params);
@@ -85,6 +92,13 @@
                                 bool bSetting,
                                 XFA_Attribute eAttribute);
 
+  void Script_Som_BorderColor(CFXJSE_Value* pValue,
+                              bool bSetting,
+                              XFA_Attribute eAttribute);
+  void Script_Som_BorderWidth(CFXJSE_Value* pValue,
+                              bool bSetting,
+                              XFA_Attribute eAttribute);
+
   pdfium::Optional<int32_t> TryInteger(XFA_Attribute eAttr, bool bUseDefault);
   bool SetInteger(XFA_Attribute eAttr, int32_t iValue, bool bNotify);
   int32_t GetInteger(XFA_Attribute eAttr);
@@ -164,6 +178,7 @@
   void RemoveMapModuleKey(void* pKey);
   void MoveBufferMapData(CXFA_Object* pDstModule);
 
+  std::unique_ptr<CXFA_WidgetData> widget_data_;
   UnownedPtr<CXFA_Object> object_;
   std::unique_ptr<XFA_MAPMODULEDATA> map_module_data_;
   std::unique_ptr<CXFA_CalcData> calc_data_;
diff --git a/fxjs/xfa/cjx_template.cpp b/fxjs/xfa/cjx_template.cpp
index 8ba2bca..d55fd66 100644
--- a/fxjs/xfa/cjx_template.cpp
+++ b/fxjs/xfa/cjx_template.cpp
@@ -50,9 +50,7 @@
     const std::vector<v8::Local<v8::Value>>& params) {
   if (!params.empty())
     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
-
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
-  return CJS_Return(runtime->NewBoolean(!!pWidgetData));
+  return CJS_Return(runtime->NewBoolean(!!GetWidgetData()));
 }
 
 CJS_Return CJX_Template::recalculate(
@@ -68,9 +66,7 @@
     const std::vector<v8::Local<v8::Value>>& params) {
   if (!params.empty())
     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
-
-  CXFA_WidgetData* pWidgetData = GetXFANode()->GetWidgetData();
-  return CJS_Return(runtime->NewBoolean(!!pWidgetData));
+  return CJS_Return(runtime->NewBoolean(!!GetWidgetData()));
 }
 
 CJS_Return CJX_Template::execValidate(
@@ -78,5 +74,5 @@
     const std::vector<v8::Local<v8::Value>>& params) {
   if (!params.empty())
     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
-  return CJS_Return(runtime->NewBoolean(!!GetXFANode()->GetWidgetData()));
+  return CJS_Return(runtime->NewBoolean(!!GetWidgetData()));
 }
diff --git a/xfa/fxfa/parser/xfa_basic_data_element_script.cpp b/xfa/fxfa/parser/xfa_basic_data_element_script.cpp
index e9814d8..071612e 100644
--- a/xfa/fxfa/parser/xfa_basic_data_element_script.cpp
+++ b/xfa/fxfa/parser/xfa_basic_data_element_script.cpp
@@ -1053,7 +1053,7 @@
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Attribute_String,
      XFA_Attribute::Presence, XFA_ScriptType::Basic},
     {0x5a3b375d, L"borderColor",
-     (XFA_ATTRIBUTE_CALLBACK)&CJX_Node::Script_Som_BorderColor,
+     (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Som_BorderColor,
      XFA_Attribute::Unknown, XFA_ScriptType::Basic},
     {0x5e936ed6, L"fontColor",
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Node::Script_Som_FontColor,
@@ -1122,7 +1122,7 @@
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Node::Script_Field_SelectedIndex,
      XFA_Attribute::Unknown, XFA_ScriptType::Basic},
     {0xf65e34be, L"borderWidth",
-     (XFA_ATTRIBUTE_CALLBACK)&CJX_Node::Script_Som_BorderWidth,
+     (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Som_BorderWidth,
      XFA_Attribute::Unknown, XFA_ScriptType::Basic},
     {0x31b19c1, L"name",
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Attribute_String,
@@ -1308,7 +1308,7 @@
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Attribute_String,
      XFA_Attribute::Presence, XFA_ScriptType::Basic},
     {0x5a3b375d, L"borderColor",
-     (XFA_ATTRIBUTE_CALLBACK)&CJX_Node::Script_Som_BorderColor,
+     (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Som_BorderColor,
      XFA_Attribute::Unknown, XFA_ScriptType::Basic},
     {0x79b67434, L"mandatoryMessage",
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Node::Script_Som_MandatoryMessage,
@@ -1362,7 +1362,7 @@
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Node::Script_Som_ValidationMessage,
      XFA_Attribute::Unknown, XFA_ScriptType::Basic},
     {0xf65e34be, L"borderWidth",
-     (XFA_ATTRIBUTE_CALLBACK)&CJX_Node::Script_Som_BorderWidth,
+     (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Som_BorderWidth,
      XFA_Attribute::Unknown, XFA_ScriptType::Basic},
     {0xc0811ed, L"use",
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Attribute_String,
@@ -1538,7 +1538,7 @@
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Attribute_String,
      XFA_Attribute::Presence, XFA_ScriptType::Basic},
     {0x5a3b375d, L"borderColor",
-     (XFA_ATTRIBUTE_CALLBACK)&CJX_Node::Script_Som_BorderColor,
+     (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Som_BorderColor,
      XFA_Attribute::Unknown, XFA_ScriptType::Basic},
     {0x7a7cc341, L"vAlign",
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Attribute_String,
@@ -1589,7 +1589,7 @@
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Attribute_String,
      XFA_Attribute::Scope, XFA_ScriptType::Basic},
     {0xf65e34be, L"borderWidth",
-     (XFA_ATTRIBUTE_CALLBACK)&CJX_Node::Script_Som_BorderWidth,
+     (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Som_BorderWidth,
      XFA_Attribute::Unknown, XFA_ScriptType::Basic},
     {0xc0811ed, L"use",
      (XFA_ATTRIBUTE_CALLBACK)&CJX_Object::Script_Attribute_String,