Large-scale usage of fxcrt::Mask<>

Convert XFA_PrintOpt and XFA_ResolveNode

-- Rename to XFA_ResolveFlag, since it is not a node per-se.

Change-Id: I38d09f95befddd9a4e492d8585e5964daeca2eca
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/83958
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
index d957fea..f4d5fea 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
@@ -577,7 +577,7 @@
 void CPDFXFA_DocEnvironment::Print(CXFA_FFDoc* hDoc,
                                    int32_t nStartPage,
                                    int32_t nEndPage,
-                                   XFA_PrintOptMask dwOptions) {
+                                   Mask<XFA_PrintOpt> dwOptions) {
   if (hDoc != m_pContext->GetXFADoc())
     return;
 
@@ -590,10 +590,12 @@
 
   pFormFillEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print(
       pFormFillEnv->GetFormFillInfo()->m_pJsPlatform,
-      dwOptions & XFA_PRINTOPT_ShowDialog, nStartPage, nEndPage,
-      dwOptions & XFA_PRINTOPT_CanCancel, dwOptions & XFA_PRINTOPT_ShrinkPage,
-      dwOptions & XFA_PRINTOPT_AsImage, dwOptions & XFA_PRINTOPT_ReverseOrder,
-      dwOptions & XFA_PRINTOPT_PrintAnnot);
+      !!(dwOptions & XFA_PrintOpt::kShowDialog), nStartPage, nEndPage,
+      !!(dwOptions & XFA_PrintOpt::kCanCancel),
+      !!(dwOptions & XFA_PrintOpt::kShrinkPage),
+      !!(dwOptions & XFA_PrintOpt::kAsImage),
+      !!(dwOptions & XFA_PrintOpt::kReverseOrder),
+      !!(dwOptions & XFA_PrintOpt::kPrintAnnot));
 }
 
 FX_ARGB CPDFXFA_DocEnvironment::GetHighlightColor(
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h
index 4bf1507..9d110f1 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h
@@ -54,7 +54,7 @@
   void Print(CXFA_FFDoc* hDoc,
              int32_t nStartPage,
              int32_t nEndPage,
-             XFA_PrintOptMask dwOptions) override;
+             Mask<XFA_PrintOpt> dwOptions) override;
   FX_ARGB GetHighlightColor(const CXFA_FFDoc* hDoc) const override;
   IJS_Runtime* GetIJSRuntime(const CXFA_FFDoc* hDoc) const override;
   CFX_XMLDocument* GetXMLDoc() const override;
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index 205b862..bd6dee1 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -182,7 +182,7 @@
 bool CFXJSE_Engine::QueryNodeByFlag(CXFA_Node* refNode,
                                     WideStringView propname,
                                     v8::Local<v8::Value>* pValue,
-                                    XFA_ResolveNodeMask dwFlag) {
+                                    Mask<XFA_ResolveFlag> dwFlag) {
   if (!refNode)
     return false;
 
@@ -209,7 +209,7 @@
 bool CFXJSE_Engine::UpdateNodeByFlag(CXFA_Node* refNode,
                                      WideStringView propname,
                                      v8::Local<v8::Value> pValue,
-                                     XFA_ResolveNodeMask dwFlag) {
+                                     Mask<XFA_ResolveFlag> dwFlag) {
   if (!refNode)
     return false;
 
@@ -243,9 +243,10 @@
   WideString wsPropName = WideString::FromUTF8(szPropName);
   if (pScriptContext->UpdateNodeByFlag(
           pRefNode, wsPropName.AsStringView(), pValue,
-          XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings |
-              XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
-              XFA_RESOLVENODE_Attributes)) {
+          Mask<XFA_ResolveFlag>{
+              XFA_ResolveFlag::kParent, XFA_ResolveFlag::kSiblings,
+              XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kProperties,
+              XFA_ResolveFlag::kAttributes})) {
     return;
   }
   if (pOriginalNode->IsThisProxy() && fxv8::IsUndefined(pValue)) {
@@ -299,13 +300,15 @@
 
   if (pScriptContext->QueryNodeByFlag(
           pRefNode, wsPropName.AsStringView(), &pValue,
-          XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
-              XFA_RESOLVENODE_Attributes)) {
+          Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kChildren,
+                                XFA_ResolveFlag::kProperties,
+                                XFA_ResolveFlag::kAttributes})) {
     return pValue;
   }
   if (pScriptContext->QueryNodeByFlag(
           pRefNode, wsPropName.AsStringView(), &pValue,
-          XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings)) {
+          Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kParent,
+                                XFA_ResolveFlag::kSiblings})) {
     return pValue;
   }
 
@@ -373,8 +376,9 @@
   CXFA_Node* pRefNode = ToNode(pObject);
   if (pScriptContext->QueryNodeByFlag(
           pRefNode, wsPropName.AsStringView(), &pReturnValue,
-          XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
-              XFA_RESOLVENODE_Attributes)) {
+          Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kChildren,
+                                XFA_ResolveFlag::kProperties,
+                                XFA_ResolveFlag::kAttributes})) {
     return pReturnValue;
   }
   if (pObject == pScriptContext->GetThisObject() ||
@@ -382,7 +386,8 @@
        !pScriptContext->IsStrictScopeInJavaScript())) {
     if (pScriptContext->QueryNodeByFlag(
             pRefNode, wsPropName.AsStringView(), &pReturnValue,
-            XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings)) {
+            Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kParent,
+                                  XFA_ResolveFlag::kSiblings})) {
       return pReturnValue;
     }
   }
@@ -650,31 +655,30 @@
 Optional<CFXJSE_Engine::ResolveResult> CFXJSE_Engine::ResolveObjects(
     CXFA_Object* refObject,
     WideStringView wsExpression,
-    XFA_ResolveNodeMask dwStyles) {
+    Mask<XFA_ResolveFlag> dwStyles) {
   return ResolveObjectsWithBindNode(refObject, wsExpression, dwStyles, nullptr);
 }
 
 Optional<CFXJSE_Engine::ResolveResult>
 CFXJSE_Engine::ResolveObjectsWithBindNode(CXFA_Object* refObject,
                                           WideStringView wsExpression,
-                                          XFA_ResolveNodeMask dwStyles,
+                                          Mask<XFA_ResolveFlag> dwStyles,
                                           CXFA_Node* bindNode) {
   if (wsExpression.IsEmpty())
     return pdfium::nullopt;
 
-  ResolveResult result;
-  if (m_eScriptType != CXFA_Script::Type::Formcalc ||
-      (dwStyles & (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings))) {
+  const bool bParentOrSiblings =
+      !!(dwStyles & Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kParent,
+                                          XFA_ResolveFlag::kSiblings});
+  if (m_eScriptType != CXFA_Script::Type::Formcalc || bParentOrSiblings)
     m_upObjectArray.clear();
-  }
-  if (refObject && refObject->IsNode() &&
-      (dwStyles & (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings))) {
+  if (refObject && refObject->IsNode() && bParentOrSiblings)
     m_upObjectArray.push_back(refObject->AsNode());
-  }
 
+  ResolveResult result;
   bool bNextCreate = false;
   CFXJSE_NodeHelper* pNodeHelper = m_ResolveProcessor->GetNodeHelper();
-  if (dwStyles & XFA_RESOLVENODE_CreateNode)
+  if (dwStyles & XFA_ResolveFlag::kCreateNode)
     pNodeHelper->SetCreateNodeType(bindNode);
 
   pNodeHelper->m_pCreateParent = nullptr;
@@ -694,7 +698,7 @@
     m_ResolveProcessor->SetCurStart(nStart);
     nStart = m_ResolveProcessor->GetFilter(wsExpression, nStart, rndFind);
     if (nStart < 1) {
-      if ((dwStyles & XFA_RESOLVENODE_CreateNode) && !bNextCreate) {
+      if ((dwStyles & XFA_ResolveFlag::kCreateNode) && !bNextCreate) {
         CXFA_Node* pDataNode = nullptr;
         nStart = pNodeHelper->m_iCurAllStart;
         if (nStart != -1) {
@@ -710,7 +714,7 @@
           findObjects.emplace_back(pDataNode);
           break;
         }
-        dwStyles |= XFA_RESOLVENODE_Bind;
+        dwStyles |= XFA_ResolveFlag::kBind;
         findObjects.clear();
         findObjects.emplace_back(pNodeHelper->m_pAllStartParent.Get());
         continue;
@@ -729,8 +733,8 @@
     std::vector<cppgc::Member<CXFA_Object>> retObjects;
     while (i < nNodes) {
       bool bDataBind = false;
-      if (((dwStyles & XFA_RESOLVENODE_Bind) ||
-           (dwStyles & XFA_RESOLVENODE_CreateNode)) &&
+      if (((dwStyles & XFA_ResolveFlag::kBind) ||
+           (dwStyles & XFA_ResolveFlag::kCreateNode)) &&
           nNodes > 1) {
         CFXJSE_ResolveNodeData rndBind(nullptr);
         m_ResolveProcessor->GetFilter(wsExpression, nStart, rndBind);
@@ -768,7 +772,7 @@
 
     nNodes = fxcrt::CollectionSize<int32_t>(retObjects);
     if (nNodes < 1) {
-      if (dwStyles & XFA_RESOLVENODE_CreateNode) {
+      if (dwStyles & XFA_ResolveFlag::kCreateNode) {
         bNextCreate = true;
         if (!pNodeHelper->m_pCreateParent) {
           pNodeHelper->m_pCreateParent = ToNode(rndFind.m_CurObject.Get());
@@ -786,9 +790,10 @@
 
     findObjects = std::move(retObjects);
     rndFind.m_Result.objects.clear();
-    if (nLevel == 0)
-      dwStyles &= ~(XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings);
-
+    if (nLevel == 0) {
+      dwStyles.Clear(XFA_ResolveFlag::kParent);
+      dwStyles.Clear(XFA_ResolveFlag::kSiblings);
+    }
     nLevel++;
   }
 
@@ -803,8 +808,9 @@
       return result;
     }
   }
-  if (dwStyles & (XFA_RESOLVENODE_CreateNode | XFA_RESOLVENODE_Bind |
-                  XFA_RESOLVENODE_BindNew)) {
+  if ((dwStyles & XFA_ResolveFlag::kCreateNode) ||
+      (dwStyles & XFA_ResolveFlag::kBind) ||
+      (dwStyles & XFA_ResolveFlag::kBindNew)) {
     if (pNodeHelper->m_pCreateParent)
       result.objects.emplace_back(pNodeHelper->m_pCreateParent.Get());
     else
@@ -816,7 +822,7 @@
         result.type = ResolveResult::Type::kCreateNodeMidAll;
     }
 
-    if (!bNextCreate && (dwStyles & XFA_RESOLVENODE_CreateNode))
+    if (!bNextCreate && (dwStyles & XFA_ResolveFlag::kCreateNode))
       result.type = ResolveResult::Type::kExistNodes;
 
     if (result.objects.empty())
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h
index 9c83c0d..50094f1 100644
--- a/fxjs/xfa/cfxjse_engine.h
+++ b/fxjs/xfa/cfxjse_engine.h
@@ -12,6 +12,7 @@
 #include <type_traits>
 #include <vector>
 
+#include "core/fxcrt/mask.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "fxjs/cfx_v8.h"
 #include "v8/include/cppgc/persistent.h"
@@ -29,20 +30,19 @@
 class CFXJSE_Value;
 class CJS_Runtime;
 
-enum XFA_ResolveNode : uint16_t {
-  XFA_RESOLVENODE_Children = 1 << 0,
-  XFA_RESOLVENODE_TagName = 1 << 1,
-  XFA_RESOLVENODE_Attributes = 1 << 2,
-  XFA_RESOLVENODE_Properties = 1 << 3,
-  XFA_RESOLVENODE_Siblings = 1 << 5,
-  XFA_RESOLVENODE_Parent = 1 << 6,
-  XFA_RESOLVENODE_AnyChild = 1 << 7,
-  XFA_RESOLVENODE_ALL = 1 << 8,
-  XFA_RESOLVENODE_CreateNode = 1 << 10,
-  XFA_RESOLVENODE_Bind = 1 << 11,
-  XFA_RESOLVENODE_BindNew = 1 << 12,
+enum class XFA_ResolveFlag : uint16_t {
+  kChildren = 1 << 0,
+  kTagName = 1 << 1,
+  kAttributes = 1 << 2,
+  kProperties = 1 << 3,
+  kSiblings = 1 << 5,
+  kParent = 1 << 6,
+  kAnyChild = 1 << 7,
+  kALL = 1 << 8,
+  kCreateNode = 1 << 10,
+  kBind = 1 << 11,
+  kBindNew = 1 << 12,
 };
-using XFA_ResolveNodeMask = std::underlying_type<XFA_ResolveNode>::type;
 
 class CFXJSE_Engine final : public CFX_V8 {
  public:
@@ -117,12 +117,12 @@
 
   Optional<ResolveResult> ResolveObjects(CXFA_Object* refObject,
                                          WideStringView wsExpression,
-                                         XFA_ResolveNodeMask dwStyles);
+                                         Mask<XFA_ResolveFlag> dwStyles);
 
   Optional<ResolveResult> ResolveObjectsWithBindNode(
       CXFA_Object* refObject,
       WideStringView wsExpression,
-      XFA_ResolveNodeMask dwStyles,
+      Mask<XFA_ResolveFlag> dwStyles,
       CXFA_Node* bindNode);
 
   v8::Local<v8::Object> GetOrCreateJSBindingFromMap(CXFA_Object* pObject);
@@ -153,11 +153,11 @@
   bool QueryNodeByFlag(CXFA_Node* refNode,
                        WideStringView propname,
                        v8::Local<v8::Value>* pValue,
-                       XFA_ResolveNodeMask dwFlag);
+                       Mask<XFA_ResolveFlag> dwFlag);
   bool UpdateNodeByFlag(CXFA_Node* refNode,
                         WideStringView propname,
                         v8::Local<v8::Value> pValue,
-                        XFA_ResolveNodeMask dwFlag);
+                        Mask<XFA_ResolveFlag> dwFlag);
   bool IsStrictScopeInJavaScript();
   CXFA_Object* GetVariablesThis(CXFA_Object* pObject);
   CXFA_Object* GetVariablesScript(CXFA_Object* pObject);
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index 2127ad6..bd8e1a0 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -1553,13 +1553,13 @@
     return v8::Local<v8::Value>();
 
   CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
-  constexpr XFA_ResolveNodeMask kFlags =
-      XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
-      XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
   Optional<CFXJSE_Engine::ResolveResult> maybeResult =
       pScriptContext->ResolveObjects(
           pScriptContext->GetThisObject(),
-          WideString::FromUTF8(bsAccessorName).AsStringView(), kFlags);
+          WideString::FromUTF8(bsAccessorName).AsStringView(),
+          Mask<XFA_ResolveFlag>{
+              XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kProperties,
+              XFA_ResolveFlag::kSiblings, XFA_ResolveFlag::kParent});
   if (!maybeResult.has_value() ||
       maybeResult.value().type != CFXJSE_Engine::ResolveResult::Type::kNodes ||
       maybeResult.value().objects.empty()) {
@@ -1583,11 +1583,11 @@
   WideString wsSomExpression = WideString::FromUTF8(bsSomExp);
   CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
   CXFA_Object* pNode = nullptr;
-  XFA_ResolveNodeMask dwFlags = 0;
+  Mask<XFA_ResolveFlag> dwFlags;
   if (bDotAccessor) {
     if (fxv8::IsNull(pRefValue)) {
       pNode = pScriptContext->GetThisObject();
-      dwFlags = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
+      dwFlags = {XFA_ResolveFlag::kSiblings, XFA_ResolveFlag::kParent};
     } else {
       pNode = CFXJSE_Engine::ToObject(pIsolate, pRefValue);
       if (!pNode)
@@ -1605,17 +1605,18 @@
           wsName = L"#" + WideString::FromASCII(pNode->GetClassName());
 
         wsSomExpression = wsName + wsSomExpression;
-        dwFlags = XFA_RESOLVENODE_Siblings;
+        dwFlags = XFA_ResolveFlag::kSiblings;
       } else {
         dwFlags = (bsSomExp == "*")
-                      ? (XFA_RESOLVENODE_Children)
-                      : (XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
-                         XFA_RESOLVENODE_Properties);
+                      ? Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kChildren}
+                      : Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kChildren,
+                                              XFA_ResolveFlag::kAttributes,
+                                              XFA_ResolveFlag::kProperties};
       }
     }
   } else {
     pNode = CFXJSE_Engine::ToObject(pIsolate, pRefValue);
-    dwFlags = XFA_RESOLVENODE_AnyChild;
+    dwFlags = XFA_ResolveFlag::kAnyChild;
   }
   return pScriptContext->ResolveObjects(pNode, wsSomExpression.AsStringView(),
                                         dwFlags);
diff --git a/fxjs/xfa/cfxjse_resolveprocessor.cpp b/fxjs/xfa/cfxjse_resolveprocessor.cpp
index 6bdc5e4..58dc7ae 100644
--- a/fxjs/xfa/cfxjse_resolveprocessor.cpp
+++ b/fxjs/xfa/cfxjse_resolveprocessor.cpp
@@ -65,13 +65,13 @@
     return false;
 
   if (!rnd.m_CurObject->IsNode()) {
-    if (rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) {
+    if (rnd.m_dwStyles & XFA_ResolveFlag::kAttributes) {
       return ResolveForAttributeRs(rnd.m_CurObject.Get(), &rnd.m_Result,
                                    rnd.m_wsName.AsStringView());
     }
     return false;
   }
-  if (rnd.m_dwStyles & XFA_RESOLVENODE_AnyChild)
+  if (rnd.m_dwStyles & XFA_ResolveFlag::kAnyChild)
     return ResolveAnyChild(pIsolate, rnd);
 
   if (rnd.m_wsName.GetLength()) {
@@ -103,7 +103,7 @@
       rnd.m_Result.objects.emplace_back(pObjNode);
     } else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) {
       rnd.m_Result.objects.emplace_back(rnd.m_CurObject.Get());
-    } else if ((rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) &&
+    } else if ((rnd.m_dwStyles & XFA_ResolveFlag::kAttributes) &&
                ResolveForAttributeRs(rnd.m_CurObject.Get(), &rnd.m_Result,
                                      rnd.m_wsName.AsStringView())) {
       return true;
@@ -194,7 +194,7 @@
   rndFind.m_uHashName = static_cast<XFA_HashCode>(
       FX_HashCode_GetW(rndFind.m_wsName.AsStringView()));
   rndFind.m_nLevel = rnd.m_nLevel + 1;
-  rndFind.m_dwStyles = XFA_RESOLVENODE_Children;
+  rndFind.m_dwStyles = XFA_ResolveFlag::kChildren;
   rndFind.m_wsCondition = rnd.m_wsCondition;
   Resolve(pIsolate, rndFind);
 
@@ -215,8 +215,8 @@
   CFXJSE_ResolveNodeData rndFind(rnd.m_pSC.Get());
   rndFind.m_nLevel = rnd.m_nLevel + 1;
   rndFind.m_dwStyles = rnd.m_dwStyles;
-  rndFind.m_dwStyles |= XFA_RESOLVENODE_TagName;
-  rndFind.m_dwStyles &= ~XFA_RESOLVENODE_Attributes;
+  rndFind.m_dwStyles |= XFA_ResolveFlag::kTagName;
+  rndFind.m_dwStyles.Clear(XFA_ResolveFlag::kAttributes);
   rndFind.m_wsName = std::move(wsName);
   rndFind.m_uHashName = static_cast<XFA_HashCode>(
       FX_HashCode_GetW(rndFind.m_wsName.AsStringView()));
@@ -259,7 +259,7 @@
 
   CXFA_Node* curNode = rnd.m_CurObject->AsNode();
   size_t nNum = rnd.m_Result.objects.size();
-  uint32_t dwStyles = rnd.m_dwStyles;
+  Mask<XFA_ResolveFlag> dwStyles = rnd.m_dwStyles;
   WideString& wsName = rnd.m_wsName;
   XFA_HashCode uNameHash = rnd.m_uHashName;
   WideString& wsCondition = rnd.m_wsCondition;
@@ -289,7 +289,7 @@
     else
       children.push_back(pChild);
   }
-  if ((dwStyles & XFA_RESOLVENODE_Properties) && pVariablesNode) {
+  if ((dwStyles & XFA_ResolveFlag::kProperties) && pVariablesNode) {
     if (pVariablesNode->GetClassHashCode() == uNameHash) {
       rnd.m_Result.objects.emplace_back(pVariablesNode);
     } else {
@@ -309,13 +309,13 @@
     }
   }
 
-  if (dwStyles & XFA_RESOLVENODE_Children) {
+  if (dwStyles & XFA_ResolveFlag::kChildren) {
     bool bSetFlag = false;
-    if (pPageSetNode && (dwStyles & XFA_RESOLVENODE_Properties))
+    if (pPageSetNode && (dwStyles & XFA_ResolveFlag::kProperties))
       children.push_back(pPageSetNode);
 
     for (CXFA_Node* child : children) {
-      if (dwStyles & XFA_RESOLVENODE_TagName) {
+      if (dwStyles & XFA_ResolveFlag::kTagName) {
         if (child->GetClassHashCode() == uNameHash)
           rnd.m_Result.objects.emplace_back(child);
       } else if (child->GetNameHash() == uNameHash) {
@@ -340,13 +340,13 @@
       }
     }
     if (rnd.m_Result.objects.size() > nNum) {
-      if (!(dwStyles & XFA_RESOLVENODE_ALL)) {
+      if (!(dwStyles & XFA_ResolveFlag::kALL)) {
         std::vector<CXFA_Node*> upArrayNodes;
         if (curNode->IsTransparent()) {
           CXFA_Node* pCurrent = ToNode(rnd.m_Result.objects.front().Get());
           if (pCurrent) {
             upArrayNodes =
-                pCurrent->GetSiblings(!!(dwStyles & XFA_RESOLVENODE_TagName));
+                pCurrent->GetSiblings(!!(dwStyles & XFA_ResolveFlag::kTagName));
           }
         }
         if (upArrayNodes.size() > rnd.m_Result.objects.size()) {
@@ -360,11 +360,11 @@
       return !rnd.m_Result.objects.empty();
     }
   }
-  if (dwStyles & XFA_RESOLVENODE_Attributes) {
+  if (dwStyles & XFA_ResolveFlag::kAttributes) {
     if (ResolveForAttributeRs(curNode, &rnd.m_Result, wsName.AsStringView()))
       return 1;
   }
-  if (dwStyles & XFA_RESOLVENODE_Properties) {
+  if (dwStyles & XFA_ResolveFlag::kProperties) {
     for (CXFA_Node* pChildProperty : properties) {
       if (pChildProperty->IsUnnamed()) {
         if (pChildProperty->GetClassHashCode() == uNameHash)
@@ -416,19 +416,19 @@
     return false;
   }
 
-  if (dwStyles & XFA_RESOLVENODE_Siblings) {
+  if (dwStyles & XFA_ResolveFlag::kSiblings) {
     CXFA_Node* child = parentNode->GetFirstChild();
-    uint32_t dwSubStyles =
-        XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties;
-    if (dwStyles & XFA_RESOLVENODE_TagName)
-      dwSubStyles |= XFA_RESOLVENODE_TagName;
-    if (dwStyles & XFA_RESOLVENODE_ALL)
-      dwSubStyles |= XFA_RESOLVENODE_ALL;
+    Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kChildren,
+                                         XFA_ResolveFlag::kProperties};
+    if (dwStyles & XFA_ResolveFlag::kTagName)
+      dwSubStyles |= XFA_ResolveFlag::kTagName;
+    if (dwStyles & XFA_ResolveFlag::kALL)
+      dwSubStyles |= XFA_ResolveFlag::kALL;
 
     rndFind.m_dwStyles = dwSubStyles;
     while (child) {
       if (child == curNode) {
-        if (dwStyles & XFA_RESOLVENODE_TagName) {
+        if (dwStyles & XFA_ResolveFlag::kTagName) {
           if (uCurClassHash == uNameHash)
             rnd.m_Result.objects.emplace_back(curNode);
         } else {
@@ -445,7 +445,7 @@
         continue;
       }
 
-      if (dwStyles & XFA_RESOLVENODE_TagName) {
+      if (dwStyles & XFA_ResolveFlag::kTagName) {
         if (child->GetClassHashCode() == uNameHash)
           rnd.m_Result.objects.emplace_back(child);
       } else if (child->GetNameHash() == uNameHash) {
@@ -464,8 +464,8 @@
       if (bInnerSearch) {
         rndFind.m_CurObject = child;
         WideString wsOriginCondition = std::move(rndFind.m_wsCondition);
-        uint32_t dwOriginStyle = rndFind.m_dwStyles;
-        rndFind.m_dwStyles = dwOriginStyle | XFA_RESOLVENODE_ALL;
+        Mask<XFA_ResolveFlag> dwOriginStyle = rndFind.m_dwStyles;
+        rndFind.m_dwStyles = dwOriginStyle | XFA_ResolveFlag::kALL;
         ResolveNormal(pIsolate, rndFind);
         rndFind.m_dwStyles = dwOriginStyle;
         rndFind.m_wsCondition = std::move(wsOriginCondition);
@@ -482,7 +482,7 @@
         CXFA_Node* pCurrent = ToNode(rnd.m_Result.objects.front().Get());
         if (pCurrent) {
           upArrayNodes =
-              pCurrent->GetSiblings(!!(dwStyles & XFA_RESOLVENODE_TagName));
+              pCurrent->GetSiblings(!!(dwStyles & XFA_ResolveFlag::kTagName));
         }
         if (upArrayNodes.size() > rnd.m_Result.objects.size()) {
           CXFA_Object* pSaveObject = rnd.m_Result.objects.front().Get();
@@ -496,13 +496,14 @@
     }
   }
 
-  if (dwStyles & XFA_RESOLVENODE_Parent) {
-    uint32_t dwSubStyles = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent |
-                           XFA_RESOLVENODE_Properties;
-    if (dwStyles & XFA_RESOLVENODE_TagName)
-      dwSubStyles |= XFA_RESOLVENODE_TagName;
-    if (dwStyles & XFA_RESOLVENODE_ALL)
-      dwSubStyles |= XFA_RESOLVENODE_ALL;
+  if (dwStyles & XFA_ResolveFlag::kParent) {
+    Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kSiblings,
+                                         XFA_ResolveFlag::kParent,
+                                         XFA_ResolveFlag::kProperties};
+    if (dwStyles & XFA_ResolveFlag::kTagName)
+      dwSubStyles |= XFA_ResolveFlag::kTagName;
+    if (dwStyles & XFA_ResolveFlag::kALL)
+      dwSubStyles |= XFA_ResolveFlag::kALL;
 
     rndFind.m_dwStyles = dwSubStyles;
     rndFind.m_CurObject = parentNode;
@@ -555,7 +556,7 @@
       wCur = pSrc[nStart++];
       if (wCur == '.') {
         if (nNameCount == 0) {
-          rnd.m_dwStyles |= XFA_RESOLVENODE_AnyChild;
+          rnd.m_dwStyles |= XFA_ResolveFlag::kAnyChild;
           continue;
         }
         if (wPrev == '\\') {
@@ -627,8 +628,8 @@
     break;
   }
   if (bAll) {
-    if (pRnd->m_dwStyles & XFA_RESOLVENODE_CreateNode) {
-      if (pRnd->m_dwStyles & XFA_RESOLVENODE_Bind) {
+    if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
+      if (pRnd->m_dwStyles & XFA_ResolveFlag::kBind) {
         m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject.Get());
         m_pNodeHelper->m_iCreateCount = 1;
         pRnd->m_Result.objects.clear();
@@ -638,7 +639,7 @@
         m_pNodeHelper->m_iCurAllStart = m_iCurStart;
         m_pNodeHelper->m_pAllStartParent = ToNode(pRnd->m_CurObject.Get());
       }
-    } else if (pRnd->m_dwStyles & XFA_RESOLVENODE_BindNew) {
+    } else if (pRnd->m_dwStyles & XFA_ResolveFlag::kBindNew) {
       if (m_pNodeHelper->m_iCurAllStart == -1)
         m_pNodeHelper->m_iCurAllStart = m_iCurStart;
     }
@@ -652,7 +653,7 @@
     iIndex += iCurIndex;
 
   if (iIndex < 0 || static_cast<size_t>(iIndex) >= iFoundCount) {
-    if (pRnd->m_dwStyles & XFA_RESOLVENODE_CreateNode) {
+    if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
       m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject.Get());
       m_pNodeHelper->m_iCreateCount = iIndex - iFoundCount + 1;
     }
@@ -682,13 +683,13 @@
 
   int32_t iLen = wsCondition.GetLength();
   if (!iLen) {
-    if (pRnd->m_dwStyles & XFA_RESOLVENODE_ALL)
+    if (pRnd->m_dwStyles & XFA_ResolveFlag::kALL)
       return;
     if (iFoundCount == 1)
       return;
 
     if (iFoundCount <= iCurIndex) {
-      if (pRnd->m_dwStyles & XFA_RESOLVENODE_CreateNode) {
+      if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
         m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject.Get());
         m_pNodeHelper->m_iCreateCount = iCurIndex - iFoundCount + 1;
       }
@@ -717,16 +718,13 @@
   }
 }
 
-void CFXJSE_ResolveProcessor::SetStylesForChild(uint32_t dwParentStyles,
-                                                CFXJSE_ResolveNodeData& rnd) {
-  uint32_t dwSubStyles = XFA_RESOLVENODE_Children;
-  if (dwParentStyles & XFA_RESOLVENODE_TagName)
-    dwSubStyles |= XFA_RESOLVENODE_TagName;
-
-  dwSubStyles &= ~XFA_RESOLVENODE_Parent;
-  dwSubStyles &= ~XFA_RESOLVENODE_Siblings;
-  dwSubStyles &= ~XFA_RESOLVENODE_Properties;
-  dwSubStyles |= XFA_RESOLVENODE_ALL;
+void CFXJSE_ResolveProcessor::SetStylesForChild(
+    Mask<XFA_ResolveFlag> dwParentStyles,
+    CFXJSE_ResolveNodeData& rnd) {
+  Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kChildren,
+                                       XFA_ResolveFlag::kALL};
+  if (dwParentStyles & XFA_ResolveFlag::kTagName)
+    dwSubStyles |= XFA_ResolveFlag::kTagName;
   rnd.m_dwStyles = dwSubStyles;
 }
 
diff --git a/fxjs/xfa/cfxjse_resolveprocessor.h b/fxjs/xfa/cfxjse_resolveprocessor.h
index ac11338..d809abb 100644
--- a/fxjs/xfa/cfxjse_resolveprocessor.h
+++ b/fxjs/xfa/cfxjse_resolveprocessor.h
@@ -32,7 +32,7 @@
   WideString m_wsCondition;
   XFA_HashCode m_uHashName = XFA_HASHCODE_None;
   int32_t m_nLevel = 0;
-  XFA_ResolveNodeMask m_dwStyles = XFA_RESOLVENODE_Children;
+  Mask<XFA_ResolveFlag> m_dwStyles = XFA_ResolveFlag::kChildren;
   CFXJSE_Engine::ResolveResult m_Result;
 };
 
@@ -60,7 +60,8 @@
   bool ResolveNumberSign(v8::Isolate* pIsolate, CFXJSE_ResolveNodeData& rnd);
   bool ResolveAsterisk(CFXJSE_ResolveNodeData& rnd);
   bool ResolveNormal(v8::Isolate* pIsolate, CFXJSE_ResolveNodeData& rnd);
-  void SetStylesForChild(uint32_t dwParentStyles, CFXJSE_ResolveNodeData& rnd);
+  void SetStylesForChild(Mask<XFA_ResolveFlag> dwParentStyles,
+                         CFXJSE_ResolveNodeData& rnd);
 
   void ConditionArray(size_t iCurIndex,
                       WideString wsCondition,
diff --git a/fxjs/xfa/cjx_hostpseudomodel.cpp b/fxjs/xfa/cjx_hostpseudomodel.cpp
index 51daeec..e56702b 100644
--- a/fxjs/xfa/cjx_hostpseudomodel.cpp
+++ b/fxjs/xfa/cjx_hostpseudomodel.cpp
@@ -292,9 +292,9 @@
     if (!pObject)
       return CJS_Result::Success();
 
-    constexpr XFA_ResolveNodeMask kFlags = XFA_RESOLVENODE_Children |
-                                           XFA_RESOLVENODE_Parent |
-                                           XFA_RESOLVENODE_Siblings;
+    constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
+                                              XFA_ResolveFlag::kParent,
+                                              XFA_ResolveFlag::kSiblings};
     Optional<CFXJSE_Engine::ResolveResult> maybeResult =
         pScriptContext->ResolveObjects(
             pObject, runtime->ToWideString(params[0]).AsStringView(), kFlags);
@@ -378,9 +378,9 @@
     if (!pObject)
       return CJS_Result::Success();
 
-    constexpr XFA_ResolveNodeMask kFlags = XFA_RESOLVENODE_Children |
-                                           XFA_RESOLVENODE_Parent |
-                                           XFA_RESOLVENODE_Siblings;
+    constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
+                                              XFA_ResolveFlag::kParent,
+                                              XFA_ResolveFlag::kSiblings};
     Optional<CFXJSE_Engine::ResolveResult> maybeResult =
         pScriptContext->ResolveObjects(pObject, wsName.AsStringView(), kFlags);
     if (!maybeResult.has_value() ||
@@ -441,9 +441,9 @@
       if (!pObject)
         return CJS_Result::Success();
 
-      constexpr XFA_ResolveNodeMask kFlags = XFA_RESOLVENODE_Children |
-                                             XFA_RESOLVENODE_Parent |
-                                             XFA_RESOLVENODE_Siblings;
+      constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
+                                                XFA_ResolveFlag::kParent,
+                                                XFA_ResolveFlag::kSiblings};
       Optional<CFXJSE_Engine::ResolveResult> maybeResult =
           pScriptContext->ResolveObjects(
               pObject, runtime->ToWideString(params[0]).AsStringView(), kFlags);
@@ -534,19 +534,19 @@
   if (!pNotify)
     return CJS_Result::Success();
 
-  XFA_PrintOptMask dwOptions = 0;
+  Mask<XFA_PrintOpt> dwOptions;
   if (runtime->ToBoolean(params[0]))
-    dwOptions |= XFA_PRINTOPT_ShowDialog;
+    dwOptions |= XFA_PrintOpt::kShowDialog;
   if (runtime->ToBoolean(params[3]))
-    dwOptions |= XFA_PRINTOPT_CanCancel;
+    dwOptions |= XFA_PrintOpt::kCanCancel;
   if (runtime->ToBoolean(params[4]))
-    dwOptions |= XFA_PRINTOPT_ShrinkPage;
+    dwOptions |= XFA_PrintOpt::kShrinkPage;
   if (runtime->ToBoolean(params[5]))
-    dwOptions |= XFA_PRINTOPT_AsImage;
+    dwOptions |= XFA_PrintOpt::kAsImage;
   if (runtime->ToBoolean(params[6]))
-    dwOptions |= XFA_PRINTOPT_ReverseOrder;
+    dwOptions |= XFA_PrintOpt::kReverseOrder;
   if (runtime->ToBoolean(params[7]))
-    dwOptions |= XFA_PRINTOPT_PrintAnnot;
+    dwOptions |= XFA_PrintOpt::kPrintAnnot;
 
   int32_t nStartPage = runtime->ToInt32(params[1]);
   int32_t nEndPage = runtime->ToInt32(params[2]);
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index 073628e..177e656 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -1004,13 +1004,13 @@
 
   CXFA_Node* pProtoNode = nullptr;
   if (!wsSOM.IsEmpty()) {
-    constexpr XFA_ResolveNodeMask kFlags =
-        XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
-        XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
-        XFA_RESOLVENODE_Siblings;
     Optional<CFXJSE_Engine::ResolveResult> maybeResult =
         GetDocument()->GetScriptContext()->ResolveObjects(
-            pProtoRoot, wsSOM.AsStringView(), kFlags);
+            pProtoRoot, wsSOM.AsStringView(),
+            Mask<XFA_ResolveFlag>{
+                XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kAttributes,
+                XFA_ResolveFlag::kProperties, XFA_ResolveFlag::kParent,
+                XFA_ResolveFlag::kSiblings});
     if (maybeResult.has_value() &&
         maybeResult.value().objects.front()->IsNode()) {
       pProtoNode = maybeResult.value().objects.front()->AsNode();
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp
index 17d18b6..bca07ac 100644
--- a/fxjs/xfa/cjx_tree.cpp
+++ b/fxjs/xfa/cjx_tree.cpp
@@ -47,13 +47,13 @@
   if (pRefNode->GetElementType() == XFA_Element::Xfa)
     pRefNode = pScriptContext->GetThisObject();
 
-  constexpr XFA_ResolveNodeMask kFlags =
-      XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
-      XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
-      XFA_RESOLVENODE_Siblings;
   Optional<CFXJSE_Engine::ResolveResult> maybeResult =
-      pScriptContext->ResolveObjects(ToNode(pRefNode),
-                                     wsExpression.AsStringView(), kFlags);
+      pScriptContext->ResolveObjects(
+          ToNode(pRefNode), wsExpression.AsStringView(),
+          Mask<XFA_ResolveFlag>{
+              XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kAttributes,
+              XFA_ResolveFlag::kProperties, XFA_ResolveFlag::kParent,
+              XFA_ResolveFlag::kSiblings});
   if (!maybeResult.has_value())
     return CJS_Result::Success(runtime->NewNull());
 
@@ -88,10 +88,10 @@
     refNode = GetDocument()->GetScriptContext()->GetThisObject();
 
   CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
-  constexpr XFA_ResolveNodeMask kFlags =
-      XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
-      XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
-      XFA_RESOLVENODE_Siblings;
+  const Mask<XFA_ResolveFlag> kFlags = {
+      XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kAttributes,
+      XFA_ResolveFlag::kProperties, XFA_ResolveFlag::kParent,
+      XFA_ResolveFlag::kSiblings};
   return CJS_Result::Success(ResolveNodeList(pScriptContext->GetIsolate(),
                                              runtime->ToWideString(params[0]),
                                              kFlags, ToNode(refNode)));
@@ -105,8 +105,8 @@
     ThrowInvalidPropertyException();
     return;
   }
-  constexpr XFA_ResolveNodeMask kFlags =
-      XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
+  const Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kSiblings,
+                                        XFA_ResolveFlag::kALL};
   WideString wsExpression = GetAttributeByEnum(XFA_Attribute::Name) + L"[*]";
   *pValue = ResolveNodeList(pIsolate, wsExpression, kFlags, nullptr);
 }
@@ -119,8 +119,8 @@
     ThrowInvalidPropertyException();
     return;
   }
-  constexpr XFA_ResolveNodeMask kFlags =
-      XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
+  const Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kSiblings,
+                                        XFA_ResolveFlag::kALL};
   WideString wsExpression =
       L"#" + WideString::FromASCII(GetXFAObject()->GetClassName()) + L"[*]";
   *pValue = ResolveNodeList(pIsolate, wsExpression, kFlags, nullptr);
@@ -208,7 +208,7 @@
 
 v8::Local<v8::Value> CJX_Tree::ResolveNodeList(v8::Isolate* pIsolate,
                                                WideString wsExpression,
-                                               XFA_ResolveNodeMask dwFlag,
+                                               Mask<XFA_ResolveFlag> dwFlag,
                                                CXFA_Node* refNode) {
   if (!refNode)
     refNode = GetXFANode();
diff --git a/fxjs/xfa/cjx_tree.h b/fxjs/xfa/cjx_tree.h
index f18d0b7..6db4e99 100644
--- a/fxjs/xfa/cjx_tree.h
+++ b/fxjs/xfa/cjx_tree.h
@@ -45,7 +45,7 @@
 
   v8::Local<v8::Value> ResolveNodeList(v8::Isolate* pIsolate,
                                        WideString wsExpression,
-                                       XFA_ResolveNodeMask dwFlag,
+                                       Mask<XFA_ResolveFlag> dwFlag,
                                        CXFA_Node* refNode);
 };
 
diff --git a/testing/resources/javascript/xfa_specific/xfa_host_pseudomodel_expected.txt b/testing/resources/javascript/xfa_specific/xfa_host_pseudomodel_expected.txt
index 3835e4a..6c1359d 100644
--- a/testing/resources/javascript/xfa_specific/xfa_host_pseudomodel_expected.txt
+++ b/testing/resources/javascript/xfa_specific/xfa_host_pseudomodel_expected.txt
@@ -52,7 +52,7 @@
 Alert: PASS: xfa.host.pageDown('ignored arg') = undefined
 Alert: PASS: xfa.host.print(1, 2, 3, 4, 5, 6, 7) threw XFAObject.print: Incorrect number of parameters passed to function.
 Alert: PASS: xfa.host.print(1, 2, 3, 4, 5, 6, 7, 8, 9) threw XFAObject.print: Incorrect number of parameters passed to function.
-Doc Print: 1, 1, 1, 2, 4, 8, 16, 32
+Doc Print: 1, 1, 1, 1, 1, 1, 1, 1
 Alert: PASS: xfa.host.print(true, 1, 1, true, true, true, true, true) = undefined
 Alert: PASS: xfa.host.response() threw XFAObject.response: Incorrect number of parameters passed to function.
 Alert: PASS: xfa.host.response(1, 2, 3, 4, 5) threw XFAObject.response: Incorrect number of parameters passed to function.
diff --git a/xfa/fwl/cfwl_message.h b/xfa/fwl/cfwl_message.h
index 7a6e565..fd8fb1b 100644
--- a/xfa/fwl/cfwl_message.h
+++ b/xfa/fwl/cfwl_message.h
@@ -7,6 +7,9 @@
 #ifndef XFA_FWL_CFWL_MESSAGE_H_
 #define XFA_FWL_CFWL_MESSAGE_H_
 
+#include <type_traits>
+
+#include "core/fxcrt/mask.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "v8/include/cppgc/macros.h"
 
diff --git a/xfa/fxfa/cxfa_ffdoc.cpp b/xfa/fxfa/cxfa_ffdoc.cpp
index ab25174..1bec0e7 100644
--- a/xfa/fxfa/cxfa_ffdoc.cpp
+++ b/xfa/fxfa/cxfa_ffdoc.cpp
@@ -200,7 +200,7 @@
 
 void CXFA_FFDoc::Print(int32_t nStartPage,
                        int32_t nEndPage,
-                       XFA_PrintOptMask dwOptions) {
+                       Mask<XFA_PrintOpt> dwOptions) {
   m_pDocEnvironment->Print(this, nStartPage, nEndPage, dwOptions);
 }
 
diff --git a/xfa/fxfa/cxfa_ffdoc.h b/xfa/fxfa/cxfa_ffdoc.h
index 2ec9ce6..c0880fb 100644
--- a/xfa/fxfa/cxfa_ffdoc.h
+++ b/xfa/fxfa/cxfa_ffdoc.h
@@ -12,6 +12,7 @@
 
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_stream.h"
+#include "core/fxcrt/mask.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/dib/fx_dib.h"
@@ -102,7 +103,7 @@
     virtual void Print(CXFA_FFDoc* hDoc,
                        int32_t nStartPage,
                        int32_t nEndPage,
-                       XFA_PrintOptMask dwOptions) = 0;
+                       Mask<XFA_PrintOpt> dwOptions) = 0;
     virtual FX_ARGB GetHighlightColor(const CXFA_FFDoc* hDoc) const = 0;
     virtual IJS_Runtime* GetIJSRuntime(const CXFA_FFDoc* hDoc) const = 0;
     virtual CFX_XMLDocument* GetXMLDoc() const = 0;
@@ -149,7 +150,9 @@
   bool IsValidationsEnabled() const;
   void SetValidationsEnabled(bool bEnabled);
   void SetFocusWidget(CXFA_FFWidget* hWidget);
-  void Print(int32_t nStartPage, int32_t nEndPage, XFA_PrintOptMask dwOptions);
+  void Print(int32_t nStartPage,
+             int32_t nEndPage,
+             Mask<XFA_PrintOpt> dwOptions);
   FX_ARGB GetHighlightColor() const;
   IJS_Runtime* GetIJSRuntime() const;
   CFX_XMLDocument* GetXMLDocument() const;
diff --git a/xfa/fxfa/cxfa_ffdocview.cpp b/xfa/fxfa/cxfa_ffdocview.cpp
index 5c24b66..e68a1f7 100644
--- a/xfa/fxfa/cxfa_ffdocview.cpp
+++ b/xfa/fxfa/cxfa_ffdocview.cpp
@@ -437,12 +437,12 @@
     pRefNode = node->IsWidgetReady() ? node : nullptr;
   }
   WideString wsExpression = (!pRefNode ? L"$form." : L"") + wsName;
-  constexpr XFA_ResolveNodeMask kFlags =
-      XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
-      XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
   Optional<CFXJSE_Engine::ResolveResult> maybeResult =
-      pScriptContext->ResolveObjects(pRefNode, wsExpression.AsStringView(),
-                                     kFlags);
+      pScriptContext->ResolveObjects(
+          pRefNode, wsExpression.AsStringView(),
+          Mask<XFA_ResolveFlag>{
+              XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kProperties,
+              XFA_ResolveFlag::kSiblings, XFA_ResolveFlag::kParent});
   if (!maybeResult.has_value())
     return nullptr;
 
@@ -634,12 +634,13 @@
     CFXJSE_Engine* pScriptContext =
         pWidgetNode->GetDocument()->GetScriptContext();
     WideString wsRef = item->GetRef();
-    constexpr XFA_ResolveNodeMask kFlags =
-        XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
-        XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_ALL;
     Optional<CFXJSE_Engine::ResolveResult> maybeRS =
-        pScriptContext->ResolveObjects(pWidgetNode, wsRef.AsStringView(),
-                                       kFlags);
+        pScriptContext->ResolveObjects(
+            pWidgetNode, wsRef.AsStringView(),
+            Mask<XFA_ResolveFlag>{
+                XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kProperties,
+                XFA_ResolveFlag::kSiblings, XFA_ResolveFlag::kParent,
+                XFA_ResolveFlag::kALL});
     pWidgetNode->DeleteItem(-1, false, false);
     if (!maybeRS.has_value() ||
         maybeRS.value().type != CFXJSE_Engine::ResolveResult::Type::kNodes ||
diff --git a/xfa/fxfa/fxfa.h b/xfa/fxfa/fxfa.h
index ba3ca7c..688bdce 100644
--- a/xfa/fxfa/fxfa.h
+++ b/xfa/fxfa/fxfa.h
@@ -44,15 +44,14 @@
   kXFAForeground = 3,
 };
 
-enum XFA_PrintOpt : uint8_t {
-  XFA_PRINTOPT_ShowDialog = 1 << 0,
-  XFA_PRINTOPT_CanCancel = 1 << 1,
-  XFA_PRINTOPT_ShrinkPage = 1 << 2,
-  XFA_PRINTOPT_AsImage = 1 << 3,
-  XFA_PRINTOPT_ReverseOrder = 1 << 4,
-  XFA_PRINTOPT_PrintAnnot = 1 << 5,
+enum class XFA_PrintOpt : uint8_t {
+  kShowDialog = 1 << 0,
+  kCanCancel = 1 << 1,
+  kShrinkPage = 1 << 2,
+  kAsImage = 1 << 3,
+  kReverseOrder = 1 << 4,
+  kPrintAnnot = 1 << 5,
 };
-using XFA_PrintOptMask = std::underlying_type<XFA_PrintOpt>::type;
 
 enum class XFA_EventError {
   kError = -1,
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
index 843d790..4ceba71 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
@@ -209,13 +209,13 @@
       if (wsExpr.First(4).EqualsASCII("som(") && wsExpr.Back() == L')')
         wsProcessedTarget = wsExpr.Substr(4, wsExpr.GetLength() - 5);
 
-      constexpr XFA_ResolveNodeMask kFlags =
-          XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
-          XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Siblings |
-          XFA_RESOLVENODE_Parent;
       Optional<CFXJSE_Engine::ResolveResult> maybeResult =
           pDocument->GetScriptContext()->ResolveObjects(
-              pPageSetRoot, wsProcessedTarget.AsStringView(), kFlags);
+              pPageSetRoot, wsProcessedTarget.AsStringView(),
+              Mask<XFA_ResolveFlag>{
+                  XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kProperties,
+                  XFA_ResolveFlag::kAttributes, XFA_ResolveFlag::kSiblings,
+                  XFA_ResolveFlag::kParent});
       if (maybeResult.has_value() &&
           maybeResult.value().objects.front()->IsNode()) {
         return maybeResult.value().objects.front()->AsNode();
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp
index 588faef..740d41d 100644
--- a/xfa/fxfa/parser/cxfa_document.cpp
+++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -346,11 +346,12 @@
                                CXFA_Node* pTemplateNode,
                                bool bForceBind,
                                bool bUpLevel) {
-  XFA_ResolveNodeMask dwFlags =
-      XFA_RESOLVENODE_Children | XFA_RESOLVENODE_BindNew;
-  if (bUpLevel || !wsRef.EqualsASCII("name"))
-    dwFlags |= (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings);
-
+  Mask<XFA_ResolveFlag> dwFlags = {XFA_ResolveFlag::kChildren,
+                                   XFA_ResolveFlag::kBindNew};
+  if (bUpLevel || !wsRef.EqualsASCII("name")) {
+    dwFlags |= XFA_ResolveFlag::kParent;
+    dwFlags |= XFA_ResolveFlag::kSiblings;
+  }
   Optional<CFXJSE_Engine::ResolveResult> maybeResult =
       pDocument->GetScriptContext()->ResolveObjectsWithBindNode(
           pDataScope, wsRef.AsStringView(), dwFlags, pTemplateNode);
@@ -1198,8 +1199,8 @@
               pTemplateNodeBind
                   ? pTemplateNodeBind->JSObject()->GetCData(XFA_Attribute::Ref)
                   : WideString();
-          constexpr XFA_ResolveNodeMask kFlags =
-              XFA_RESOLVENODE_Children | XFA_RESOLVENODE_CreateNode;
+          const Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
+                                                XFA_ResolveFlag::kCreateNode};
           Optional<CFXJSE_Engine::ResolveResult> maybeResult =
               pDocument->GetScriptContext()->ResolveObjectsWithBindNode(
                   pDataScope, wsRef.AsStringView(), kFlags, pTemplateNode);
@@ -1577,12 +1578,13 @@
 
     CXFA_Node* pProtoNode = nullptr;
     if (!wsSOM.IsEmpty()) {
-      constexpr uint32_t dwFlag =
-          XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
-          XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
-          XFA_RESOLVENODE_Siblings;
       Optional<CFXJSE_Engine::ResolveResult> maybeResult =
-          m_pScriptContext->ResolveObjects(pUseHrefNode, wsSOM, dwFlag);
+          m_pScriptContext->ResolveObjects(
+              pUseHrefNode, wsSOM,
+              Mask<XFA_ResolveFlag>{
+                  XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kAttributes,
+                  XFA_ResolveFlag::kProperties, XFA_ResolveFlag::kParent,
+                  XFA_ResolveFlag::kSiblings});
       if (maybeResult.has_value()) {
         auto* pFirstObject = maybeResult.value().objects.front().Get();
         if (pFirstObject && pFirstObject->IsNode())