1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "xfa/fxfa/parser/cxfa_node.h"
8 
9 #include <algorithm>
10 #include <map>
11 #include <memory>
12 #include <set>
13 #include <utility>
14 #include <vector>
15 
16 #include "core/fxcrt/autorestorer.h"
17 #include "core/fxcrt/cfx_readonlymemorystream.h"
18 #include "core/fxcrt/fx_codepage.h"
19 #include "core/fxcrt/fx_extension.h"
20 #include "core/fxcrt/xml/cfx_xmldocument.h"
21 #include "core/fxcrt/xml/cfx_xmlelement.h"
22 #include "core/fxcrt/xml/cfx_xmlnode.h"
23 #include "core/fxcrt/xml/cfx_xmltext.h"
24 #include "core/fxge/dib/cfx_dibitmap.h"
25 #include "core/fxge/fx_font.h"
26 #include "fxjs/gc/container_trace.h"
27 #include "fxjs/xfa/cfxjse_engine.h"
28 #include "fxjs/xfa/cfxjse_value.h"
29 #include "fxjs/xfa/cjx_node.h"
30 #include "third_party/base/check.h"
31 #include "third_party/base/compiler_specific.h"
32 #include "third_party/base/notreached.h"
33 #include "third_party/base/span.h"
34 #include "third_party/base/stl_util.h"
35 #include "xfa/fde/cfde_textout.h"
36 #include "xfa/fgas/crt/cfgas_decimal.h"
37 #include "xfa/fgas/crt/locale_iface.h"
38 #include "xfa/fgas/font/cfgas_fontmgr.h"
39 #include "xfa/fgas/font/cfgas_gefont.h"
40 #include "xfa/fxfa/cxfa_eventparam.h"
41 #include "xfa/fxfa/cxfa_ffapp.h"
42 #include "xfa/fxfa/cxfa_ffdocview.h"
43 #include "xfa/fxfa/cxfa_ffnotify.h"
44 #include "xfa/fxfa/cxfa_fontmgr.h"
45 #include "xfa/fxfa/cxfa_textprovider.h"
46 #include "xfa/fxfa/parser/cxfa_accessiblecontent.h"
47 #include "xfa/fxfa/parser/cxfa_acrobat.h"
48 #include "xfa/fxfa/parser/cxfa_acrobat7.h"
49 #include "xfa/fxfa/parser/cxfa_adbe_jsconsole.h"
50 #include "xfa/fxfa/parser/cxfa_adbe_jsdebugger.h"
51 #include "xfa/fxfa/parser/cxfa_addsilentprint.h"
52 #include "xfa/fxfa/parser/cxfa_addviewerpreferences.h"
53 #include "xfa/fxfa/parser/cxfa_adjustdata.h"
54 #include "xfa/fxfa/parser/cxfa_adobeextensionlevel.h"
55 #include "xfa/fxfa/parser/cxfa_agent.h"
56 #include "xfa/fxfa/parser/cxfa_alwaysembed.h"
57 #include "xfa/fxfa/parser/cxfa_amd.h"
58 #include "xfa/fxfa/parser/cxfa_appearancefilter.h"
59 #include "xfa/fxfa/parser/cxfa_arc.h"
60 #include "xfa/fxfa/parser/cxfa_area.h"
61 #include "xfa/fxfa/parser/cxfa_arraynodelist.h"
62 #include "xfa/fxfa/parser/cxfa_assist.h"
63 #include "xfa/fxfa/parser/cxfa_attachnodelist.h"
64 #include "xfa/fxfa/parser/cxfa_attributes.h"
65 #include "xfa/fxfa/parser/cxfa_autosave.h"
66 #include "xfa/fxfa/parser/cxfa_barcode.h"
67 #include "xfa/fxfa/parser/cxfa_base.h"
68 #include "xfa/fxfa/parser/cxfa_batchoutput.h"
69 #include "xfa/fxfa/parser/cxfa_behavioroverride.h"
70 #include "xfa/fxfa/parser/cxfa_bind.h"
71 #include "xfa/fxfa/parser/cxfa_binditems.h"
72 #include "xfa/fxfa/parser/cxfa_bookend.h"
73 #include "xfa/fxfa/parser/cxfa_boolean.h"
74 #include "xfa/fxfa/parser/cxfa_border.h"
75 #include "xfa/fxfa/parser/cxfa_break.h"
76 #include "xfa/fxfa/parser/cxfa_breakafter.h"
77 #include "xfa/fxfa/parser/cxfa_breakbefore.h"
78 #include "xfa/fxfa/parser/cxfa_button.h"
79 #include "xfa/fxfa/parser/cxfa_cache.h"
80 #include "xfa/fxfa/parser/cxfa_calculate.h"
81 #include "xfa/fxfa/parser/cxfa_calendarsymbols.h"
82 #include "xfa/fxfa/parser/cxfa_caption.h"
83 #include "xfa/fxfa/parser/cxfa_certificate.h"
84 #include "xfa/fxfa/parser/cxfa_certificates.h"
85 #include "xfa/fxfa/parser/cxfa_change.h"
86 #include "xfa/fxfa/parser/cxfa_checkbutton.h"
87 #include "xfa/fxfa/parser/cxfa_choicelist.h"
88 #include "xfa/fxfa/parser/cxfa_color.h"
89 #include "xfa/fxfa/parser/cxfa_comb.h"
90 #include "xfa/fxfa/parser/cxfa_command.h"
91 #include "xfa/fxfa/parser/cxfa_common.h"
92 #include "xfa/fxfa/parser/cxfa_compress.h"
93 #include "xfa/fxfa/parser/cxfa_compression.h"
94 #include "xfa/fxfa/parser/cxfa_compresslogicalstructure.h"
95 #include "xfa/fxfa/parser/cxfa_compressobjectstream.h"
96 #include "xfa/fxfa/parser/cxfa_config.h"
97 #include "xfa/fxfa/parser/cxfa_conformance.h"
98 #include "xfa/fxfa/parser/cxfa_connect.h"
99 #include "xfa/fxfa/parser/cxfa_connectionset.h"
100 #include "xfa/fxfa/parser/cxfa_connectstring.h"
101 #include "xfa/fxfa/parser/cxfa_contentarea.h"
102 #include "xfa/fxfa/parser/cxfa_contentcopy.h"
103 #include "xfa/fxfa/parser/cxfa_copies.h"
104 #include "xfa/fxfa/parser/cxfa_corner.h"
105 #include "xfa/fxfa/parser/cxfa_creator.h"
106 #include "xfa/fxfa/parser/cxfa_currencysymbol.h"
107 #include "xfa/fxfa/parser/cxfa_currencysymbols.h"
108 #include "xfa/fxfa/parser/cxfa_currentpage.h"
109 #include "xfa/fxfa/parser/cxfa_data.h"
110 #include "xfa/fxfa/parser/cxfa_datagroup.h"
111 #include "xfa/fxfa/parser/cxfa_datamodel.h"
112 #include "xfa/fxfa/parser/cxfa_datavalue.h"
113 #include "xfa/fxfa/parser/cxfa_date.h"
114 #include "xfa/fxfa/parser/cxfa_datepattern.h"
115 #include "xfa/fxfa/parser/cxfa_datepatterns.h"
116 #include "xfa/fxfa/parser/cxfa_datetime.h"
117 #include "xfa/fxfa/parser/cxfa_datetimeedit.h"
118 #include "xfa/fxfa/parser/cxfa_datetimesymbols.h"
119 #include "xfa/fxfa/parser/cxfa_day.h"
120 #include "xfa/fxfa/parser/cxfa_daynames.h"
121 #include "xfa/fxfa/parser/cxfa_debug.h"
122 #include "xfa/fxfa/parser/cxfa_decimal.h"
123 #include "xfa/fxfa/parser/cxfa_defaulttypeface.h"
124 #include "xfa/fxfa/parser/cxfa_defaultui.h"
125 #include "xfa/fxfa/parser/cxfa_delete.h"
126 #include "xfa/fxfa/parser/cxfa_delta.h"
127 #include "xfa/fxfa/parser/cxfa_desc.h"
128 #include "xfa/fxfa/parser/cxfa_destination.h"
129 #include "xfa/fxfa/parser/cxfa_digestmethod.h"
130 #include "xfa/fxfa/parser/cxfa_digestmethods.h"
131 #include "xfa/fxfa/parser/cxfa_document.h"
132 #include "xfa/fxfa/parser/cxfa_document_builder.h"
133 #include "xfa/fxfa/parser/cxfa_documentassembly.h"
134 #include "xfa/fxfa/parser/cxfa_draw.h"
135 #include "xfa/fxfa/parser/cxfa_driver.h"
136 #include "xfa/fxfa/parser/cxfa_dsigdata.h"
137 #include "xfa/fxfa/parser/cxfa_duplexoption.h"
138 #include "xfa/fxfa/parser/cxfa_dynamicrender.h"
139 #include "xfa/fxfa/parser/cxfa_edge.h"
140 #include "xfa/fxfa/parser/cxfa_effectiveinputpolicy.h"
141 #include "xfa/fxfa/parser/cxfa_effectiveoutputpolicy.h"
142 #include "xfa/fxfa/parser/cxfa_embed.h"
143 #include "xfa/fxfa/parser/cxfa_encoding.h"
144 #include "xfa/fxfa/parser/cxfa_encodings.h"
145 #include "xfa/fxfa/parser/cxfa_encrypt.h"
146 #include "xfa/fxfa/parser/cxfa_encryption.h"
147 #include "xfa/fxfa/parser/cxfa_encryptionlevel.h"
148 #include "xfa/fxfa/parser/cxfa_encryptionmethod.h"
149 #include "xfa/fxfa/parser/cxfa_encryptionmethods.h"
150 #include "xfa/fxfa/parser/cxfa_enforce.h"
151 #include "xfa/fxfa/parser/cxfa_equate.h"
152 #include "xfa/fxfa/parser/cxfa_equaterange.h"
153 #include "xfa/fxfa/parser/cxfa_era.h"
154 #include "xfa/fxfa/parser/cxfa_eranames.h"
155 #include "xfa/fxfa/parser/cxfa_event.h"
156 #include "xfa/fxfa/parser/cxfa_exclgroup.h"
157 #include "xfa/fxfa/parser/cxfa_exclude.h"
158 #include "xfa/fxfa/parser/cxfa_excludens.h"
159 #include "xfa/fxfa/parser/cxfa_exdata.h"
160 #include "xfa/fxfa/parser/cxfa_execute.h"
161 #include "xfa/fxfa/parser/cxfa_exobject.h"
162 #include "xfa/fxfa/parser/cxfa_extras.h"
163 #include "xfa/fxfa/parser/cxfa_field.h"
164 #include "xfa/fxfa/parser/cxfa_fill.h"
165 #include "xfa/fxfa/parser/cxfa_filter.h"
166 #include "xfa/fxfa/parser/cxfa_fliplabel.h"
167 #include "xfa/fxfa/parser/cxfa_float.h"
168 #include "xfa/fxfa/parser/cxfa_font.h"
169 #include "xfa/fxfa/parser/cxfa_fontinfo.h"
170 #include "xfa/fxfa/parser/cxfa_form.h"
171 #include "xfa/fxfa/parser/cxfa_format.h"
172 #include "xfa/fxfa/parser/cxfa_formfieldfilling.h"
173 #include "xfa/fxfa/parser/cxfa_groupparent.h"
174 #include "xfa/fxfa/parser/cxfa_handler.h"
175 #include "xfa/fxfa/parser/cxfa_hyphenation.h"
176 #include "xfa/fxfa/parser/cxfa_ifempty.h"
177 #include "xfa/fxfa/parser/cxfa_image.h"
178 #include "xfa/fxfa/parser/cxfa_imageedit.h"
179 #include "xfa/fxfa/parser/cxfa_includexdpcontent.h"
180 #include "xfa/fxfa/parser/cxfa_incrementalload.h"
181 #include "xfa/fxfa/parser/cxfa_incrementalmerge.h"
182 #include "xfa/fxfa/parser/cxfa_insert.h"
183 #include "xfa/fxfa/parser/cxfa_instancemanager.h"
184 #include "xfa/fxfa/parser/cxfa_integer.h"
185 #include "xfa/fxfa/parser/cxfa_interactive.h"
186 #include "xfa/fxfa/parser/cxfa_issuers.h"
187 #include "xfa/fxfa/parser/cxfa_items.h"
188 #include "xfa/fxfa/parser/cxfa_jog.h"
189 #include "xfa/fxfa/parser/cxfa_keep.h"
190 #include "xfa/fxfa/parser/cxfa_keyusage.h"
191 #include "xfa/fxfa/parser/cxfa_labelprinter.h"
192 #include "xfa/fxfa/parser/cxfa_layout.h"
193 #include "xfa/fxfa/parser/cxfa_level.h"
194 #include "xfa/fxfa/parser/cxfa_line.h"
195 #include "xfa/fxfa/parser/cxfa_linear.h"
196 #include "xfa/fxfa/parser/cxfa_linearized.h"
197 #include "xfa/fxfa/parser/cxfa_locale.h"
198 #include "xfa/fxfa/parser/cxfa_localeset.h"
199 #include "xfa/fxfa/parser/cxfa_localevalue.h"
200 #include "xfa/fxfa/parser/cxfa_lockdocument.h"
201 #include "xfa/fxfa/parser/cxfa_log.h"
202 #include "xfa/fxfa/parser/cxfa_manifest.h"
203 #include "xfa/fxfa/parser/cxfa_map.h"
204 #include "xfa/fxfa/parser/cxfa_margin.h"
205 #include "xfa/fxfa/parser/cxfa_mdp.h"
206 #include "xfa/fxfa/parser/cxfa_measurement.h"
207 #include "xfa/fxfa/parser/cxfa_medium.h"
208 #include "xfa/fxfa/parser/cxfa_mediuminfo.h"
209 #include "xfa/fxfa/parser/cxfa_meridiem.h"
210 #include "xfa/fxfa/parser/cxfa_meridiemnames.h"
211 #include "xfa/fxfa/parser/cxfa_message.h"
212 #include "xfa/fxfa/parser/cxfa_messaging.h"
213 #include "xfa/fxfa/parser/cxfa_mode.h"
214 #include "xfa/fxfa/parser/cxfa_modifyannots.h"
215 #include "xfa/fxfa/parser/cxfa_month.h"
216 #include "xfa/fxfa/parser/cxfa_monthnames.h"
217 #include "xfa/fxfa/parser/cxfa_msgid.h"
218 #include "xfa/fxfa/parser/cxfa_nameattr.h"
219 #include "xfa/fxfa/parser/cxfa_neverembed.h"
220 #include "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h"
221 #include "xfa/fxfa/parser/cxfa_numberofcopies.h"
222 #include "xfa/fxfa/parser/cxfa_numberpattern.h"
223 #include "xfa/fxfa/parser/cxfa_numberpatterns.h"
224 #include "xfa/fxfa/parser/cxfa_numbersymbol.h"
225 #include "xfa/fxfa/parser/cxfa_numbersymbols.h"
226 #include "xfa/fxfa/parser/cxfa_numericedit.h"
227 #include "xfa/fxfa/parser/cxfa_occur.h"
228 #include "xfa/fxfa/parser/cxfa_oid.h"
229 #include "xfa/fxfa/parser/cxfa_oids.h"
230 #include "xfa/fxfa/parser/cxfa_openaction.h"
231 #include "xfa/fxfa/parser/cxfa_operation.h"
232 #include "xfa/fxfa/parser/cxfa_output.h"
233 #include "xfa/fxfa/parser/cxfa_outputbin.h"
234 #include "xfa/fxfa/parser/cxfa_outputxsl.h"
235 #include "xfa/fxfa/parser/cxfa_overflow.h"
236 #include "xfa/fxfa/parser/cxfa_overprint.h"
237 #include "xfa/fxfa/parser/cxfa_packet.h"
238 #include "xfa/fxfa/parser/cxfa_packets.h"
239 #include "xfa/fxfa/parser/cxfa_pagearea.h"
240 #include "xfa/fxfa/parser/cxfa_pageoffset.h"
241 #include "xfa/fxfa/parser/cxfa_pagerange.h"
242 #include "xfa/fxfa/parser/cxfa_pageset.h"
243 #include "xfa/fxfa/parser/cxfa_pagination.h"
244 #include "xfa/fxfa/parser/cxfa_paginationoverride.h"
245 #include "xfa/fxfa/parser/cxfa_para.h"
246 #include "xfa/fxfa/parser/cxfa_part.h"
247 #include "xfa/fxfa/parser/cxfa_password.h"
248 #include "xfa/fxfa/parser/cxfa_passwordedit.h"
249 #include "xfa/fxfa/parser/cxfa_pattern.h"
250 #include "xfa/fxfa/parser/cxfa_pcl.h"
251 #include "xfa/fxfa/parser/cxfa_pdf.h"
252 #include "xfa/fxfa/parser/cxfa_pdfa.h"
253 #include "xfa/fxfa/parser/cxfa_permissions.h"
254 #include "xfa/fxfa/parser/cxfa_picktraybypdfsize.h"
255 #include "xfa/fxfa/parser/cxfa_picture.h"
256 #include "xfa/fxfa/parser/cxfa_plaintextmetadata.h"
257 #include "xfa/fxfa/parser/cxfa_presence.h"
258 #include "xfa/fxfa/parser/cxfa_present.h"
259 #include "xfa/fxfa/parser/cxfa_print.h"
260 #include "xfa/fxfa/parser/cxfa_printername.h"
261 #include "xfa/fxfa/parser/cxfa_printhighquality.h"
262 #include "xfa/fxfa/parser/cxfa_printscaling.h"
263 #include "xfa/fxfa/parser/cxfa_producer.h"
264 #include "xfa/fxfa/parser/cxfa_proto.h"
265 #include "xfa/fxfa/parser/cxfa_ps.h"
266 #include "xfa/fxfa/parser/cxfa_psmap.h"
267 #include "xfa/fxfa/parser/cxfa_query.h"
268 #include "xfa/fxfa/parser/cxfa_radial.h"
269 #include "xfa/fxfa/parser/cxfa_range.h"
270 #include "xfa/fxfa/parser/cxfa_reason.h"
271 #include "xfa/fxfa/parser/cxfa_reasons.h"
272 #include "xfa/fxfa/parser/cxfa_record.h"
273 #include "xfa/fxfa/parser/cxfa_recordset.h"
274 #include "xfa/fxfa/parser/cxfa_rectangle.h"
275 #include "xfa/fxfa/parser/cxfa_ref.h"
276 #include "xfa/fxfa/parser/cxfa_relevant.h"
277 #include "xfa/fxfa/parser/cxfa_rename.h"
278 #include "xfa/fxfa/parser/cxfa_renderpolicy.h"
279 #include "xfa/fxfa/parser/cxfa_rootelement.h"
280 #include "xfa/fxfa/parser/cxfa_runscripts.h"
281 #include "xfa/fxfa/parser/cxfa_script.h"
282 #include "xfa/fxfa/parser/cxfa_scriptmodel.h"
283 #include "xfa/fxfa/parser/cxfa_select.h"
284 #include "xfa/fxfa/parser/cxfa_setproperty.h"
285 #include "xfa/fxfa/parser/cxfa_severity.h"
286 #include "xfa/fxfa/parser/cxfa_sharptext.h"
287 #include "xfa/fxfa/parser/cxfa_sharpxhtml.h"
288 #include "xfa/fxfa/parser/cxfa_sharpxml.h"
289 #include "xfa/fxfa/parser/cxfa_signature.h"
290 #include "xfa/fxfa/parser/cxfa_signatureproperties.h"
291 #include "xfa/fxfa/parser/cxfa_signdata.h"
292 #include "xfa/fxfa/parser/cxfa_signing.h"
293 #include "xfa/fxfa/parser/cxfa_silentprint.h"
294 #include "xfa/fxfa/parser/cxfa_soapaction.h"
295 #include "xfa/fxfa/parser/cxfa_soapaddress.h"
296 #include "xfa/fxfa/parser/cxfa_solid.h"
297 #include "xfa/fxfa/parser/cxfa_source.h"
298 #include "xfa/fxfa/parser/cxfa_sourceset.h"
299 #include "xfa/fxfa/parser/cxfa_speak.h"
300 #include "xfa/fxfa/parser/cxfa_staple.h"
301 #include "xfa/fxfa/parser/cxfa_startnode.h"
302 #include "xfa/fxfa/parser/cxfa_startpage.h"
303 #include "xfa/fxfa/parser/cxfa_stipple.h"
304 #include "xfa/fxfa/parser/cxfa_stroke.h"
305 #include "xfa/fxfa/parser/cxfa_subform.h"
306 #include "xfa/fxfa/parser/cxfa_subformset.h"
307 #include "xfa/fxfa/parser/cxfa_subjectdn.h"
308 #include "xfa/fxfa/parser/cxfa_subjectdns.h"
309 #include "xfa/fxfa/parser/cxfa_submit.h"
310 #include "xfa/fxfa/parser/cxfa_submitformat.h"
311 #include "xfa/fxfa/parser/cxfa_submiturl.h"
312 #include "xfa/fxfa/parser/cxfa_subsetbelow.h"
313 #include "xfa/fxfa/parser/cxfa_suppressbanner.h"
314 #include "xfa/fxfa/parser/cxfa_tagged.h"
315 #include "xfa/fxfa/parser/cxfa_template.h"
316 #include "xfa/fxfa/parser/cxfa_templatecache.h"
317 #include "xfa/fxfa/parser/cxfa_text.h"
318 #include "xfa/fxfa/parser/cxfa_textedit.h"
319 #include "xfa/fxfa/parser/cxfa_threshold.h"
320 #include "xfa/fxfa/parser/cxfa_time.h"
321 #include "xfa/fxfa/parser/cxfa_timepattern.h"
322 #include "xfa/fxfa/parser/cxfa_timepatterns.h"
323 #include "xfa/fxfa/parser/cxfa_timestamp.h"
324 #include "xfa/fxfa/parser/cxfa_to.h"
325 #include "xfa/fxfa/parser/cxfa_tooltip.h"
326 #include "xfa/fxfa/parser/cxfa_trace.h"
327 #include "xfa/fxfa/parser/cxfa_transform.h"
328 #include "xfa/fxfa/parser/cxfa_traversal.h"
329 #include "xfa/fxfa/parser/cxfa_traverse.h"
330 #include "xfa/fxfa/parser/cxfa_traversestrategy_xfacontainernode.h"
331 #include "xfa/fxfa/parser/cxfa_traversestrategy_xfanode.h"
332 #include "xfa/fxfa/parser/cxfa_type.h"
333 #include "xfa/fxfa/parser/cxfa_typeface.h"
334 #include "xfa/fxfa/parser/cxfa_typefaces.h"
335 #include "xfa/fxfa/parser/cxfa_ui.h"
336 #include "xfa/fxfa/parser/cxfa_update.h"
337 #include "xfa/fxfa/parser/cxfa_uri.h"
338 #include "xfa/fxfa/parser/cxfa_user.h"
339 #include "xfa/fxfa/parser/cxfa_validate.h"
340 #include "xfa/fxfa/parser/cxfa_validateapprovalsignatures.h"
341 #include "xfa/fxfa/parser/cxfa_validationmessaging.h"
342 #include "xfa/fxfa/parser/cxfa_value.h"
343 #include "xfa/fxfa/parser/cxfa_variables.h"
344 #include "xfa/fxfa/parser/cxfa_version.h"
345 #include "xfa/fxfa/parser/cxfa_versioncontrol.h"
346 #include "xfa/fxfa/parser/cxfa_viewerpreferences.h"
347 #include "xfa/fxfa/parser/cxfa_webclient.h"
348 #include "xfa/fxfa/parser/cxfa_whitespace.h"
349 #include "xfa/fxfa/parser/cxfa_window.h"
350 #include "xfa/fxfa/parser/cxfa_wsdladdress.h"
351 #include "xfa/fxfa/parser/cxfa_wsdlconnection.h"
352 #include "xfa/fxfa/parser/cxfa_xdc.h"
353 #include "xfa/fxfa/parser/cxfa_xdp.h"
354 #include "xfa/fxfa/parser/cxfa_xfa.h"
355 #include "xfa/fxfa/parser/cxfa_xmlconnection.h"
356 #include "xfa/fxfa/parser/cxfa_xsdconnection.h"
357 #include "xfa/fxfa/parser/cxfa_xsl.h"
358 #include "xfa/fxfa/parser/cxfa_zpl.h"
359 #include "xfa/fxfa/parser/xfa_basic_data.h"
360 #include "xfa/fxfa/parser/xfa_utils.h"
361 
362 class CXFA_FieldLayoutData;
363 class CXFA_ImageEditData;
364 class CXFA_ImageLayoutData;
365 class CXFA_TextEditData;
366 class CXFA_TextLayoutData;
367 
368 namespace {
369 
370 constexpr uint8_t kMaxExecuteRecursion = 2;
371 
372 constexpr uint8_t g_inv_base64[128] = {
373     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
374     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
375     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62,  255,
376     255, 255, 63,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  255, 255,
377     255, 255, 255, 255, 255, 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
378     10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
379     25,  255, 255, 255, 255, 255, 255, 26,  27,  28,  29,  30,  31,  32,  33,
380     34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
381     49,  50,  51,  255, 255, 255, 255, 255,
382 };
383 
GetInvBase64(uint8_t x)384 inline uint8_t GetInvBase64(uint8_t x) {
385   return (x & 128) == 0 ? g_inv_base64[x] : 255;
386 }
387 
XFA_RemoveBase64Whitespace(pdfium::span<const uint8_t> spStr)388 std::vector<uint8_t, FxAllocAllocator<uint8_t>> XFA_RemoveBase64Whitespace(
389     pdfium::span<const uint8_t> spStr) {
390   std::vector<uint8_t, FxAllocAllocator<uint8_t>> result;
391   result.reserve(spStr.size());
392   for (uint8_t ch : spStr) {
393     if (GetInvBase64(ch) != 255 || ch == '=')
394       result.push_back(ch);
395   }
396   return result;
397 }
398 
XFA_Base64Decode(const ByteString & bsStr)399 std::vector<uint8_t, FxAllocAllocator<uint8_t>> XFA_Base64Decode(
400     const ByteString& bsStr) {
401   std::vector<uint8_t, FxAllocAllocator<uint8_t>> result;
402   if (bsStr.IsEmpty())
403     return result;
404 
405   std::vector<uint8_t, FxAllocAllocator<uint8_t>> buffer =
406       XFA_RemoveBase64Whitespace(bsStr.raw_span());
407   result.reserve(3 * (buffer.size() / 4));
408 
409   uint32_t dwLimb = 0;
410   for (size_t i = 0; i + 3 < buffer.size(); i += 4) {
411     if (buffer[i] == '=' || buffer[i + 1] == '=' || buffer[i + 2] == '=' ||
412         buffer[i + 3] == '=') {
413       if (buffer[i] == '=' || buffer[i + 1] == '=') {
414         break;
415       }
416       if (buffer[i + 2] == '=') {
417         dwLimb = ((uint32_t)g_inv_base64[buffer[i]] << 6) |
418                  ((uint32_t)g_inv_base64[buffer[i + 1]]);
419         result.push_back((uint8_t)(dwLimb >> 4) & 0xFF);
420       } else {
421         dwLimb = ((uint32_t)g_inv_base64[buffer[i]] << 12) |
422                  ((uint32_t)g_inv_base64[buffer[i + 1]] << 6) |
423                  ((uint32_t)g_inv_base64[buffer[i + 2]]);
424         result.push_back((uint8_t)(dwLimb >> 10) & 0xFF);
425         result.push_back((uint8_t)(dwLimb >> 2) & 0xFF);
426       }
427     } else {
428       dwLimb = ((uint32_t)g_inv_base64[buffer[i]] << 18) |
429                ((uint32_t)g_inv_base64[buffer[i + 1]] << 12) |
430                ((uint32_t)g_inv_base64[buffer[i + 2]] << 6) |
431                ((uint32_t)g_inv_base64[buffer[i + 3]]);
432       result.push_back((uint8_t)(dwLimb >> 16) & 0xff);
433       result.push_back((uint8_t)(dwLimb >> 8) & 0xff);
434       result.push_back((uint8_t)(dwLimb)&0xff);
435     }
436   }
437   return result;
438 }
439 
XFA_GetImageType(const WideString & wsType)440 FXCODEC_IMAGE_TYPE XFA_GetImageType(const WideString& wsType) {
441   WideString wsContentType(wsType);
442   if (wsContentType.EqualsASCIINoCase("image/jpg"))
443     return FXCODEC_IMAGE_JPG;
444 
445 #ifdef PDF_ENABLE_XFA_BMP
446   if (wsContentType.EqualsASCIINoCase("image/bmp"))
447     return FXCODEC_IMAGE_BMP;
448 #endif  // PDF_ENABLE_XFA_BMP
449 
450 #ifdef PDF_ENABLE_XFA_GIF
451   if (wsContentType.EqualsASCIINoCase("image/gif"))
452     return FXCODEC_IMAGE_GIF;
453 #endif  // PDF_ENABLE_XFA_GIF
454 
455 #ifdef PDF_ENABLE_XFA_PNG
456   if (wsContentType.EqualsASCIINoCase("image/png"))
457     return FXCODEC_IMAGE_PNG;
458 #endif  // PDF_ENABLE_XFA_PNG
459 
460 #ifdef PDF_ENABLE_XFA_TIFF
461   if (wsContentType.EqualsASCII("image/tif"))
462     return FXCODEC_IMAGE_TIFF;
463 #endif  // PDF_ENABLE_XFA_TIFF
464 
465   return FXCODEC_IMAGE_UNKNOWN;
466 }
467 
XFA_LoadImageData(CXFA_FFDoc * pDoc,CXFA_Image * pImage,bool & bNameImage,int32_t & iImageXDpi,int32_t & iImageYDpi)468 RetainPtr<CFX_DIBitmap> XFA_LoadImageData(CXFA_FFDoc* pDoc,
469                                           CXFA_Image* pImage,
470                                           bool& bNameImage,
471                                           int32_t& iImageXDpi,
472                                           int32_t& iImageYDpi) {
473   WideString wsHref = pImage->GetHref();
474   WideString wsImage = pImage->GetContent();
475   if (wsHref.IsEmpty() && wsImage.IsEmpty())
476     return nullptr;
477 
478   FXCODEC_IMAGE_TYPE type = XFA_GetImageType(pImage->GetContentType());
479   ByteString bsData;  // Must outlive |pImageFileRead|.
480 
481   // Must outlive |pImageFileRead|.
482   std::vector<uint8_t, FxAllocAllocator<uint8_t>> buffer;
483 
484   RetainPtr<IFX_SeekableReadStream> pImageFileRead;
485   if (wsImage.GetLength() > 0) {
486     XFA_AttributeValue iEncoding = pImage->GetTransferEncoding();
487     if (iEncoding == XFA_AttributeValue::Base64) {
488       bsData = wsImage.ToUTF8();
489       buffer = XFA_Base64Decode(bsData);
490       if (!buffer.empty())
491         pImageFileRead = pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(buffer);
492     } else {
493       bsData = wsImage.ToDefANSI();
494       pImageFileRead =
495           pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(bsData.raw_span());
496     }
497   } else {
498     WideString wsURL = wsHref;
499     if (!(wsURL.First(7).EqualsASCII("http://") ||
500           wsURL.First(6).EqualsASCII("ftp://"))) {
501       RetainPtr<CFX_DIBitmap> pBitmap =
502           pDoc->GetPDFNamedImage(wsURL.AsStringView(), iImageXDpi, iImageYDpi);
503       if (pBitmap) {
504         bNameImage = true;
505         return pBitmap;
506       }
507     }
508     pImageFileRead = pDoc->OpenLinkedFile(wsURL);
509   }
510   if (!pImageFileRead)
511     return nullptr;
512 
513   bNameImage = false;
514   RetainPtr<CFX_DIBitmap> pBitmap =
515       XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
516   return pBitmap;
517 }
518 
SplitDateTime(const WideString & wsDateTime,WideString & wsDate,WideString & wsTime)519 bool SplitDateTime(const WideString& wsDateTime,
520                    WideString& wsDate,
521                    WideString& wsTime) {
522   wsDate.clear();
523   wsTime.clear();
524   if (wsDateTime.IsEmpty())
525     return false;
526 
527   auto nSplitIndex = wsDateTime.Find('T');
528   if (!nSplitIndex.has_value())
529     nSplitIndex = wsDateTime.Find(' ');
530   if (!nSplitIndex.has_value())
531     return false;
532 
533   wsDate = wsDateTime.First(nSplitIndex.value());
534   if (!wsDate.IsEmpty()) {
535     if (!std::any_of(wsDate.begin(), wsDate.end(),
536                      [](wchar_t c) { return FXSYS_IsDecimalDigit(c); })) {
537       return false;
538     }
539   }
540   wsTime = wsDateTime.Last(wsDateTime.GetLength() - nSplitIndex.value() - 1);
541   if (!wsTime.IsEmpty()) {
542     if (!std::any_of(wsTime.begin(), wsTime.end(),
543                      [](wchar_t c) { return FXSYS_IsDecimalDigit(c); })) {
544       return false;
545     }
546   }
547   return true;
548 }
549 
550 // Stack allocated. Using containers of members would be correct here
551 // if advanced GC worked with STL.
552 using NodeSet = std::set<cppgc::Member<CXFA_Node>>;
553 using NodeSetPair = std::pair<NodeSet, NodeSet>;
554 using NodeSetPairMap = std::map<uint32_t, NodeSetPair>;
555 using NodeSetPairMapMap = std::map<CXFA_Node*, NodeSetPairMap>;
556 using NodeVector = std::vector<cppgc::Member<CXFA_Node>>;
557 
NodesSortedByDocumentIdx(const NodeSet & rgNodeSet)558 NodeVector NodesSortedByDocumentIdx(const NodeSet& rgNodeSet) {
559   if (rgNodeSet.empty())
560     return NodeVector();
561 
562   NodeVector rgNodeArray;
563   CXFA_Node* pCommonParent = (*rgNodeSet.begin())->GetParent();
564   for (CXFA_Node* pNode = pCommonParent->GetFirstChild(); pNode;
565        pNode = pNode->GetNextSibling()) {
566     if (pdfium::Contains(rgNodeSet, pNode))
567       rgNodeArray.push_back(pNode);
568   }
569   return rgNodeArray;
570 }
571 
NodeSetPairForNode(CXFA_Node * pNode,NodeSetPairMapMap * pMap)572 NodeSetPair* NodeSetPairForNode(CXFA_Node* pNode, NodeSetPairMapMap* pMap) {
573   CXFA_Node* pParentNode = pNode->GetParent();
574   uint32_t dwNameHash = pNode->GetNameHash();
575   if (!pParentNode || !dwNameHash)
576     return nullptr;
577 
578   return &((*pMap)[pParentNode][dwNameHash]);
579 }
580 
ReorderDataNodes(const NodeSet & sSet1,const NodeSet & sSet2,bool bInsertBefore)581 void ReorderDataNodes(const NodeSet& sSet1,
582                       const NodeSet& sSet2,
583                       bool bInsertBefore) {
584   NodeSetPairMapMap rgMap;
585   for (CXFA_Node* pNode : sSet1) {
586     NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
587     if (pNodeSetPair)
588       pNodeSetPair->first.insert(pNode);
589   }
590   for (CXFA_Node* pNode : sSet2) {
591     NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
592     if (pNodeSetPair) {
593       if (pdfium::Contains(pNodeSetPair->first, pNode))
594         pNodeSetPair->first.erase(pNode);
595       else
596         pNodeSetPair->second.insert(pNode);
597     }
598   }
599   for (auto& iter1 : rgMap) {
600     NodeSetPairMap* pNodeSetPairMap = &iter1.second;
601     for (auto& iter2 : *pNodeSetPairMap) {
602       NodeSetPair* pNodeSetPair = &iter2.second;
603       if (!pNodeSetPair->first.empty() && !pNodeSetPair->second.empty()) {
604         NodeVector rgNodeArray1 = NodesSortedByDocumentIdx(pNodeSetPair->first);
605         NodeVector rgNodeArray2 =
606             NodesSortedByDocumentIdx(pNodeSetPair->second);
607         CXFA_Node* pParentNode = nullptr;
608         CXFA_Node* pBeforeNode = nullptr;
609         if (bInsertBefore) {
610           pBeforeNode = rgNodeArray2.front();
611           pParentNode = pBeforeNode->GetParent();
612         } else {
613           CXFA_Node* pLastNode = rgNodeArray2.back();
614           pParentNode = pLastNode->GetParent();
615           pBeforeNode = pLastNode->GetNextSibling();
616         }
617         for (auto& pCurNode : rgNodeArray1) {
618           pParentNode->RemoveChildAndNotify(pCurNode, true);
619           pParentNode->InsertChildAndNotify(pCurNode, pBeforeNode);
620         }
621       }
622     }
623     pNodeSetPairMap->clear();
624   }
625 }
626 
GetEdgeThickness(const std::vector<CXFA_Stroke * > & strokes,bool b3DStyle,int32_t nIndex)627 float GetEdgeThickness(const std::vector<CXFA_Stroke*>& strokes,
628                        bool b3DStyle,
629                        int32_t nIndex) {
630   float fThickness = 0.0f;
631   CXFA_Stroke* stroke = strokes[nIndex * 2 + 1];
632   if (stroke->IsVisible()) {
633     if (nIndex == 0)
634       fThickness += 2.5f;
635 
636     fThickness += stroke->GetThickness() * (b3DStyle ? 4 : 2);
637   }
638   return fThickness;
639 }
640 
FormatNumStr(const WideString & wsValue,LocaleIface * pLocale)641 WideString FormatNumStr(const WideString& wsValue, LocaleIface* pLocale) {
642   if (wsValue.IsEmpty())
643     return WideString();
644 
645   WideString wsSrcNum = wsValue;
646   WideString wsGroupSymbol = pLocale->GetGroupingSymbol();
647   bool bNeg = false;
648   if (wsSrcNum[0] == '-') {
649     bNeg = true;
650     wsSrcNum.Delete(0, 1);
651   }
652 
653   auto dot_index = wsSrcNum.Find('.');
654   dot_index = !dot_index.has_value() ? wsSrcNum.GetLength() : dot_index;
655 
656   if (dot_index.value() < 1)
657     return WideString();
658 
659   size_t nPos = dot_index.value() % 3;
660   WideString wsOutput;
661   for (size_t i = 0; i < dot_index.value(); i++) {
662     if (i % 3 == nPos && i != 0)
663       wsOutput += wsGroupSymbol;
664 
665     wsOutput += wsSrcNum[i];
666   }
667   if (dot_index.value() < wsSrcNum.GetLength()) {
668     wsOutput += pLocale->GetDecimalSymbol();
669     wsOutput += wsSrcNum.Last(wsSrcNum.GetLength() - dot_index.value() - 1);
670   }
671   if (bNeg)
672     return pLocale->GetMinusSymbol() + wsOutput;
673 
674   return wsOutput;
675 }
676 
677 CXFA_Node* FindFirstSiblingNamedInList(CXFA_Node* parent,
678                                        uint32_t dwNameHash,
679                                        uint32_t dwFilter);
680 CXFA_Node* FindFirstSiblingOfClassInList(CXFA_Node* parent,
681                                          XFA_Element element,
682                                          uint32_t dwFilter);
683 
FindFirstSiblingNamed(CXFA_Node * parent,uint32_t dwNameHash)684 CXFA_Node* FindFirstSiblingNamed(CXFA_Node* parent, uint32_t dwNameHash) {
685   CXFA_Node* result = FindFirstSiblingNamedInList(parent, dwNameHash,
686                                                   XFA_NODEFILTER_Properties);
687   if (result)
688     return result;
689 
690   return FindFirstSiblingNamedInList(parent, dwNameHash,
691                                      XFA_NODEFILTER_Children);
692 }
693 
FindFirstSiblingNamedInList(CXFA_Node * parent,uint32_t dwNameHash,uint32_t dwFilter)694 CXFA_Node* FindFirstSiblingNamedInList(CXFA_Node* parent,
695                                        uint32_t dwNameHash,
696                                        uint32_t dwFilter) {
697   for (CXFA_Node* child : parent->GetNodeListWithFilter(dwFilter)) {
698     if (child->GetNameHash() == dwNameHash)
699       return child;
700 
701     CXFA_Node* result = FindFirstSiblingNamed(child, dwNameHash);
702     if (result)
703       return result;
704   }
705   return nullptr;
706 }
707 
FindFirstSiblingOfClass(CXFA_Node * parent,XFA_Element element)708 CXFA_Node* FindFirstSiblingOfClass(CXFA_Node* parent, XFA_Element element) {
709   CXFA_Node* result =
710       FindFirstSiblingOfClassInList(parent, element, XFA_NODEFILTER_Properties);
711   if (result)
712     return result;
713 
714   return FindFirstSiblingOfClassInList(parent, element,
715                                        XFA_NODEFILTER_Children);
716 }
717 
FindFirstSiblingOfClassInList(CXFA_Node * parent,XFA_Element element,uint32_t dwFilter)718 CXFA_Node* FindFirstSiblingOfClassInList(CXFA_Node* parent,
719                                          XFA_Element element,
720                                          uint32_t dwFilter) {
721   for (CXFA_Node* child : parent->GetNodeListWithFilter(dwFilter)) {
722     if (child->GetElementType() == element)
723       return child;
724 
725     CXFA_Node* result = FindFirstSiblingOfClass(child, element);
726     if (result)
727       return result;
728   }
729   return nullptr;
730 }
731 
GetNameExpressionSinglePath(CXFA_Node * pNode)732 WideString GetNameExpressionSinglePath(CXFA_Node* pNode) {
733   const bool bIsProperty = pNode->IsProperty();
734   const bool bIsClassIndex =
735       pNode->IsUnnamed() ||
736       (bIsProperty && pNode->GetElementType() != XFA_Element::PageSet);
737   const wchar_t* pszFormat;
738   WideString ws;
739   if (bIsClassIndex) {
740     pszFormat = L"#%ls[%zu]";
741     ws = WideString::FromASCII(pNode->GetClassName());
742   } else {
743     pszFormat = L"%ls[%zu]";
744     ws = pNode->JSObject()->GetCData(XFA_Attribute::Name);
745     ws.Replace(L".", L"\\.");
746   }
747 
748   return WideString::Format(pszFormat, ws.c_str(),
749                             pNode->GetIndex(bIsProperty, bIsClassIndex));
750 }
751 
TraverseSiblings(CXFA_Node * parent,uint32_t dwNameHash,std::vector<CXFA_Node * > * pSiblings,bool bIsClassName,bool bIsFindProperty)752 void TraverseSiblings(CXFA_Node* parent,
753                       uint32_t dwNameHash,
754                       std::vector<CXFA_Node*>* pSiblings,
755                       bool bIsClassName,
756                       bool bIsFindProperty) {
757   DCHECK(parent);
758   DCHECK(pSiblings);
759 
760   if (bIsFindProperty) {
761     for (CXFA_Node* child :
762          parent->GetNodeListWithFilter(XFA_NODEFILTER_Properties)) {
763       if (bIsClassName) {
764         if (child->GetClassHashCode() == dwNameHash)
765           pSiblings->push_back(child);
766       } else {
767         if (child->GetNameHash() == dwNameHash) {
768           if (child->GetElementType() != XFA_Element::PageSet &&
769               child->GetElementType() != XFA_Element::Extras &&
770               child->GetElementType() != XFA_Element::Items) {
771             pSiblings->push_back(child);
772           }
773         }
774       }
775       if (child->IsUnnamed() &&
776           child->GetElementType() == XFA_Element::PageSet) {
777         TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false);
778       }
779     }
780     if (!pSiblings->empty())
781       return;
782   }
783   for (CXFA_Node* child :
784        parent->GetNodeListWithFilter(XFA_NODEFILTER_Children)) {
785     if (child->GetElementType() == XFA_Element::Variables)
786       continue;
787 
788     if (bIsClassName) {
789       if (child->GetClassHashCode() == dwNameHash)
790         pSiblings->push_back(child);
791     } else {
792       if (child->GetNameHash() == dwNameHash)
793         pSiblings->push_back(child);
794     }
795 
796     if (child->IsTransparent() &&
797         child->GetElementType() != XFA_Element::PageSet) {
798       TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false);
799     }
800   }
801 }
802 
803 }  // namespace
804 
805 class CXFA_WidgetLayoutData
806     : public cppgc::GarbageCollected<CXFA_WidgetLayoutData> {
807  public:
808   CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
809   virtual ~CXFA_WidgetLayoutData() = default;
810 
Trace(cppgc::Visitor * visitor) const811   virtual void Trace(cppgc::Visitor* visitor) const {}
812 
AsFieldLayoutData()813   virtual CXFA_FieldLayoutData* AsFieldLayoutData() { return nullptr; }
AsImageLayoutData()814   virtual CXFA_ImageLayoutData* AsImageLayoutData() { return nullptr; }
AsTextLayoutData()815   virtual CXFA_TextLayoutData* AsTextLayoutData() { return nullptr; }
816 
817   float m_fWidgetHeight = -1.0f;
818 
819  protected:
820   CXFA_WidgetLayoutData() = default;
821 };
822 
823 class CXFA_TextLayoutData final : public CXFA_WidgetLayoutData {
824  public:
825   CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
826   ~CXFA_TextLayoutData() override = default;
827 
Trace(cppgc::Visitor * visitor) const828   void Trace(cppgc::Visitor* visitor) const override {
829     CXFA_WidgetLayoutData::Trace(visitor);
830     visitor->Trace(m_pTextLayout);
831     visitor->Trace(m_pTextProvider);
832   }
833 
AsTextLayoutData()834   CXFA_TextLayoutData* AsTextLayoutData() override { return this; }
835 
GetTextLayout() const836   CXFA_TextLayout* GetTextLayout() const { return m_pTextLayout; }
GetTextProvider() const837   CXFA_TextProvider* GetTextProvider() const { return m_pTextProvider; }
838 
LoadText(CXFA_FFDoc * doc,CXFA_Node * pNode)839   void LoadText(CXFA_FFDoc* doc, CXFA_Node* pNode) {
840     if (m_pTextLayout)
841       return;
842 
843     m_pTextProvider = cppgc::MakeGarbageCollected<CXFA_TextProvider>(
844         doc->GetHeap()->GetAllocationHandle(), pNode,
845         XFA_TEXTPROVIDERTYPE_Text);
846     m_pTextLayout = cppgc::MakeGarbageCollected<CXFA_TextLayout>(
847         doc->GetHeap()->GetAllocationHandle(), doc, m_pTextProvider);
848   }
849 
850  private:
851   CXFA_TextLayoutData() = default;
852 
853   cppgc::Member<CXFA_TextLayout> m_pTextLayout;
854   cppgc::Member<CXFA_TextProvider> m_pTextProvider;
855 };
856 
857 class CXFA_ImageLayoutData final : public CXFA_WidgetLayoutData {
858  public:
859   CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
860   ~CXFA_ImageLayoutData() override = default;
861 
AsImageLayoutData()862   CXFA_ImageLayoutData* AsImageLayoutData() override { return this; }
863 
LoadImageData(CXFA_FFDoc * doc,CXFA_Node * pNode)864   bool LoadImageData(CXFA_FFDoc* doc, CXFA_Node* pNode) {
865     if (m_pDIBitmap)
866       return true;
867 
868     CXFA_Value* value = pNode->GetFormValueIfExists();
869     if (!value)
870       return false;
871 
872     CXFA_Image* image = value->GetImageIfExists();
873     if (!image)
874       return false;
875 
876     pNode->SetImageImage(XFA_LoadImageData(doc, image, m_bNamedImage,
877                                            m_iImageXDpi, m_iImageYDpi));
878     return !!m_pDIBitmap;
879   }
880 
881   bool m_bNamedImage = false;
882   int32_t m_iImageXDpi = 0;
883   int32_t m_iImageYDpi = 0;
884   RetainPtr<CFX_DIBitmap> m_pDIBitmap;
885 
886  private:
887   CXFA_ImageLayoutData() = default;
888 };
889 
890 class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData {
891  public:
892   CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
893   ~CXFA_FieldLayoutData() override = default;
894 
Trace(cppgc::Visitor * visitor) const895   void Trace(cppgc::Visitor* visitor) const override {
896     CXFA_WidgetLayoutData::Trace(visitor);
897     visitor->Trace(m_pCapTextLayout);
898     visitor->Trace(m_pCapTextProvider);
899   }
AsFieldLayoutData()900   CXFA_FieldLayoutData* AsFieldLayoutData() override { return this; }
901 
AsImageEditData()902   virtual CXFA_ImageEditData* AsImageEditData() { return nullptr; }
AsTextEditData()903   virtual CXFA_TextEditData* AsTextEditData() { return nullptr; }
904 
LoadCaption(CXFA_FFDoc * doc,CXFA_Node * pNode)905   bool LoadCaption(CXFA_FFDoc* doc, CXFA_Node* pNode) {
906     if (m_pCapTextLayout)
907       return true;
908     CXFA_Caption* caption = pNode->GetCaptionIfExists();
909     if (!caption || caption->IsHidden())
910       return false;
911 
912     m_pCapTextProvider = cppgc::MakeGarbageCollected<CXFA_TextProvider>(
913         doc->GetHeap()->GetAllocationHandle(), pNode,
914         XFA_TEXTPROVIDERTYPE_Caption);
915     m_pCapTextLayout = cppgc::MakeGarbageCollected<CXFA_TextLayout>(
916         doc->GetHeap()->GetAllocationHandle(), doc, m_pCapTextProvider);
917     return true;
918   }
919 
920   cppgc::Member<CXFA_TextLayout> m_pCapTextLayout;
921   cppgc::Member<CXFA_TextProvider> m_pCapTextProvider;
922   std::unique_ptr<CFDE_TextOut> m_pTextOut;
923   std::vector<float> m_FieldSplitArray;
924 
925  protected:
926   CXFA_FieldLayoutData() = default;
927 };
928 
929 class CXFA_TextEditData final : public CXFA_FieldLayoutData {
930  public:
931   CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
932   ~CXFA_TextEditData() override = default;
933 
AsTextEditData()934   CXFA_TextEditData* AsTextEditData() override { return this; }
935 
936  protected:
937   CXFA_TextEditData() = default;
938 };
939 
940 class CXFA_ImageEditData final : public CXFA_FieldLayoutData {
941  public:
942   CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
943   ~CXFA_ImageEditData() override = default;
944 
AsImageEditData()945   CXFA_ImageEditData* AsImageEditData() override { return this; }
946 
LoadImageData(CXFA_FFDoc * doc,CXFA_Node * pNode)947   bool LoadImageData(CXFA_FFDoc* doc, CXFA_Node* pNode) {
948     if (m_pDIBitmap)
949       return true;
950 
951     CXFA_Value* value = pNode->GetFormValueIfExists();
952     if (!value)
953       return false;
954 
955     CXFA_Image* image = value->GetImageIfExists();
956     if (!image)
957       return false;
958 
959     pNode->SetImageEditImage(XFA_LoadImageData(doc, image, m_bNamedImage,
960                                                m_iImageXDpi, m_iImageYDpi));
961     return !!m_pDIBitmap;
962   }
963 
964   bool m_bNamedImage = false;
965   int32_t m_iImageXDpi = 0;
966   int32_t m_iImageYDpi = 0;
967   RetainPtr<CFX_DIBitmap> m_pDIBitmap;
968 
969  private:
970   CXFA_ImageEditData() = default;
971 };
972 
CXFA_Node(CXFA_Document * pDoc,XFA_PacketType ePacket,uint32_t validPackets,XFA_ObjectType oType,XFA_Element eType,pdfium::span<const PropertyData> properties,pdfium::span<const AttributeData> attributes,CJX_Object * js_object)973 CXFA_Node::CXFA_Node(CXFA_Document* pDoc,
974                      XFA_PacketType ePacket,
975                      uint32_t validPackets,
976                      XFA_ObjectType oType,
977                      XFA_Element eType,
978                      pdfium::span<const PropertyData> properties,
979                      pdfium::span<const AttributeData> attributes,
980                      CJX_Object* js_object)
981     : CXFA_Object(pDoc, oType, eType, js_object),
982       m_Properties(properties),
983       m_Attributes(attributes),
984       m_ValidPackets(validPackets),
985       m_ePacket(ePacket) {
986   DCHECK(m_pDocument);
987 }
988 
989 CXFA_Node::~CXFA_Node() = default;
990 
Trace(cppgc::Visitor * visitor) const991 void CXFA_Node::Trace(cppgc::Visitor* visitor) const {
992   CXFA_Object::Trace(visitor);
993   GCedTreeNodeMixin<CXFA_Node>::Trace(visitor);
994   visitor->Trace(m_pAuxNode);
995   ContainerTrace(visitor, binding_nodes_);
996   visitor->Trace(m_pLayoutData);
997   visitor->Trace(ui_);
998 }
999 
Clone(bool bRecursive)1000 CXFA_Node* CXFA_Node::Clone(bool bRecursive) {
1001   CXFA_Node* pClone = m_pDocument->CreateNode(m_ePacket, m_elementType);
1002   if (!pClone)
1003     return nullptr;
1004 
1005   JSObject()->MergeAllData(pClone);
1006   pClone->UpdateNameHash();
1007   if (IsNeedSavingXMLNode()) {
1008     CFX_XMLNode* pCloneXML;
1009     if (IsAttributeInXML()) {
1010       WideString wsName = JSObject()
1011                               ->TryAttribute(XFA_Attribute::Name, false)
1012                               .value_or(WideString());
1013       auto* pCloneXMLElement =
1014           GetXMLDocument()->CreateNode<CFX_XMLElement>(wsName);
1015 
1016       WideString wsValue = JSObject()->GetCData(XFA_Attribute::Value);
1017       if (!wsValue.IsEmpty()) {
1018         auto* text = GetXMLDocument()->CreateNode<CFX_XMLText>(wsValue);
1019         pCloneXMLElement->AppendLastChild(text);
1020       }
1021 
1022       pCloneXML = pCloneXMLElement;
1023       pClone->JSObject()->SetEnum(XFA_Attribute::Contains,
1024                                   XFA_AttributeValue::Unknown, false);
1025     } else {
1026       pCloneXML = xml_node_->Clone(GetXMLDocument());
1027     }
1028     pClone->SetXMLMappingNode(pCloneXML);
1029   }
1030   if (bRecursive) {
1031     for (CXFA_Node* pChild = GetFirstChild(); pChild;
1032          pChild = pChild->GetNextSibling()) {
1033       pClone->InsertChildAndNotify(pChild->Clone(bRecursive), nullptr);
1034     }
1035   }
1036   pClone->SetFlagAndNotify(XFA_NodeFlag_Initialized);
1037   pClone->SetBindingNode(nullptr);
1038   return pClone;
1039 }
1040 
GetNextContainerSibling() const1041 CXFA_Node* CXFA_Node::GetNextContainerSibling() const {
1042   for (auto* pNode = GetNextSibling(); pNode; pNode = pNode->GetNextSibling()) {
1043     if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
1044       return pNode;
1045   }
1046   return nullptr;
1047 }
1048 
GetPrevContainerSibling() const1049 CXFA_Node* CXFA_Node::GetPrevContainerSibling() const {
1050   for (auto* pNode = GetPrevSibling(); pNode; pNode = pNode->GetPrevSibling()) {
1051     if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
1052       return pNode;
1053   }
1054   return nullptr;
1055 }
1056 
GetFirstContainerChild() const1057 CXFA_Node* CXFA_Node::GetFirstContainerChild() const {
1058   for (auto* pNode = GetFirstChild(); pNode; pNode = pNode->GetNextSibling()) {
1059     if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
1060       return pNode;
1061   }
1062   return nullptr;
1063 }
1064 
GetContainerParent() const1065 CXFA_Node* CXFA_Node::GetContainerParent() const {
1066   for (auto* pNode = GetParent(); pNode; pNode = pNode->GetParent()) {
1067     if (pNode->GetObjectType() == XFA_ObjectType::ContainerNode)
1068       return pNode;
1069   }
1070   return nullptr;
1071 }
1072 
IsValidInPacket(XFA_PacketType packet) const1073 bool CXFA_Node::IsValidInPacket(XFA_PacketType packet) const {
1074   return !!(m_ValidPackets & (1 << static_cast<uint8_t>(packet)));
1075 }
1076 
GetPropertyData(XFA_Element property) const1077 const CXFA_Node::PropertyData* CXFA_Node::GetPropertyData(
1078     XFA_Element property) const {
1079   DCHECK(property != XFA_Element::Unknown);
1080   for (const auto& prop : m_Properties) {
1081     if (prop.property == property)
1082       return &prop;
1083   }
1084   return nullptr;
1085 }
1086 
HasProperty(XFA_Element property) const1087 bool CXFA_Node::HasProperty(XFA_Element property) const {
1088   return !!GetPropertyData(property);
1089 }
1090 
HasPropertyFlags(XFA_Element property,uint8_t flags) const1091 bool CXFA_Node::HasPropertyFlags(XFA_Element property, uint8_t flags) const {
1092   const PropertyData* data = GetPropertyData(property);
1093   return data && !!(data->flags & flags);
1094 }
1095 
PropertyOccuranceCount(XFA_Element property) const1096 uint8_t CXFA_Node::PropertyOccuranceCount(XFA_Element property) const {
1097   const PropertyData* data = GetPropertyData(property);
1098   return data ? data->occurance_count : 0;
1099 }
1100 
GetProperty(int32_t index,XFA_Element eProperty) const1101 std::pair<CXFA_Node*, int32_t> CXFA_Node::GetProperty(
1102     int32_t index,
1103     XFA_Element eProperty) const {
1104   if (index < 0 || index >= PropertyOccuranceCount(eProperty))
1105     return {nullptr, 0};
1106 
1107   int32_t iCount = 0;
1108   for (CXFA_Node* pNode = GetFirstChild(); pNode;
1109        pNode = pNode->GetNextSibling()) {
1110     if (pNode->GetElementType() == eProperty) {
1111       iCount++;
1112       if (iCount > index)
1113         return {pNode, iCount};
1114     }
1115   }
1116   return {nullptr, iCount};
1117 }
1118 
GetOrCreateProperty(int32_t index,XFA_Element eProperty)1119 CXFA_Node* CXFA_Node::GetOrCreateProperty(int32_t index,
1120                                           XFA_Element eProperty) {
1121   if (index < 0 || index >= PropertyOccuranceCount(eProperty))
1122     return nullptr;
1123 
1124   int32_t iCount = 0;
1125   CXFA_Node* node;
1126   std::tie(node, iCount) = GetProperty(index, eProperty);
1127   if (node)
1128     return node;
1129 
1130   if (HasPropertyFlags(eProperty, XFA_PROPERTYFLAG_OneOf)) {
1131     for (CXFA_Node* pNode = GetFirstChild(); pNode;
1132          pNode = pNode->GetNextSibling()) {
1133       if (HasPropertyFlags(pNode->GetElementType(), XFA_PROPERTYFLAG_OneOf)) {
1134         return nullptr;
1135       }
1136     }
1137   }
1138 
1139   CXFA_Node* pNewNode = nullptr;
1140   for (; iCount <= index; ++iCount) {
1141     pNewNode = GetDocument()->CreateNode(GetPacketType(), eProperty);
1142     if (!pNewNode)
1143       return nullptr;
1144 
1145     InsertChildAndNotify(pNewNode, nullptr);
1146     pNewNode->SetFlagAndNotify(XFA_NodeFlag_Initialized);
1147   }
1148   return pNewNode;
1149 }
1150 
GetFirstPropertyWithFlag(uint8_t flag) const1151 Optional<XFA_Element> CXFA_Node::GetFirstPropertyWithFlag(uint8_t flag) const {
1152   for (const auto& prop : m_Properties) {
1153     if (prop.flags & flag)
1154       return prop.property;
1155   }
1156   return {};
1157 }
1158 
GetAttributeData(XFA_Attribute attr) const1159 const CXFA_Node::AttributeData* CXFA_Node::GetAttributeData(
1160     XFA_Attribute attr) const {
1161   DCHECK(attr != XFA_Attribute::Unknown);
1162   for (const auto& cur_attr : m_Attributes) {
1163     if (cur_attr.attribute == attr)
1164       return &cur_attr;
1165   }
1166   return nullptr;
1167 }
1168 
HasAttribute(XFA_Attribute attr) const1169 bool CXFA_Node::HasAttribute(XFA_Attribute attr) const {
1170   return !!GetAttributeData(attr);
1171 }
1172 
GetAttribute(size_t i) const1173 XFA_Attribute CXFA_Node::GetAttribute(size_t i) const {
1174   return i < m_Attributes.size() ? m_Attributes[i].attribute
1175                                  : XFA_Attribute::Unknown;
1176 }
1177 
GetAttributeType(XFA_Attribute type) const1178 XFA_AttributeType CXFA_Node::GetAttributeType(XFA_Attribute type) const {
1179   const AttributeData* data = GetAttributeData(type);
1180   return data ? data->type : XFA_AttributeType::CData;
1181 }
1182 
GetNodeListForType(XFA_Element eTypeFilter)1183 std::vector<CXFA_Node*> CXFA_Node::GetNodeListForType(XFA_Element eTypeFilter) {
1184   std::vector<CXFA_Node*> nodes;
1185   for (CXFA_Node* pChild = GetFirstChild(); pChild;
1186        pChild = pChild->GetNextSibling()) {
1187     if (pChild->GetElementType() == eTypeFilter)
1188       nodes.push_back(pChild);
1189   }
1190   return nodes;
1191 }
1192 
GetNodeListWithFilter(uint32_t dwTypeFilter)1193 std::vector<CXFA_Node*> CXFA_Node::GetNodeListWithFilter(
1194     uint32_t dwTypeFilter) {
1195   std::vector<CXFA_Node*> nodes;
1196   if (dwTypeFilter == (XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties)) {
1197     for (CXFA_Node* pChild = GetFirstChild(); pChild;
1198          pChild = pChild->GetNextSibling())
1199       nodes.push_back(pChild);
1200     return nodes;
1201   }
1202 
1203   if (dwTypeFilter == 0)
1204     return nodes;
1205 
1206   bool bFilterChildren = !!(dwTypeFilter & XFA_NODEFILTER_Children);
1207   bool bFilterProperties = !!(dwTypeFilter & XFA_NODEFILTER_Properties);
1208   bool bFilterOneOfProperties = !!(dwTypeFilter & XFA_NODEFILTER_OneOfProperty);
1209   for (CXFA_Node* pChild = GetFirstChild(); pChild;
1210        pChild = pChild->GetNextSibling()) {
1211     if (HasProperty(pChild->GetElementType())) {
1212       if (bFilterProperties) {
1213         nodes.push_back(pChild);
1214       } else if (bFilterOneOfProperties &&
1215                  HasPropertyFlags(pChild->GetElementType(),
1216                                   XFA_PROPERTYFLAG_OneOf)) {
1217         nodes.push_back(pChild);
1218       } else if (bFilterChildren &&
1219                  (pChild->GetElementType() == XFA_Element::Variables ||
1220                   pChild->GetElementType() == XFA_Element::PageSet)) {
1221         nodes.push_back(pChild);
1222       }
1223     } else if (bFilterChildren) {
1224       nodes.push_back(pChild);
1225     }
1226   }
1227 
1228   if (!bFilterOneOfProperties || !nodes.empty())
1229     return nodes;
1230 
1231   Optional<XFA_Element> property =
1232       GetFirstPropertyWithFlag(XFA_PROPERTYFLAG_DefaultOneOf);
1233   if (!property.has_value())
1234     return nodes;
1235 
1236   CXFA_Node* pNewNode =
1237       m_pDocument->CreateNode(GetPacketType(), property.value());
1238   if (pNewNode) {
1239     InsertChildAndNotify(pNewNode, nullptr);
1240     pNewNode->SetFlagAndNotify(XFA_NodeFlag_Initialized);
1241     nodes.push_back(pNewNode);
1242   }
1243   return nodes;
1244 }
1245 
CreateSamePacketNode(XFA_Element eType)1246 CXFA_Node* CXFA_Node::CreateSamePacketNode(XFA_Element eType) {
1247   CXFA_Node* pNode = m_pDocument->CreateNode(m_ePacket, eType);
1248   if (!pNode)
1249     return nullptr;
1250 
1251   pNode->SetFlagAndNotify(XFA_NodeFlag_Initialized);
1252   return pNode;
1253 }
1254 
CloneTemplateToForm(bool bRecursive)1255 CXFA_Node* CXFA_Node::CloneTemplateToForm(bool bRecursive) {
1256   DCHECK(m_ePacket == XFA_PacketType::Template);
1257   CXFA_Node* pClone =
1258       m_pDocument->CreateNode(XFA_PacketType::Form, m_elementType);
1259   if (!pClone)
1260     return nullptr;
1261 
1262   pClone->SetTemplateNode(this);
1263   pClone->UpdateNameHash();
1264   pClone->SetXMLMappingNode(GetXMLMappingNode());
1265   if (bRecursive) {
1266     for (CXFA_Node* pChild = GetFirstChild(); pChild;
1267          pChild = pChild->GetNextSibling()) {
1268       pClone->InsertChildAndNotify(pChild->CloneTemplateToForm(bRecursive),
1269                                    nullptr);
1270     }
1271   }
1272   pClone->SetFlagAndNotify(XFA_NodeFlag_Initialized);
1273   return pClone;
1274 }
1275 
GetTemplateNodeIfExists() const1276 CXFA_Node* CXFA_Node::GetTemplateNodeIfExists() const {
1277   return m_pAuxNode;
1278 }
1279 
SetTemplateNode(CXFA_Node * pTemplateNode)1280 void CXFA_Node::SetTemplateNode(CXFA_Node* pTemplateNode) {
1281   m_pAuxNode = pTemplateNode;
1282 }
1283 
GetBindData()1284 CXFA_Node* CXFA_Node::GetBindData() {
1285   DCHECK(GetPacketType() == XFA_PacketType::Form);
1286   return GetBindingNode();
1287 }
1288 
GetBindItemsCopy() const1289 std::vector<CXFA_Node*> CXFA_Node::GetBindItemsCopy() const {
1290   return std::vector<CXFA_Node*>(binding_nodes_.begin(), binding_nodes_.end());
1291 }
1292 
AddBindItem(CXFA_Node * pFormNode)1293 void CXFA_Node::AddBindItem(CXFA_Node* pFormNode) {
1294   DCHECK(pFormNode);
1295 
1296   if (BindsFormItems()) {
1297     if (!pdfium::Contains(binding_nodes_, pFormNode))
1298       binding_nodes_.emplace_back(pFormNode);
1299     return;
1300   }
1301 
1302   CXFA_Node* pOldFormItem = GetBindingNode();
1303   if (!pOldFormItem) {
1304     SetBindingNode(pFormNode);
1305     return;
1306   }
1307   if (pOldFormItem == pFormNode)
1308     return;
1309 
1310   binding_nodes_.clear();
1311   binding_nodes_.push_back(pOldFormItem);
1312   binding_nodes_.push_back(pFormNode);
1313   m_uNodeFlags |= XFA_NodeFlag_BindFormItems;
1314 }
1315 
RemoveBindItem(CXFA_Node * pFormNode)1316 bool CXFA_Node::RemoveBindItem(CXFA_Node* pFormNode) {
1317   if (BindsFormItems()) {
1318     auto it =
1319         std::find(binding_nodes_.begin(), binding_nodes_.end(), pFormNode);
1320     if (it != binding_nodes_.end())
1321       binding_nodes_.erase(it);
1322 
1323     if (binding_nodes_.size() == 1) {
1324       m_uNodeFlags &= ~XFA_NodeFlag_BindFormItems;
1325       return true;
1326     }
1327     return !binding_nodes_.empty();
1328   }
1329 
1330   CXFA_Node* pOldFormItem = GetBindingNode();
1331   if (pOldFormItem != pFormNode)
1332     return !!pOldFormItem;
1333 
1334   SetBindingNode(nullptr);
1335   return false;
1336 }
1337 
HasBindItem() const1338 bool CXFA_Node::HasBindItem() const {
1339   return GetPacketType() == XFA_PacketType::Datasets && GetBindingNode();
1340 }
1341 
GetContainerNode()1342 CXFA_Node* CXFA_Node::GetContainerNode() {
1343   if (GetPacketType() != XFA_PacketType::Form)
1344     return nullptr;
1345   XFA_Element eType = GetElementType();
1346   if (eType == XFA_Element::ExclGroup)
1347     return nullptr;
1348   CXFA_Node* pParentNode = GetParent();
1349   if (pParentNode && pParentNode->GetElementType() == XFA_Element::ExclGroup)
1350     return nullptr;
1351 
1352   if (eType == XFA_Element::Field) {
1353     if (IsChoiceListMultiSelect())
1354       return nullptr;
1355 
1356     WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
1357     if (!wsPicture.IsEmpty())
1358       return this;
1359 
1360     CXFA_Node* pDataNode = GetBindData();
1361     if (!pDataNode)
1362       return nullptr;
1363 
1364     CXFA_Node* pFieldNode = nullptr;
1365     for (auto* pFormNode : pDataNode->GetBindItemsCopy()) {
1366       if (!pFormNode || pFormNode->HasRemovedChildren())
1367         continue;
1368       pFieldNode = pFormNode->IsWidgetReady() ? pFormNode : nullptr;
1369       if (pFieldNode)
1370         wsPicture = pFieldNode->GetPictureContent(XFA_VALUEPICTURE_DataBind);
1371       if (!wsPicture.IsEmpty())
1372         break;
1373 
1374       pFieldNode = nullptr;
1375     }
1376     return pFieldNode;
1377   }
1378 
1379   CXFA_Node* pGrandNode = pParentNode ? pParentNode->GetParent() : nullptr;
1380   CXFA_Node* pValueNode =
1381       (pParentNode && pParentNode->GetElementType() == XFA_Element::Value)
1382           ? pParentNode
1383           : nullptr;
1384   if (!pValueNode) {
1385     pValueNode =
1386         (pGrandNode && pGrandNode->GetElementType() == XFA_Element::Value)
1387             ? pGrandNode
1388             : nullptr;
1389   }
1390   CXFA_Node* pParentOfValueNode =
1391       pValueNode ? pValueNode->GetParent() : nullptr;
1392   return pParentOfValueNode ? pParentOfValueNode->GetContainerNode() : nullptr;
1393 }
1394 
GetLocale()1395 GCedLocaleIface* CXFA_Node::GetLocale() {
1396   Optional<WideString> localeName = GetLocaleName();
1397   if (!localeName.has_value())
1398     return nullptr;
1399   if (localeName.value().EqualsASCII("ambient"))
1400     return GetDocument()->GetLocaleMgr()->GetDefLocale();
1401   return GetDocument()->GetLocaleMgr()->GetLocaleByName(localeName.value());
1402 }
1403 
GetLocaleName()1404 Optional<WideString> CXFA_Node::GetLocaleName() {
1405   CXFA_Node* pForm = ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form));
1406   if (!pForm)
1407     return pdfium::nullopt;
1408 
1409   CXFA_Subform* pTopSubform =
1410       pForm->GetFirstChildByClass<CXFA_Subform>(XFA_Element::Subform);
1411   if (!pTopSubform)
1412     return pdfium::nullopt;
1413 
1414   Optional<WideString> localeName;
1415   CXFA_Node* pLocaleNode = this;
1416   do {
1417     localeName =
1418         pLocaleNode->JSObject()->TryCData(XFA_Attribute::Locale, false);
1419     if (localeName.has_value())
1420       return localeName;
1421 
1422     pLocaleNode = pLocaleNode->GetParent();
1423   } while (pLocaleNode && pLocaleNode != pTopSubform);
1424 
1425   CXFA_Node* pConfig = ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Config));
1426   localeName = GetDocument()->GetLocaleMgr()->GetConfigLocaleName(pConfig);
1427   if (localeName.has_value())
1428     return localeName;
1429 
1430   if (pTopSubform) {
1431     localeName =
1432         pTopSubform->JSObject()->TryCData(XFA_Attribute::Locale, false);
1433     if (localeName.has_value())
1434       return localeName;
1435   }
1436 
1437   LocaleIface* pLocale = GetDocument()->GetLocaleMgr()->GetDefLocale();
1438   if (!pLocale)
1439     return pdfium::nullopt;
1440 
1441   return pLocale->GetName();
1442 }
1443 
GetIntact()1444 XFA_AttributeValue CXFA_Node::GetIntact() {
1445   CXFA_Keep* pKeep = GetFirstChildByClass<CXFA_Keep>(XFA_Element::Keep);
1446   auto layout = JSObject()->TryEnum(XFA_Attribute::Layout, true);
1447   XFA_AttributeValue eLayoutType =
1448       layout.value_or(XFA_AttributeValue::Position);
1449   if (pKeep) {
1450     Optional<XFA_AttributeValue> intact = GetIntactFromKeep(pKeep, eLayoutType);
1451     if (intact)
1452       return *intact;
1453   }
1454 
1455   switch (GetElementType()) {
1456     case XFA_Element::Subform:
1457       switch (eLayoutType) {
1458         case XFA_AttributeValue::Position:
1459         case XFA_AttributeValue::Row:
1460           return XFA_AttributeValue::ContentArea;
1461         default:
1462           return XFA_AttributeValue::None;
1463       }
1464     case XFA_Element::Field: {
1465       CXFA_Node* parent = GetParent();
1466       if (!parent || parent->GetElementType() == XFA_Element::PageArea)
1467         return XFA_AttributeValue::ContentArea;
1468       if (parent->GetIntact() != XFA_AttributeValue::None)
1469         return XFA_AttributeValue::ContentArea;
1470 
1471       auto value = parent->JSObject()->TryEnum(XFA_Attribute::Layout, true);
1472       XFA_AttributeValue eParLayout =
1473           value.value_or(XFA_AttributeValue::Position);
1474       if (eParLayout == XFA_AttributeValue::Position ||
1475           eParLayout == XFA_AttributeValue::Row ||
1476           eParLayout == XFA_AttributeValue::Table) {
1477         return XFA_AttributeValue::None;
1478       }
1479 
1480       XFA_VERSION version = m_pDocument->GetCurVersionMode();
1481       if (eParLayout == XFA_AttributeValue::Tb && version < XFA_VERSION_208) {
1482         Optional<CXFA_Measurement> measureH =
1483             JSObject()->TryMeasure(XFA_Attribute::H, false);
1484         if (measureH)
1485           return XFA_AttributeValue::ContentArea;
1486       }
1487       return XFA_AttributeValue::None;
1488     }
1489     case XFA_Element::Draw:
1490       return XFA_AttributeValue::ContentArea;
1491     default:
1492       return XFA_AttributeValue::None;
1493   }
1494 }
1495 
GetNameExpression()1496 WideString CXFA_Node::GetNameExpression() {
1497   WideString wsName = GetNameExpressionSinglePath(this);
1498   CXFA_Node* parent = GetParent();
1499   while (parent) {
1500     WideString wsParent = GetNameExpressionSinglePath(parent);
1501     wsParent += L".";
1502     wsParent += wsName;
1503     wsName = std::move(wsParent);
1504     parent = parent->GetParent();
1505   }
1506   return wsName;
1507 }
1508 
GetDataDescriptionNode()1509 CXFA_Node* CXFA_Node::GetDataDescriptionNode() {
1510   if (m_ePacket == XFA_PacketType::Datasets)
1511     return m_pAuxNode;
1512   return nullptr;
1513 }
1514 
SetDataDescriptionNode(CXFA_Node * pDataDescriptionNode)1515 void CXFA_Node::SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode) {
1516   DCHECK(m_ePacket == XFA_PacketType::Datasets);
1517   m_pAuxNode = pDataDescriptionNode;
1518 }
1519 
GetModelNode()1520 CXFA_Node* CXFA_Node::GetModelNode() {
1521   switch (GetPacketType()) {
1522     case XFA_PacketType::Xdp:
1523       return m_pDocument->GetRoot();
1524     case XFA_PacketType::Config:
1525       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Config));
1526     case XFA_PacketType::Template:
1527       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Template));
1528     case XFA_PacketType::Form:
1529       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form));
1530     case XFA_PacketType::Datasets:
1531       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Datasets));
1532     case XFA_PacketType::LocaleSet:
1533       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_LocaleSet));
1534     case XFA_PacketType::ConnectionSet:
1535       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_ConnectionSet));
1536     case XFA_PacketType::SourceSet:
1537       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_SourceSet));
1538     case XFA_PacketType::Xdc:
1539       return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Xdc));
1540     default:
1541       return this;
1542   }
1543 }
1544 
CountChildren(XFA_Element eType,bool bOnlyChild)1545 size_t CXFA_Node::CountChildren(XFA_Element eType, bool bOnlyChild) {
1546   size_t count = 0;
1547   for (CXFA_Node* pNode = GetFirstChild(); pNode;
1548        pNode = pNode->GetNextSibling()) {
1549     if (pNode->GetElementType() != eType && eType != XFA_Element::Unknown)
1550       continue;
1551     if (bOnlyChild && HasProperty(pNode->GetElementType()))
1552       continue;
1553     ++count;
1554   }
1555   return count;
1556 }
1557 
GetChildInternal(size_t index,XFA_Element eType,bool bOnlyChild) const1558 CXFA_Node* CXFA_Node::GetChildInternal(size_t index,
1559                                        XFA_Element eType,
1560                                        bool bOnlyChild) const {
1561   size_t count = 0;
1562   for (CXFA_Node* pNode = GetFirstChild(); pNode;
1563        pNode = pNode->GetNextSibling()) {
1564     if (pNode->GetElementType() != eType && eType != XFA_Element::Unknown)
1565       continue;
1566     if (bOnlyChild && HasProperty(pNode->GetElementType()))
1567       continue;
1568     if (count == index)
1569       return pNode;
1570 
1571     ++count;
1572   }
1573   return nullptr;
1574 }
1575 
InsertChildAndNotify(int32_t index,CXFA_Node * pNode)1576 void CXFA_Node::InsertChildAndNotify(int32_t index, CXFA_Node* pNode) {
1577   InsertChildAndNotify(pNode, GetNthChild(index));
1578 }
1579 
InsertChildAndNotify(CXFA_Node * pNode,CXFA_Node * pBeforeNode)1580 void CXFA_Node::InsertChildAndNotify(CXFA_Node* pNode, CXFA_Node* pBeforeNode) {
1581   CHECK(!pNode->GetParent());
1582   CHECK(!pBeforeNode || pBeforeNode->GetParent() == this);
1583   pNode->ClearFlag(XFA_NodeFlag_HasRemovedChildren);
1584   InsertBefore(pNode, pBeforeNode);
1585 
1586   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
1587   if (pNotify)
1588     pNotify->OnChildAdded(this);
1589 
1590   if (!IsNeedSavingXMLNode() || !pNode->xml_node_)
1591     return;
1592 
1593   DCHECK(!pNode->xml_node_->GetParent());
1594   xml_node_->InsertBefore(pNode->xml_node_.Get(),
1595                           pBeforeNode ? pBeforeNode->xml_node_.Get() : nullptr);
1596 }
1597 
RemoveChildAndNotify(CXFA_Node * pNode,bool bNotify)1598 void CXFA_Node::RemoveChildAndNotify(CXFA_Node* pNode, bool bNotify) {
1599   CHECK(pNode);
1600   if (pNode->GetParent() != this)
1601     return;
1602 
1603   pNode->SetFlag(XFA_NodeFlag_HasRemovedChildren);
1604   GCedTreeNodeMixin<CXFA_Node>::RemoveChild(pNode);
1605   OnRemoved(bNotify);
1606 
1607   if (!IsNeedSavingXMLNode() || !pNode->xml_node_)
1608     return;
1609 
1610   if (!pNode->IsAttributeInXML()) {
1611     xml_node_->RemoveChild(pNode->xml_node_.Get());
1612     return;
1613   }
1614 
1615   DCHECK(pNode->xml_node_ == xml_node_);
1616   CFX_XMLElement* pXMLElement = ToXMLElement(pNode->xml_node_.Get());
1617   if (pXMLElement) {
1618     WideString wsAttributeName =
1619         pNode->JSObject()->GetCData(XFA_Attribute::QualifiedName);
1620     pXMLElement->RemoveAttribute(wsAttributeName);
1621   }
1622 
1623   WideString wsName = pNode->JSObject()
1624                           ->TryAttribute(XFA_Attribute::Name, false)
1625                           .value_or(WideString());
1626 
1627   auto* pNewXMLElement = GetXMLDocument()->CreateNode<CFX_XMLElement>(wsName);
1628   WideString wsValue = JSObject()->GetCData(XFA_Attribute::Value);
1629   if (!wsValue.IsEmpty()) {
1630     auto* text = GetXMLDocument()->CreateNode<CFX_XMLText>(wsValue);
1631     pNewXMLElement->AppendLastChild(text);
1632   }
1633   pNode->xml_node_ = pNewXMLElement;
1634   pNode->JSObject()->SetEnum(XFA_Attribute::Contains,
1635                              XFA_AttributeValue::Unknown, false);
1636 }
1637 
GetFirstChildByName(WideStringView wsName) const1638 CXFA_Node* CXFA_Node::GetFirstChildByName(WideStringView wsName) const {
1639   return GetFirstChildByName(FX_HashCode_GetW(wsName, false));
1640 }
1641 
GetFirstChildByName(uint32_t dwNameHash) const1642 CXFA_Node* CXFA_Node::GetFirstChildByName(uint32_t dwNameHash) const {
1643   for (CXFA_Node* pNode = GetFirstChild(); pNode;
1644        pNode = pNode->GetNextSibling()) {
1645     if (pNode->GetNameHash() == dwNameHash)
1646       return pNode;
1647   }
1648   return nullptr;
1649 }
1650 
GetFirstChildByClassInternal(XFA_Element eType) const1651 CXFA_Node* CXFA_Node::GetFirstChildByClassInternal(XFA_Element eType) const {
1652   for (CXFA_Node* pNode = GetFirstChild(); pNode;
1653        pNode = pNode->GetNextSibling()) {
1654     if (pNode->GetElementType() == eType)
1655       return pNode;
1656   }
1657   return nullptr;
1658 }
1659 
GetNextSameNameSibling(uint32_t dwNameHash) const1660 CXFA_Node* CXFA_Node::GetNextSameNameSibling(uint32_t dwNameHash) const {
1661   for (CXFA_Node* pNode = GetNextSibling(); pNode;
1662        pNode = pNode->GetNextSibling()) {
1663     if (pNode->GetNameHash() == dwNameHash)
1664       return pNode;
1665   }
1666   return nullptr;
1667 }
1668 
GetNextSameNameSiblingInternal(WideStringView wsNodeName) const1669 CXFA_Node* CXFA_Node::GetNextSameNameSiblingInternal(
1670     WideStringView wsNodeName) const {
1671   return GetNextSameNameSibling(FX_HashCode_GetW(wsNodeName, false));
1672 }
1673 
GetNextSameClassSiblingInternal(XFA_Element eType) const1674 CXFA_Node* CXFA_Node::GetNextSameClassSiblingInternal(XFA_Element eType) const {
1675   for (CXFA_Node* pNode = GetNextSibling(); pNode;
1676        pNode = pNode->GetNextSibling()) {
1677     if (pNode->GetElementType() == eType)
1678       return pNode;
1679   }
1680   return nullptr;
1681 }
1682 
GetOneChildNamed(WideStringView wsName)1683 CXFA_Node* CXFA_Node::GetOneChildNamed(WideStringView wsName) {
1684   return FindFirstSiblingNamed(this, FX_HashCode_GetW(wsName, false));
1685 }
1686 
GetOneChildOfClass(WideStringView wsClass)1687 CXFA_Node* CXFA_Node::GetOneChildOfClass(WideStringView wsClass) {
1688   XFA_Element element = XFA_GetElementByName(wsClass);
1689   if (element == XFA_Element::Unknown)
1690     return nullptr;
1691 
1692   return FindFirstSiblingOfClass(this, element);
1693 }
1694 
GetSiblings(bool bIsClassName)1695 std::vector<CXFA_Node*> CXFA_Node::GetSiblings(bool bIsClassName) {
1696   std::vector<CXFA_Node*> siblings;
1697   CXFA_Node* parent = GetParent();
1698   if (!parent)
1699     return siblings;
1700   if (!parent->HasProperty(GetElementType())) {
1701     parent = GetTransparentParent();
1702     if (!parent)
1703       return siblings;
1704   }
1705 
1706   uint32_t dwNameHash = bIsClassName ? GetClassHashCode() : GetNameHash();
1707   TraverseSiblings(parent, dwNameHash, &siblings, bIsClassName, true);
1708   return siblings;
1709 }
1710 
GetIndex(bool bIsProperty,bool bIsClassIndex)1711 size_t CXFA_Node::GetIndex(bool bIsProperty, bool bIsClassIndex) {
1712   CXFA_Node* parent = GetParent();
1713   if (!parent)
1714     return 0;
1715 
1716   if (!bIsProperty) {
1717     parent = GetTransparentParent();
1718     if (!parent)
1719       return 0;
1720   }
1721   uint32_t dwHashName = bIsClassIndex ? GetClassHashCode() : GetNameHash();
1722   std::vector<CXFA_Node*> siblings;
1723   TraverseSiblings(parent, dwHashName, &siblings, bIsClassIndex, true);
1724   for (size_t i = 0; i < siblings.size(); ++i) {
1725     if (siblings[i] == this)
1726       return i;
1727   }
1728   return 0;
1729 }
1730 
GetIndexByName()1731 size_t CXFA_Node::GetIndexByName() {
1732   return GetIndex(IsProperty(), /*bIsClassIndex=*/false);
1733 }
1734 
GetIndexByClassName()1735 size_t CXFA_Node::GetIndexByClassName() {
1736   return GetIndex(IsProperty(), /*bIsClassIndex=*/true);
1737 }
1738 
GetInstanceMgrOfSubform()1739 CXFA_Node* CXFA_Node::GetInstanceMgrOfSubform() {
1740   CXFA_Node* pInstanceMgr = nullptr;
1741   if (m_ePacket == XFA_PacketType::Form) {
1742     CXFA_Node* pParentNode = GetParent();
1743     if (!pParentNode || pParentNode->GetElementType() == XFA_Element::Area)
1744       return pInstanceMgr;
1745 
1746     for (CXFA_Node* pNode = GetPrevSibling(); pNode;
1747          pNode = pNode->GetPrevSibling()) {
1748       XFA_Element eType = pNode->GetElementType();
1749       if ((eType == XFA_Element::Subform || eType == XFA_Element::SubformSet) &&
1750           pNode->m_dwNameHash != m_dwNameHash) {
1751         break;
1752       }
1753       if (eType == XFA_Element::InstanceManager) {
1754         WideString wsName = JSObject()->GetCData(XFA_Attribute::Name);
1755         WideString wsInstName =
1756             pNode->JSObject()->GetCData(XFA_Attribute::Name);
1757         if (wsInstName.GetLength() > 0 && wsInstName[0] == '_' &&
1758             wsInstName.Last(wsInstName.GetLength() - 1) == wsName) {
1759           pInstanceMgr = pNode;
1760         }
1761         break;
1762       }
1763     }
1764   }
1765   return pInstanceMgr;
1766 }
1767 
GetOccurIfExists()1768 CXFA_Occur* CXFA_Node::GetOccurIfExists() {
1769   return GetFirstChildByClass<CXFA_Occur>(XFA_Element::Occur);
1770 }
1771 
HasFlag(XFA_NodeFlag dwFlag) const1772 bool CXFA_Node::HasFlag(XFA_NodeFlag dwFlag) const {
1773   if (m_uNodeFlags & dwFlag)
1774     return true;
1775   if (dwFlag == XFA_NodeFlag_HasRemovedChildren)
1776     return GetParent() && GetParent()->HasFlag(dwFlag);
1777   return false;
1778 }
1779 
SetFlagAndNotify(uint32_t dwFlag)1780 void CXFA_Node::SetFlagAndNotify(uint32_t dwFlag) {
1781   DCHECK(dwFlag == XFA_NodeFlag_Initialized);
1782 
1783   if (!IsInitialized()) {
1784     CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
1785     if (pNotify) {
1786       pNotify->OnNodeReady(this);
1787     }
1788   }
1789   m_uNodeFlags |= dwFlag;
1790 }
1791 
SetFlag(uint32_t dwFlag)1792 void CXFA_Node::SetFlag(uint32_t dwFlag) {
1793   m_uNodeFlags |= dwFlag;
1794 }
1795 
ClearFlag(uint32_t dwFlag)1796 void CXFA_Node::ClearFlag(uint32_t dwFlag) {
1797   m_uNodeFlags &= ~dwFlag;
1798 }
1799 
IsAttributeInXML()1800 bool CXFA_Node::IsAttributeInXML() {
1801   return JSObject()->GetEnum(XFA_Attribute::Contains) ==
1802          XFA_AttributeValue::MetaData;
1803 }
1804 
OnRemoved(bool bNotify) const1805 void CXFA_Node::OnRemoved(bool bNotify) const {
1806   if (!bNotify)
1807     return;
1808 
1809   CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
1810   if (pNotify)
1811     pNotify->OnChildRemoved();
1812 }
1813 
UpdateNameHash()1814 void CXFA_Node::UpdateNameHash() {
1815   WideString wsName = JSObject()->GetCData(XFA_Attribute::Name);
1816   m_dwNameHash = FX_HashCode_GetW(wsName.AsStringView(), false);
1817 }
1818 
CreateXMLMappingNode()1819 CFX_XMLNode* CXFA_Node::CreateXMLMappingNode() {
1820   if (!xml_node_) {
1821     xml_node_ = GetXMLDocument()->CreateNode<CFX_XMLElement>(
1822         JSObject()->GetCData(XFA_Attribute::Name));
1823   }
1824   return xml_node_.Get();
1825 }
1826 
IsNeedSavingXMLNode() const1827 bool CXFA_Node::IsNeedSavingXMLNode() const {
1828   return xml_node_ && (GetPacketType() == XFA_PacketType::Datasets ||
1829                        GetElementType() == XFA_Element::Xfa);
1830 }
1831 
GetItemIfExists(int32_t iIndex)1832 CXFA_Node* CXFA_Node::GetItemIfExists(int32_t iIndex) {
1833   int32_t iCount = 0;
1834   uint32_t dwNameHash = 0;
1835   for (CXFA_Node* pNode = GetNextSibling(); pNode;
1836        pNode = pNode->GetNextSibling()) {
1837     XFA_Element eCurType = pNode->GetElementType();
1838     if (eCurType == XFA_Element::InstanceManager)
1839       break;
1840     if ((eCurType != XFA_Element::Subform) &&
1841         (eCurType != XFA_Element::SubformSet)) {
1842       continue;
1843     }
1844     if (iCount == 0) {
1845       WideString wsName = pNode->JSObject()->GetCData(XFA_Attribute::Name);
1846       WideString wsInstName = JSObject()->GetCData(XFA_Attribute::Name);
1847       if (wsInstName.GetLength() < 1 || wsInstName[0] != '_' ||
1848           wsInstName.Last(wsInstName.GetLength() - 1) != wsName) {
1849         return nullptr;
1850       }
1851       dwNameHash = pNode->GetNameHash();
1852     }
1853     if (dwNameHash != pNode->GetNameHash())
1854       break;
1855 
1856     iCount++;
1857     if (iCount > iIndex)
1858       return pNode;
1859   }
1860   return nullptr;
1861 }
1862 
GetCount()1863 int32_t CXFA_Node::GetCount() {
1864   int32_t iCount = 0;
1865   uint32_t dwNameHash = 0;
1866   for (CXFA_Node* pNode = GetNextSibling(); pNode;
1867        pNode = pNode->GetNextSibling()) {
1868     XFA_Element eCurType = pNode->GetElementType();
1869     if (eCurType == XFA_Element::InstanceManager)
1870       break;
1871     if ((eCurType != XFA_Element::Subform) &&
1872         (eCurType != XFA_Element::SubformSet)) {
1873       continue;
1874     }
1875     if (iCount == 0) {
1876       WideString wsName = pNode->JSObject()->GetCData(XFA_Attribute::Name);
1877       WideString wsInstName = JSObject()->GetCData(XFA_Attribute::Name);
1878       if (wsInstName.GetLength() < 1 || wsInstName[0] != '_' ||
1879           wsInstName.Last(wsInstName.GetLength() - 1) != wsName) {
1880         return iCount;
1881       }
1882       dwNameHash = pNode->GetNameHash();
1883     }
1884     if (dwNameHash != pNode->GetNameHash())
1885       break;
1886 
1887     iCount++;
1888   }
1889   return iCount;
1890 }
1891 
InsertItem(CXFA_Node * pNewInstance,int32_t iPos,int32_t iCount,bool bMoveDataBindingNodes)1892 void CXFA_Node::InsertItem(CXFA_Node* pNewInstance,
1893                            int32_t iPos,
1894                            int32_t iCount,
1895                            bool bMoveDataBindingNodes) {
1896   if (iCount < 0)
1897     iCount = GetCount();
1898   if (iPos < 0)
1899     iPos = iCount;
1900   if (iPos == iCount) {
1901     CXFA_Node* item = GetItemIfExists(iCount - 1);
1902     if (!item)
1903       return;
1904 
1905     CXFA_Node* pNextSibling =
1906         iCount > 0 ? item->GetNextSibling() : GetNextSibling();
1907     GetParent()->InsertChildAndNotify(pNewInstance, pNextSibling);
1908     if (bMoveDataBindingNodes) {
1909       NodeSet sNew;
1910       CXFA_NodeIteratorTemplate<CXFA_Node,
1911                                 CXFA_TraverseStrategy_XFAContainerNode>
1912           sIteratorNew(pNewInstance);
1913       for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
1914            pNode = sIteratorNew.MoveToNext()) {
1915         CXFA_Node* pDataNode = pNode->GetBindData();
1916         if (pDataNode)
1917           sNew.insert(pDataNode);
1918       }
1919       NodeSet sAfter;
1920       CXFA_NodeIteratorTemplate<CXFA_Node,
1921                                 CXFA_TraverseStrategy_XFAContainerNode>
1922           sIteratorAfter(pNextSibling);
1923       for (CXFA_Node* pNode = sIteratorAfter.GetCurrent(); pNode;
1924            pNode = sIteratorAfter.MoveToNext()) {
1925         CXFA_Node* pDataNode = pNode->GetBindData();
1926         if (pDataNode)
1927           sAfter.insert(pDataNode);
1928       }
1929       ReorderDataNodes(sNew, sAfter, false);
1930     }
1931   } else {
1932     CXFA_Node* pBeforeInstance = GetItemIfExists(iPos);
1933     if (!pBeforeInstance) {
1934       // TODO(dsinclair): What should happen here?
1935       return;
1936     }
1937 
1938     GetParent()->InsertChildAndNotify(pNewInstance, pBeforeInstance);
1939     if (bMoveDataBindingNodes) {
1940       NodeSet sNew;
1941       CXFA_NodeIteratorTemplate<CXFA_Node,
1942                                 CXFA_TraverseStrategy_XFAContainerNode>
1943           sIteratorNew(pNewInstance);
1944       for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
1945            pNode = sIteratorNew.MoveToNext()) {
1946         CXFA_Node* pDataNode = pNode->GetBindData();
1947         if (pDataNode)
1948           sNew.insert(pDataNode);
1949       }
1950       NodeSet sBefore;
1951       CXFA_NodeIteratorTemplate<CXFA_Node,
1952                                 CXFA_TraverseStrategy_XFAContainerNode>
1953           sIteratorBefore(pBeforeInstance);
1954       for (CXFA_Node* pNode = sIteratorBefore.GetCurrent(); pNode;
1955            pNode = sIteratorBefore.MoveToNext()) {
1956         CXFA_Node* pDataNode = pNode->GetBindData();
1957         if (pDataNode)
1958           sBefore.insert(pDataNode);
1959       }
1960       ReorderDataNodes(sNew, sBefore, true);
1961     }
1962   }
1963 }
1964 
RemoveItem(CXFA_Node * pRemoveInstance,bool bRemoveDataBinding)1965 void CXFA_Node::RemoveItem(CXFA_Node* pRemoveInstance,
1966                            bool bRemoveDataBinding) {
1967   GetParent()->RemoveChildAndNotify(pRemoveInstance, true);
1968   if (!bRemoveDataBinding)
1969     return;
1970 
1971   CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>
1972       sIterator(pRemoveInstance);
1973   for (CXFA_Node* pFormNode = sIterator.GetCurrent(); pFormNode;
1974        pFormNode = sIterator.MoveToNext()) {
1975     CXFA_Node* pDataNode = pFormNode->GetBindData();
1976     if (!pDataNode)
1977       continue;
1978 
1979     if (!pDataNode->RemoveBindItem(pFormNode)) {
1980       if (CXFA_Node* pDataParent = pDataNode->GetParent()) {
1981         pDataParent->RemoveChildAndNotify(pDataNode, true);
1982       }
1983     }
1984     pFormNode->SetBindingNode(nullptr);
1985   }
1986 }
1987 
CreateInstanceIfPossible(bool bDataMerge)1988 CXFA_Node* CXFA_Node::CreateInstanceIfPossible(bool bDataMerge) {
1989   CXFA_Document* pDocument = GetDocument();
1990   CXFA_Node* pTemplateNode = GetTemplateNodeIfExists();
1991   if (!pTemplateNode)
1992     return nullptr;
1993 
1994   CXFA_Node* pFormParent = GetParent();
1995   CXFA_Node* pDataScope = nullptr;
1996   for (CXFA_Node* pRootBoundNode = pFormParent;
1997        pRootBoundNode && pRootBoundNode->IsContainerNode();
1998        pRootBoundNode = pRootBoundNode->GetParent()) {
1999     pDataScope = pRootBoundNode->GetBindData();
2000     if (pDataScope)
2001       break;
2002   }
2003   if (!pDataScope) {
2004     pDataScope = ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record));
2005     DCHECK(pDataScope);
2006   }
2007 
2008   CXFA_Node* pInstance = pDocument->DataMerge_CopyContainer(
2009       pTemplateNode, pFormParent, pDataScope, true, bDataMerge, true);
2010   if (pInstance) {
2011     pDocument->DataMerge_UpdateBindingRelations(pInstance);
2012     pFormParent->RemoveChildAndNotify(pInstance, true);
2013   }
2014   return pInstance;
2015 }
2016 
GetDefaultBoolean(XFA_Attribute attr) const2017 Optional<bool> CXFA_Node::GetDefaultBoolean(XFA_Attribute attr) const {
2018   Optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::Boolean);
2019   if (!value)
2020     return {};
2021   return {!!*value};
2022 }
2023 
GetDefaultInteger(XFA_Attribute attr) const2024 Optional<int32_t> CXFA_Node::GetDefaultInteger(XFA_Attribute attr) const {
2025   Optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::Integer);
2026   if (!value)
2027     return {};
2028   return {static_cast<int32_t>(reinterpret_cast<uintptr_t>(*value))};
2029 }
2030 
GetDefaultMeasurement(XFA_Attribute attr) const2031 Optional<CXFA_Measurement> CXFA_Node::GetDefaultMeasurement(
2032     XFA_Attribute attr) const {
2033   Optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::Measure);
2034   if (!value)
2035     return {};
2036 
2037   WideString str = WideString(static_cast<const wchar_t*>(*value));
2038   return {CXFA_Measurement(str.AsStringView())};
2039 }
2040 
GetDefaultCData(XFA_Attribute attr) const2041 Optional<WideString> CXFA_Node::GetDefaultCData(XFA_Attribute attr) const {
2042   Optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::CData);
2043   if (!value)
2044     return {};
2045 
2046   return {WideString(static_cast<const wchar_t*>(*value))};
2047 }
2048 
GetDefaultEnum(XFA_Attribute attr) const2049 Optional<XFA_AttributeValue> CXFA_Node::GetDefaultEnum(
2050     XFA_Attribute attr) const {
2051   Optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::Enum);
2052   if (!value)
2053     return {};
2054   return {static_cast<XFA_AttributeValue>(reinterpret_cast<uintptr_t>(*value))};
2055 }
2056 
GetDefaultValue(XFA_Attribute attr,XFA_AttributeType eType) const2057 Optional<void*> CXFA_Node::GetDefaultValue(XFA_Attribute attr,
2058                                            XFA_AttributeType eType) const {
2059   const AttributeData* data = GetAttributeData(attr);
2060   if (!data)
2061     return {};
2062   if (data->type == eType)
2063     return {data->default_value};
2064   return {};
2065 }
2066 
SendAttributeChangeMessage(XFA_Attribute eAttribute,bool bScriptModify)2067 void CXFA_Node::SendAttributeChangeMessage(XFA_Attribute eAttribute,
2068                                            bool bScriptModify) {
2069   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
2070   if (!pNotify)
2071     return;
2072 
2073   if (GetPacketType() != XFA_PacketType::Form) {
2074     pNotify->OnValueChanged(this, eAttribute, this, this);
2075     return;
2076   }
2077 
2078   bool bNeedFindContainer = false;
2079   switch (GetElementType()) {
2080     case XFA_Element::Caption:
2081       bNeedFindContainer = true;
2082       pNotify->OnValueChanged(this, eAttribute, this, GetParent());
2083       break;
2084     case XFA_Element::Font:
2085     case XFA_Element::Para: {
2086       bNeedFindContainer = true;
2087       CXFA_Node* pParentNode = GetParent();
2088       if (pParentNode->GetElementType() == XFA_Element::Caption) {
2089         pNotify->OnValueChanged(this, eAttribute, pParentNode,
2090                                 pParentNode->GetParent());
2091       } else {
2092         pNotify->OnValueChanged(this, eAttribute, this, pParentNode);
2093       }
2094       break;
2095     }
2096     case XFA_Element::Margin: {
2097       bNeedFindContainer = true;
2098       CXFA_Node* pParentNode = GetParent();
2099       XFA_Element eParentType = pParentNode->GetElementType();
2100       if (pParentNode->IsContainerNode()) {
2101         pNotify->OnValueChanged(this, eAttribute, this, pParentNode);
2102       } else if (eParentType == XFA_Element::Caption) {
2103         pNotify->OnValueChanged(this, eAttribute, pParentNode,
2104                                 pParentNode->GetParent());
2105       } else {
2106         CXFA_Node* pNode = pParentNode->GetParent();
2107         if (pNode && pNode->GetElementType() == XFA_Element::Ui)
2108           pNotify->OnValueChanged(this, eAttribute, pNode, pNode->GetParent());
2109       }
2110       break;
2111     }
2112     case XFA_Element::Comb: {
2113       CXFA_Node* pEditNode = GetParent();
2114       XFA_Element eUIType = pEditNode->GetElementType();
2115       if (pEditNode && (eUIType == XFA_Element::DateTimeEdit ||
2116                         eUIType == XFA_Element::NumericEdit ||
2117                         eUIType == XFA_Element::TextEdit)) {
2118         CXFA_Node* pUINode = pEditNode->GetParent();
2119         if (pUINode) {
2120           pNotify->OnValueChanged(this, eAttribute, pUINode,
2121                                   pUINode->GetParent());
2122         }
2123       }
2124       break;
2125     }
2126     case XFA_Element::Button:
2127     case XFA_Element::Barcode:
2128     case XFA_Element::ChoiceList:
2129     case XFA_Element::DateTimeEdit:
2130     case XFA_Element::NumericEdit:
2131     case XFA_Element::PasswordEdit:
2132     case XFA_Element::TextEdit: {
2133       CXFA_Node* pUINode = GetParent();
2134       if (pUINode) {
2135         pNotify->OnValueChanged(this, eAttribute, pUINode,
2136                                 pUINode->GetParent());
2137       }
2138       break;
2139     }
2140     case XFA_Element::CheckButton: {
2141       bNeedFindContainer = true;
2142       CXFA_Node* pUINode = GetParent();
2143       if (pUINode) {
2144         pNotify->OnValueChanged(this, eAttribute, pUINode,
2145                                 pUINode->GetParent());
2146       }
2147       break;
2148     }
2149     case XFA_Element::Keep:
2150     case XFA_Element::Bookend:
2151     case XFA_Element::Break:
2152     case XFA_Element::BreakAfter:
2153     case XFA_Element::BreakBefore:
2154     case XFA_Element::Overflow:
2155       bNeedFindContainer = true;
2156       break;
2157     case XFA_Element::Area:
2158     case XFA_Element::Draw:
2159     case XFA_Element::ExclGroup:
2160     case XFA_Element::Field:
2161     case XFA_Element::Subform:
2162     case XFA_Element::SubformSet:
2163       pNotify->OnContainerChanged(this);
2164       pNotify->OnValueChanged(this, eAttribute, this, this);
2165       break;
2166     case XFA_Element::Sharptext:
2167     case XFA_Element::Sharpxml:
2168     case XFA_Element::SharpxHTML: {
2169       CXFA_Node* pTextNode = GetParent();
2170       if (!pTextNode)
2171         return;
2172 
2173       CXFA_Node* pValueNode = pTextNode->GetParent();
2174       if (!pValueNode)
2175         return;
2176 
2177       XFA_Element eType = pValueNode->GetElementType();
2178       if (eType == XFA_Element::Value) {
2179         bNeedFindContainer = true;
2180         CXFA_Node* pNode = pValueNode->GetParent();
2181         if (pNode && pNode->IsContainerNode()) {
2182           if (bScriptModify)
2183             pValueNode = pNode;
2184 
2185           pNotify->OnValueChanged(this, eAttribute, pValueNode, pNode);
2186         } else {
2187           pNotify->OnValueChanged(this, eAttribute, pNode, pNode->GetParent());
2188         }
2189       } else {
2190         if (eType == XFA_Element::Items) {
2191           CXFA_Node* pNode = pValueNode->GetParent();
2192           if (pNode && pNode->IsContainerNode()) {
2193             pNotify->OnValueChanged(this, eAttribute, pValueNode, pNode);
2194           }
2195         }
2196       }
2197       break;
2198     }
2199     default:
2200       break;
2201   }
2202 
2203   if (!bNeedFindContainer)
2204     return;
2205 
2206   CXFA_Node* pParent = this;
2207   while (pParent && !pParent->IsContainerNode())
2208     pParent = pParent->GetParent();
2209 
2210   if (pParent)
2211     pNotify->OnContainerChanged(pParent);
2212 }
2213 
SyncValue(const WideString & wsValue,bool bNotify)2214 void CXFA_Node::SyncValue(const WideString& wsValue, bool bNotify) {
2215   WideString wsFormatValue = wsValue;
2216   CXFA_Node* pContainerNode = GetContainerNode();
2217   if (pContainerNode)
2218     wsFormatValue = pContainerNode->GetFormatDataValue(wsValue);
2219 
2220   JSObject()->SetContent(wsValue, wsFormatValue, bNotify, false, true);
2221 }
2222 
GetRawValue()2223 WideString CXFA_Node::GetRawValue() {
2224   return JSObject()->GetContent(false);
2225 }
2226 
GetRotate() const2227 int32_t CXFA_Node::GetRotate() const {
2228   Optional<int32_t> degrees =
2229       JSObject()->TryInteger(XFA_Attribute::Rotate, false);
2230   return degrees ? XFA_MapRotation(*degrees) / 90 * 90 : 0;
2231 }
2232 
GetBorderIfExists() const2233 CXFA_Border* CXFA_Node::GetBorderIfExists() const {
2234   return JSObject()->GetProperty<CXFA_Border>(0, XFA_Element::Border);
2235 }
2236 
GetOrCreateBorderIfPossible()2237 CXFA_Border* CXFA_Node::GetOrCreateBorderIfPossible() {
2238   return JSObject()->GetOrCreateProperty<CXFA_Border>(0, XFA_Element::Border);
2239 }
2240 
GetCaptionIfExists() const2241 CXFA_Caption* CXFA_Node::GetCaptionIfExists() const {
2242   return JSObject()->GetProperty<CXFA_Caption>(0, XFA_Element::Caption);
2243 }
2244 
GetOrCreateFontIfPossible()2245 CXFA_Font* CXFA_Node::GetOrCreateFontIfPossible() {
2246   return JSObject()->GetOrCreateProperty<CXFA_Font>(0, XFA_Element::Font);
2247 }
2248 
GetFontIfExists() const2249 CXFA_Font* CXFA_Node::GetFontIfExists() const {
2250   return JSObject()->GetProperty<CXFA_Font>(0, XFA_Element::Font);
2251 }
2252 
GetFontSize() const2253 float CXFA_Node::GetFontSize() const {
2254   CXFA_Font* font = GetFontIfExists();
2255   float fFontSize = font ? font->GetFontSize() : 10.0f;
2256   return fFontSize < 0.1f ? 10.0f : fFontSize;
2257 }
2258 
GetLineHeight() const2259 float CXFA_Node::GetLineHeight() const {
2260   float fLineHeight = 0;
2261   CXFA_Para* para = GetParaIfExists();
2262   if (para)
2263     fLineHeight = para->GetLineHeight();
2264 
2265   if (fLineHeight < 1)
2266     fLineHeight = GetFontSize() * 1.2f;
2267   return fLineHeight;
2268 }
2269 
GetTextColor() const2270 FX_ARGB CXFA_Node::GetTextColor() const {
2271   CXFA_Font* font = GetFontIfExists();
2272   return font ? font->GetColor() : 0xFF000000;
2273 }
2274 
GetMarginIfExists() const2275 CXFA_Margin* CXFA_Node::GetMarginIfExists() const {
2276   return JSObject()->GetProperty<CXFA_Margin>(0, XFA_Element::Margin);
2277 }
2278 
GetParaIfExists() const2279 CXFA_Para* CXFA_Node::GetParaIfExists() const {
2280   return JSObject()->GetProperty<CXFA_Para>(0, XFA_Element::Para);
2281 }
2282 
IsOpenAccess() const2283 bool CXFA_Node::IsOpenAccess() const {
2284   for (auto* pNode = this; pNode; pNode = pNode->GetContainerParent()) {
2285     XFA_AttributeValue iAcc = pNode->JSObject()->GetEnum(XFA_Attribute::Access);
2286     if (iAcc != XFA_AttributeValue::Open)
2287       return false;
2288   }
2289   return true;
2290 }
2291 
GetDefaultValueIfExists()2292 CXFA_Value* CXFA_Node::GetDefaultValueIfExists() {
2293   CXFA_Node* pTemNode = GetTemplateNodeIfExists();
2294   return pTemNode ? pTemNode->JSObject()->GetProperty<CXFA_Value>(
2295                         0, XFA_Element::Value)
2296                   : nullptr;
2297 }
2298 
GetFormValueIfExists() const2299 CXFA_Value* CXFA_Node::GetFormValueIfExists() const {
2300   return JSObject()->GetProperty<CXFA_Value>(0, XFA_Element::Value);
2301 }
2302 
GetCalculateIfExists() const2303 CXFA_Calculate* CXFA_Node::GetCalculateIfExists() const {
2304   return JSObject()->GetProperty<CXFA_Calculate>(0, XFA_Element::Calculate);
2305 }
2306 
GetValidateIfExists() const2307 CXFA_Validate* CXFA_Node::GetValidateIfExists() const {
2308   return JSObject()->GetProperty<CXFA_Validate>(0, XFA_Element::Validate);
2309 }
2310 
GetOrCreateValidateIfPossible()2311 CXFA_Validate* CXFA_Node::GetOrCreateValidateIfPossible() {
2312   return JSObject()->GetOrCreateProperty<CXFA_Validate>(0,
2313                                                         XFA_Element::Validate);
2314 }
2315 
GetBindIfExists() const2316 CXFA_Bind* CXFA_Node::GetBindIfExists() const {
2317   return JSObject()->GetProperty<CXFA_Bind>(0, XFA_Element::Bind);
2318 }
2319 
GetIntactFromKeep(const CXFA_Keep * pKeep,XFA_AttributeValue eLayoutType) const2320 Optional<XFA_AttributeValue> CXFA_Node::GetIntactFromKeep(
2321     const CXFA_Keep* pKeep,
2322     XFA_AttributeValue eLayoutType) const {
2323   Optional<XFA_AttributeValue> intact =
2324       pKeep->JSObject()->TryEnum(XFA_Attribute::Intact, false);
2325   if (!intact.has_value())
2326     return {};
2327 
2328   if (intact.value() != XFA_AttributeValue::None ||
2329       eLayoutType != XFA_AttributeValue::Row ||
2330       m_pDocument->GetCurVersionMode() >= XFA_VERSION_208) {
2331     return intact;
2332   }
2333 
2334   CXFA_Node* pPreviewRow = GetPrevContainerSibling();
2335   if (!pPreviewRow || pPreviewRow->JSObject()->GetEnum(XFA_Attribute::Layout) !=
2336                           XFA_AttributeValue::Row) {
2337     return intact;
2338   }
2339 
2340   Optional<XFA_AttributeValue> value =
2341       pKeep->JSObject()->TryEnum(XFA_Attribute::Previous, false);
2342   if (value && (*value == XFA_AttributeValue::ContentArea ||
2343                 *value == XFA_AttributeValue::PageArea)) {
2344     return XFA_AttributeValue::ContentArea;
2345   }
2346 
2347   CXFA_Keep* pNode =
2348       pPreviewRow->GetFirstChildByClass<CXFA_Keep>(XFA_Element::Keep);
2349   if (!pNode)
2350     return intact;
2351 
2352   Optional<XFA_AttributeValue> ret =
2353       pNode->JSObject()->TryEnum(XFA_Attribute::Next, false);
2354   if (!ret)
2355     return intact;
2356 
2357   return (*ret == XFA_AttributeValue::ContentArea ||
2358           *ret == XFA_AttributeValue::PageArea)
2359              ? XFA_AttributeValue::ContentArea
2360              : intact;
2361 }
2362 
TryWidth()2363 Optional<float> CXFA_Node::TryWidth() {
2364   return JSObject()->TryMeasureAsFloat(XFA_Attribute::W);
2365 }
2366 
TryHeight()2367 Optional<float> CXFA_Node::TryHeight() {
2368   return JSObject()->TryMeasureAsFloat(XFA_Attribute::H);
2369 }
2370 
TryMinWidth()2371 Optional<float> CXFA_Node::TryMinWidth() {
2372   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MinW);
2373 }
2374 
TryMinHeight()2375 Optional<float> CXFA_Node::TryMinHeight() {
2376   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MinH);
2377 }
2378 
TryMaxWidth()2379 Optional<float> CXFA_Node::TryMaxWidth() {
2380   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MaxW);
2381 }
2382 
TryMaxHeight()2383 Optional<float> CXFA_Node::TryMaxHeight() {
2384   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MaxH);
2385 }
2386 
GetExclGroupIfExists()2387 CXFA_Node* CXFA_Node::GetExclGroupIfExists() {
2388   CXFA_Node* pExcl = GetParent();
2389   if (!pExcl || pExcl->GetElementType() != XFA_Element::ExclGroup)
2390     return nullptr;
2391   return pExcl;
2392 }
2393 
ProcessEvent(CXFA_FFDocView * pDocView,XFA_AttributeValue iActivity,CXFA_EventParam * pEventParam)2394 XFA_EventError CXFA_Node::ProcessEvent(CXFA_FFDocView* pDocView,
2395                                        XFA_AttributeValue iActivity,
2396                                        CXFA_EventParam* pEventParam) {
2397   if (GetElementType() == XFA_Element::Draw)
2398     return XFA_EventError::kNotExist;
2399 
2400   std::vector<CXFA_Event*> eventArray =
2401       GetEventByActivity(iActivity, pEventParam->m_bIsFormReady);
2402   bool first = true;
2403   XFA_EventError iRet = XFA_EventError::kNotExist;
2404   for (CXFA_Event* event : eventArray) {
2405     XFA_EventError result =
2406         ProcessEventInternal(pDocView, iActivity, event, pEventParam);
2407     if (first || result == XFA_EventError::kSuccess)
2408       iRet = result;
2409     first = false;
2410   }
2411   return iRet;
2412 }
2413 
ProcessEventInternal(CXFA_FFDocView * pDocView,XFA_AttributeValue iActivity,CXFA_Event * event,CXFA_EventParam * pEventParam)2414 XFA_EventError CXFA_Node::ProcessEventInternal(CXFA_FFDocView* pDocView,
2415                                                XFA_AttributeValue iActivity,
2416                                                CXFA_Event* event,
2417                                                CXFA_EventParam* pEventParam) {
2418   if (!event)
2419     return XFA_EventError::kNotExist;
2420 
2421   switch (event->GetEventType()) {
2422     case XFA_Element::Execute:
2423       break;
2424     case XFA_Element::Script:
2425       if (iActivity == XFA_AttributeValue::DocClose) {
2426         // Too late, scripting engine already gone.
2427         return XFA_EventError::kNotExist;
2428       }
2429       return ExecuteScript(pDocView, event->GetScriptIfExists(), pEventParam);
2430     case XFA_Element::SignData:
2431       break;
2432     case XFA_Element::Submit: {
2433 // TODO(crbug.com/867485): Submit is disabled for now. Fix it and reenable this
2434 // code.
2435 #ifdef PDF_XFA_ELEMENT_SUBMIT_ENABLED
2436       CXFA_Submit* submit = event->GetSubmitIfExists();
2437       if (!submit)
2438         return XFA_EventError::kNotExist;
2439       return pDocView->GetDoc()->GetDocEnvironment()->Submit(pDocView->GetDoc(),
2440                                                              submit);
2441 #else
2442       return XFA_EventError::kDisabled;
2443 #endif  // PDF_XFA_ELEMENT_SUBMIT_ENABLED
2444     }
2445     default:
2446       break;
2447   }
2448   return XFA_EventError::kNotExist;
2449 }
2450 
ProcessCalculate(CXFA_FFDocView * pDocView)2451 XFA_EventError CXFA_Node::ProcessCalculate(CXFA_FFDocView* pDocView) {
2452   if (GetElementType() == XFA_Element::Draw)
2453     return XFA_EventError::kNotExist;
2454 
2455   CXFA_Calculate* calc = GetCalculateIfExists();
2456   if (!calc)
2457     return XFA_EventError::kNotExist;
2458   if (IsUserInteractive())
2459     return XFA_EventError::kDisabled;
2460 
2461   CXFA_EventParam EventParam;
2462   EventParam.m_eType = XFA_EVENT_Calculate;
2463   XFA_EventError iRet =
2464       ExecuteScript(pDocView, calc->GetScriptIfExists(), &EventParam);
2465   if (iRet != XFA_EventError::kSuccess)
2466     return iRet;
2467 
2468   if (GetRawValue() != EventParam.m_wsResult) {
2469     SetValue(XFA_VALUEPICTURE_Raw, EventParam.m_wsResult);
2470     pDocView->UpdateUIDisplay(this, nullptr);
2471   }
2472   return XFA_EventError::kSuccess;
2473 }
2474 
ProcessScriptTestValidate(CXFA_FFDocView * pDocView,CXFA_Validate * validate,XFA_EventError iRet,bool bRetValue,bool bVersionFlag)2475 void CXFA_Node::ProcessScriptTestValidate(CXFA_FFDocView* pDocView,
2476                                           CXFA_Validate* validate,
2477                                           XFA_EventError iRet,
2478                                           bool bRetValue,
2479                                           bool bVersionFlag) {
2480   if (iRet != XFA_EventError::kSuccess)
2481     return;
2482   if (bRetValue)
2483     return;
2484 
2485   IXFA_AppProvider* pAppProvider =
2486       pDocView->GetDoc()->GetApp()->GetAppProvider();
2487   if (!pAppProvider)
2488     return;
2489 
2490   WideString wsTitle = pAppProvider->GetAppTitle();
2491   WideString wsScriptMsg = validate->GetScriptMessageText();
2492   if (validate->GetScriptTest() == XFA_AttributeValue::Warning) {
2493     if (IsUserInteractive())
2494       return;
2495     if (wsScriptMsg.IsEmpty())
2496       wsScriptMsg = GetValidateMessage(false, bVersionFlag);
2497 
2498     if (bVersionFlag) {
2499       pAppProvider->MsgBox(wsScriptMsg, wsTitle,
2500                            static_cast<uint32_t>(AlertIcon::kWarning),
2501                            static_cast<uint32_t>(AlertButton::kOK));
2502       return;
2503     }
2504     if (pAppProvider->MsgBox(wsScriptMsg, wsTitle,
2505                              static_cast<uint32_t>(AlertIcon::kWarning),
2506                              static_cast<uint32_t>(AlertButton::kYesNo)) ==
2507         static_cast<uint32_t>(AlertReturn::kYes)) {
2508       SetFlag(XFA_NodeFlag_UserInteractive);
2509     }
2510     return;
2511   }
2512 
2513   if (wsScriptMsg.IsEmpty())
2514     wsScriptMsg = GetValidateMessage(true, bVersionFlag);
2515   pAppProvider->MsgBox(wsScriptMsg, wsTitle,
2516                        static_cast<uint32_t>(AlertIcon::kError),
2517                        static_cast<uint32_t>(AlertButton::kOK));
2518 }
2519 
ProcessFormatTestValidate(CXFA_FFDocView * pDocView,CXFA_Validate * validate,bool bVersionFlag)2520 XFA_EventError CXFA_Node::ProcessFormatTestValidate(CXFA_FFDocView* pDocView,
2521                                                     CXFA_Validate* validate,
2522                                                     bool bVersionFlag) {
2523   WideString wsPicture = validate->GetPicture();
2524   if (wsPicture.IsEmpty())
2525     return XFA_EventError::kNotExist;
2526 
2527   WideString wsRawValue = GetRawValue();
2528   if (wsRawValue.IsEmpty())
2529     return XFA_EventError::kError;
2530 
2531   GCedLocaleIface* pLocale = GetLocale();
2532   if (!pLocale)
2533     return XFA_EventError::kNotExist;
2534 
2535   CXFA_LocaleValue lcValue = XFA_GetLocaleValue(this);
2536   if (lcValue.ValidateValue(lcValue.GetValue(), wsPicture, pLocale, nullptr))
2537     return XFA_EventError::kSuccess;
2538 
2539   IXFA_AppProvider* pAppProvider =
2540       pDocView->GetDoc()->GetApp()->GetAppProvider();
2541   if (!pAppProvider)
2542     return XFA_EventError::kNotExist;
2543 
2544   WideString wsFormatMsg = validate->GetFormatMessageText();
2545   WideString wsTitle = pAppProvider->GetAppTitle();
2546   if (validate->GetFormatTest() == XFA_AttributeValue::Error) {
2547     if (wsFormatMsg.IsEmpty())
2548       wsFormatMsg = GetValidateMessage(true, bVersionFlag);
2549     pAppProvider->MsgBox(wsFormatMsg, wsTitle,
2550                          static_cast<uint32_t>(AlertIcon::kError),
2551                          static_cast<uint32_t>(AlertButton::kOK));
2552     return XFA_EventError::kError;
2553   }
2554 
2555   if (wsFormatMsg.IsEmpty())
2556     wsFormatMsg = GetValidateMessage(false, bVersionFlag);
2557 
2558   if (bVersionFlag) {
2559     pAppProvider->MsgBox(wsFormatMsg, wsTitle,
2560                          static_cast<uint32_t>(AlertIcon::kWarning),
2561                          static_cast<uint32_t>(AlertButton::kOK));
2562     return XFA_EventError::kError;
2563   }
2564 
2565   if (pAppProvider->MsgBox(wsFormatMsg, wsTitle,
2566                            static_cast<uint32_t>(AlertIcon::kWarning),
2567                            static_cast<uint32_t>(AlertButton::kYesNo)) ==
2568       static_cast<uint32_t>(AlertReturn::kYes)) {
2569     SetFlag(XFA_NodeFlag_UserInteractive);
2570   }
2571 
2572   return XFA_EventError::kError;
2573 }
2574 
ProcessNullTestValidate(CXFA_FFDocView * pDocView,CXFA_Validate * validate,int32_t iFlags,bool bVersionFlag)2575 XFA_EventError CXFA_Node::ProcessNullTestValidate(CXFA_FFDocView* pDocView,
2576                                                   CXFA_Validate* validate,
2577                                                   int32_t iFlags,
2578                                                   bool bVersionFlag) {
2579   if (!GetValue(XFA_VALUEPICTURE_Raw).IsEmpty())
2580     return XFA_EventError::kSuccess;
2581   if (m_bIsNull && m_bPreNull)
2582     return XFA_EventError::kSuccess;
2583 
2584   XFA_AttributeValue eNullTest = validate->GetNullTest();
2585   WideString wsNullMsg = validate->GetNullMessageText();
2586   if (iFlags & 0x01) {
2587     XFA_EventError iRet = XFA_EventError::kSuccess;
2588     if (eNullTest != XFA_AttributeValue::Disabled)
2589       iRet = XFA_EventError::kError;
2590 
2591     if (wsNullMsg.IsEmpty())
2592       return iRet;
2593 
2594     if (eNullTest != XFA_AttributeValue::Disabled) {
2595       pDocView->m_NullTestMsgArray.push_back(wsNullMsg);
2596       return XFA_EventError::kError;
2597     }
2598     return XFA_EventError::kSuccess;
2599   }
2600   if (wsNullMsg.IsEmpty() && bVersionFlag &&
2601       eNullTest != XFA_AttributeValue::Disabled) {
2602     return XFA_EventError::kError;
2603   }
2604   IXFA_AppProvider* pAppProvider =
2605       pDocView->GetDoc()->GetApp()->GetAppProvider();
2606   if (!pAppProvider)
2607     return XFA_EventError::kNotExist;
2608 
2609   WideString wsCaptionName;
2610   WideString wsTitle = pAppProvider->GetAppTitle();
2611   switch (eNullTest) {
2612     case XFA_AttributeValue::Error: {
2613       if (wsNullMsg.IsEmpty()) {
2614         wsCaptionName = GetValidateCaptionName(bVersionFlag);
2615         wsNullMsg = wsCaptionName + L" cannot be blank.";
2616       }
2617       pAppProvider->MsgBox(wsNullMsg, wsTitle,
2618                            static_cast<uint32_t>(AlertIcon::kStatus),
2619                            static_cast<uint32_t>(AlertButton::kOK));
2620       return XFA_EventError::kError;
2621     }
2622     case XFA_AttributeValue::Warning: {
2623       if (IsUserInteractive())
2624         return XFA_EventError::kSuccess;
2625 
2626       if (wsNullMsg.IsEmpty()) {
2627         wsCaptionName = GetValidateCaptionName(bVersionFlag);
2628         wsNullMsg = wsCaptionName +
2629                     L" cannot be blank. To ignore validations for " +
2630                     wsCaptionName + L", click Ignore.";
2631       }
2632       if (pAppProvider->MsgBox(wsNullMsg, wsTitle,
2633                                static_cast<uint32_t>(AlertIcon::kWarning),
2634                                static_cast<uint32_t>(AlertButton::kYesNo)) ==
2635           static_cast<uint32_t>(AlertReturn::kYes)) {
2636         SetFlag(XFA_NodeFlag_UserInteractive);
2637       }
2638       return XFA_EventError::kError;
2639     }
2640     case XFA_AttributeValue::Disabled:
2641     default:
2642       break;
2643   }
2644   return XFA_EventError::kSuccess;
2645 }
2646 
ProcessValidate(CXFA_FFDocView * pDocView,int32_t iFlags)2647 XFA_EventError CXFA_Node::ProcessValidate(CXFA_FFDocView* pDocView,
2648                                           int32_t iFlags) {
2649   if (GetElementType() == XFA_Element::Draw)
2650     return XFA_EventError::kNotExist;
2651 
2652   CXFA_Validate* validate = GetValidateIfExists();
2653   if (!validate)
2654     return XFA_EventError::kNotExist;
2655 
2656   bool bInitDoc = validate->NeedsInitApp();
2657   bool bStatus = pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End;
2658   XFA_EventError iFormat = XFA_EventError::kNotExist;
2659   XFA_EventError iRet = XFA_EventError::kNotExist;
2660   CXFA_Script* script = validate->GetScriptIfExists();
2661   bool bRet = false;
2662   bool hasBoolResult = (bInitDoc || bStatus) && GetRawValue().IsEmpty();
2663   if (script) {
2664     CXFA_EventParam eParam;
2665     eParam.m_eType = XFA_EVENT_Validate;
2666     eParam.m_pTarget = this;
2667     std::tie(iRet, bRet) = ExecuteBoolScript(pDocView, script, &eParam);
2668   }
2669 
2670   XFA_VERSION version = pDocView->GetDoc()->GetXFADoc()->GetCurVersionMode();
2671   bool bVersionFlag = version < XFA_VERSION_208;
2672 
2673   if (bInitDoc) {
2674     validate->ClearFlag(XFA_NodeFlag_NeedsInitApp);
2675   } else {
2676     iFormat = ProcessFormatTestValidate(pDocView, validate, bVersionFlag);
2677     if (!bVersionFlag)
2678       bVersionFlag = pDocView->GetDoc()->GetXFADoc()->is_scripting();
2679     XFA_EventErrorAccumulate(
2680         &iRet,
2681         ProcessNullTestValidate(pDocView, validate, iFlags, bVersionFlag));
2682   }
2683   if (iFormat != XFA_EventError::kSuccess && hasBoolResult)
2684     ProcessScriptTestValidate(pDocView, validate, iRet, bRet, bVersionFlag);
2685 
2686   XFA_EventErrorAccumulate(&iRet, iFormat);
2687   return iRet;
2688 }
2689 
GetValidateCaptionName(bool bVersionFlag)2690 WideString CXFA_Node::GetValidateCaptionName(bool bVersionFlag) {
2691   WideString wsCaptionName;
2692 
2693   if (!bVersionFlag) {
2694     CXFA_Caption* caption = GetCaptionIfExists();
2695     if (caption) {
2696       CXFA_Value* capValue = caption->GetValueIfExists();
2697       if (capValue) {
2698         CXFA_Text* captionText = capValue->GetTextIfExists();
2699         if (captionText)
2700           wsCaptionName = captionText->GetContent();
2701       }
2702     }
2703   }
2704   if (!wsCaptionName.IsEmpty())
2705     return wsCaptionName;
2706   return JSObject()->GetCData(XFA_Attribute::Name);
2707 }
2708 
GetValidateMessage(bool bError,bool bVersionFlag)2709 WideString CXFA_Node::GetValidateMessage(bool bError, bool bVersionFlag) {
2710   WideString wsCaptionName = GetValidateCaptionName(bVersionFlag);
2711   if (bVersionFlag)
2712     return wsCaptionName + L" validation failed";
2713   WideString result =
2714       L"The value you entered for " + wsCaptionName + L" is invalid.";
2715   if (!bError) {
2716     result +=
2717         L" To ignore validations for " + wsCaptionName + L", click Ignore.";
2718   }
2719   return result;
2720 }
2721 
ExecuteScript(CXFA_FFDocView * pDocView,CXFA_Script * script,CXFA_EventParam * pEventParam)2722 XFA_EventError CXFA_Node::ExecuteScript(CXFA_FFDocView* pDocView,
2723                                         CXFA_Script* script,
2724                                         CXFA_EventParam* pEventParam) {
2725   return ExecuteBoolScript(pDocView, script, pEventParam).first;
2726 }
2727 
ExecuteBoolScript(CXFA_FFDocView * pDocView,CXFA_Script * script,CXFA_EventParam * pEventParam)2728 std::pair<XFA_EventError, bool> CXFA_Node::ExecuteBoolScript(
2729     CXFA_FFDocView* pDocView,
2730     CXFA_Script* script,
2731     CXFA_EventParam* pEventParam) {
2732   if (m_ExecuteRecursionDepth > kMaxExecuteRecursion)
2733     return {XFA_EventError::kSuccess, false};
2734 
2735   DCHECK(pEventParam);
2736   if (!script)
2737     return {XFA_EventError::kNotExist, false};
2738   if (script->GetRunAt() == XFA_AttributeValue::Server)
2739     return {XFA_EventError::kDisabled, false};
2740 
2741   WideString wsExpression = script->GetExpression();
2742   if (wsExpression.IsEmpty())
2743     return {XFA_EventError::kNotExist, false};
2744 
2745   CXFA_Script::Type eScriptType = script->GetContentType();
2746   if (eScriptType == CXFA_Script::Type::Unknown)
2747     return {XFA_EventError::kSuccess, false};
2748 
2749   CXFA_FFDoc* pDoc = pDocView->GetDoc();
2750   CFXJSE_Engine* pContext = pDoc->GetXFADoc()->GetScriptContext();
2751   pContext->SetEventParam(pEventParam);
2752   pContext->SetRunAtType(script->GetRunAt());
2753 
2754   std::vector<cppgc::Persistent<CXFA_Node>> refNodes;
2755   if (pEventParam->m_eType == XFA_EVENT_InitCalculate ||
2756       pEventParam->m_eType == XFA_EVENT_Calculate) {
2757     pContext->SetNodesOfRunScript(&refNodes);
2758   }
2759 
2760   auto pTmpRetValue = std::make_unique<CFXJSE_Value>();
2761   bool bRet = false;
2762   {
2763     AutoRestorer<uint8_t> restorer(&m_ExecuteRecursionDepth);
2764     ++m_ExecuteRecursionDepth;
2765     bRet = pContext->RunScript(eScriptType, wsExpression.AsStringView(),
2766                                pTmpRetValue.get(), this);
2767   }
2768 
2769   XFA_EventError iRet = XFA_EventError::kError;
2770   if (bRet) {
2771     iRet = XFA_EventError::kSuccess;
2772     if (pEventParam->m_eType == XFA_EVENT_Calculate ||
2773         pEventParam->m_eType == XFA_EVENT_InitCalculate) {
2774       if (!pTmpRetValue->IsUndefined(pContext->GetIsolate())) {
2775         if (!pTmpRetValue->IsNull(pContext->GetIsolate()))
2776           pEventParam->m_wsResult =
2777               pTmpRetValue->ToWideString(pContext->GetIsolate());
2778 
2779         iRet = XFA_EventError::kSuccess;
2780       } else {
2781         iRet = XFA_EventError::kError;
2782       }
2783       if (pEventParam->m_eType == XFA_EVENT_InitCalculate) {
2784         if ((iRet == XFA_EventError::kSuccess) &&
2785             (GetRawValue() != pEventParam->m_wsResult)) {
2786           SetValue(XFA_VALUEPICTURE_Raw, pEventParam->m_wsResult);
2787           pDocView->AddValidateNode(this);
2788         }
2789       }
2790       for (CXFA_Node* pRefNode : refNodes) {
2791         if (pRefNode == this)
2792           continue;
2793 
2794         CJX_Object::CalcData* pGlobalData =
2795             pRefNode->JSObject()->GetOrCreateCalcData(pDoc->GetHeap());
2796         if (!pdfium::Contains(pGlobalData->m_Globals, this))
2797           pGlobalData->m_Globals.push_back(this);
2798       }
2799     }
2800   }
2801   pContext->SetNodesOfRunScript(nullptr);
2802   pContext->SetEventParam(nullptr);
2803 
2804   return {iRet, pTmpRetValue->IsBoolean(pContext->GetIsolate()) &&
2805                     pTmpRetValue->ToBoolean(pContext->GetIsolate())};
2806 }
2807 
2808 std::pair<XFA_FFWidgetType, CXFA_Ui*>
CreateChildUIAndValueNodesIfNeeded()2809 CXFA_Node::CreateChildUIAndValueNodesIfNeeded() {
2810   XFA_Element eType = GetElementType();
2811   DCHECK(eType == XFA_Element::Field || eType == XFA_Element::Draw);
2812 
2813   // Both Field and Draw have a UI property. We should always be able to
2814   // retrieve or create the UI element. If we can't something is wrong.
2815   CXFA_Ui* pUI = JSObject()->GetOrCreateProperty<CXFA_Ui>(0, XFA_Element::Ui);
2816   DCHECK(pUI);
2817 
2818   CXFA_Node* pUIChild = nullptr;
2819   // Search through the children of the UI node to see if we have any of our
2820   // One-Of entries. If so, that is the node associated with our UI.
2821   for (CXFA_Node* pChild = pUI->GetFirstChild(); pChild;
2822        pChild = pChild->GetNextSibling()) {
2823     if (pUI->IsAOneOfChild(pChild)) {
2824       pUIChild = pChild;
2825       break;
2826     }
2827   }
2828 
2829   XFA_FFWidgetType widget_type = XFA_FFWidgetType::kNone;
2830   XFA_Element expected_ui_child_type = XFA_Element::Unknown;
2831 
2832   // Both Field and Draw nodes have a Value child. So, we should either always
2833   // have it, or always create it. If we don't get the Value child for some
2834   // reason something has gone really wrong.
2835   CXFA_Value* value =
2836       JSObject()->GetOrCreateProperty<CXFA_Value>(0, XFA_Element::Value);
2837   DCHECK(value);
2838 
2839   // The Value nodes only have One-Of children. So, if we have a first child
2840   // that child must be the type we want to use.
2841   CXFA_Node* child = value->GetFirstChild();
2842   if (child) {
2843     switch (child->GetElementType()) {
2844       case XFA_Element::Boolean:
2845         expected_ui_child_type = XFA_Element::CheckButton;
2846         break;
2847       case XFA_Element::Integer:
2848       case XFA_Element::Decimal:
2849       case XFA_Element::Float:
2850         expected_ui_child_type = XFA_Element::NumericEdit;
2851         break;
2852       case XFA_Element::ExData:
2853       case XFA_Element::Text:
2854         expected_ui_child_type = XFA_Element::TextEdit;
2855         widget_type = XFA_FFWidgetType::kText;
2856         break;
2857       case XFA_Element::Date:
2858       case XFA_Element::Time:
2859       case XFA_Element::DateTime:
2860         expected_ui_child_type = XFA_Element::DateTimeEdit;
2861         break;
2862       case XFA_Element::Image:
2863         expected_ui_child_type = XFA_Element::ImageEdit;
2864         widget_type = XFA_FFWidgetType::kImage;
2865         break;
2866       case XFA_Element::Arc:
2867         expected_ui_child_type = XFA_Element::DefaultUi;
2868         widget_type = XFA_FFWidgetType::kArc;
2869         break;
2870       case XFA_Element::Line:
2871         expected_ui_child_type = XFA_Element::DefaultUi;
2872         widget_type = XFA_FFWidgetType::kLine;
2873         break;
2874       case XFA_Element::Rectangle:
2875         expected_ui_child_type = XFA_Element::DefaultUi;
2876         widget_type = XFA_FFWidgetType::kRectangle;
2877         break;
2878       default:
2879         NOTREACHED();
2880         break;
2881     }
2882   }
2883 
2884   if (eType == XFA_Element::Draw) {
2885     if (pUIChild && pUIChild->GetElementType() == XFA_Element::TextEdit) {
2886       widget_type = XFA_FFWidgetType::kText;
2887     } else if (pUIChild &&
2888                pUIChild->GetElementType() == XFA_Element::ImageEdit) {
2889       widget_type = XFA_FFWidgetType::kImage;
2890     } else if (widget_type == XFA_FFWidgetType::kNone) {
2891       widget_type = XFA_FFWidgetType::kText;
2892     }
2893   } else if (eType == XFA_Element::Field) {
2894     if (pUIChild && pUIChild->GetElementType() == XFA_Element::DefaultUi) {
2895       widget_type = XFA_FFWidgetType::kTextEdit;
2896     } else if (pUIChild) {
2897       widget_type = pUIChild->GetDefaultFFWidgetType();
2898     } else if (expected_ui_child_type == XFA_Element::Unknown) {
2899       widget_type = XFA_FFWidgetType::kTextEdit;
2900     }
2901   } else {
2902     NOTREACHED();
2903   }
2904 
2905   if (!pUIChild) {
2906     if (expected_ui_child_type == XFA_Element::Unknown)
2907       expected_ui_child_type = XFA_Element::TextEdit;
2908     pUIChild = pUI->JSObject()->GetOrCreateProperty<CXFA_Node>(
2909         0, expected_ui_child_type);
2910   }
2911 
2912   CreateValueNodeIfNeeded(value, pUIChild);
2913   return {widget_type, pUI};
2914 }
2915 
GetDefaultFFWidgetType() const2916 XFA_FFWidgetType CXFA_Node::GetDefaultFFWidgetType() const {
2917   NOTREACHED();
2918   return XFA_FFWidgetType::kNone;
2919 }
2920 
CreateUINodeIfNeeded(CXFA_Ui * ui,XFA_Element type)2921 CXFA_Node* CXFA_Node::CreateUINodeIfNeeded(CXFA_Ui* ui, XFA_Element type) {
2922   return ui->JSObject()->GetOrCreateProperty<CXFA_Node>(0, type);
2923 }
2924 
CreateValueNodeIfNeeded(CXFA_Value * value,CXFA_Node * pUIChild)2925 void CXFA_Node::CreateValueNodeIfNeeded(CXFA_Value* value,
2926                                         CXFA_Node* pUIChild) {
2927   // Value nodes only have one child. If we have one already we're done.
2928   if (value->GetFirstChild())
2929     return;
2930 
2931   // Create the Value node for our UI if needed.
2932   XFA_Element valueType = pUIChild->GetValueNodeType();
2933   if (pUIChild->GetElementType() == XFA_Element::CheckButton) {
2934     CXFA_Items* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
2935     if (pItems) {
2936       CXFA_Node* pItem =
2937           pItems->GetChild<CXFA_Node>(0, XFA_Element::Unknown, false);
2938       if (pItem)
2939         valueType = pItem->GetElementType();
2940     }
2941   }
2942   value->JSObject()->GetOrCreateProperty<CXFA_Node>(0, valueType);
2943 }
2944 
GetValueNodeType() const2945 XFA_Element CXFA_Node::GetValueNodeType() const {
2946   return XFA_Element::Text;
2947 }
2948 
GetUIChildNode()2949 CXFA_Node* CXFA_Node::GetUIChildNode() {
2950   DCHECK(HasCreatedUIWidget());
2951 
2952   if (ff_widget_type_ != XFA_FFWidgetType::kNone)
2953     return ui_ ? ui_->GetFirstChild() : nullptr;
2954 
2955   XFA_Element type = GetElementType();
2956   if (type == XFA_Element::Field || type == XFA_Element::Draw) {
2957     std::tie(ff_widget_type_, ui_) = CreateChildUIAndValueNodesIfNeeded();
2958   } else if (type == XFA_Element::Subform) {
2959     ff_widget_type_ = XFA_FFWidgetType::kSubform;
2960   } else if (type == XFA_Element::ExclGroup) {
2961     ff_widget_type_ = XFA_FFWidgetType::kExclGroup;
2962   } else {
2963     NOTREACHED();
2964   }
2965   return ui_ ? ui_->GetFirstChild() : nullptr;
2966 }
2967 
GetFFWidgetType()2968 XFA_FFWidgetType CXFA_Node::GetFFWidgetType() {
2969   GetUIChildNode();
2970   return ff_widget_type_;
2971 }
2972 
GetUIBorder()2973 CXFA_Border* CXFA_Node::GetUIBorder() {
2974   CXFA_Node* pUIChild = GetUIChildNode();
2975   return pUIChild ? pUIChild->JSObject()->GetProperty<CXFA_Border>(
2976                         0, XFA_Element::Border)
2977                   : nullptr;
2978 }
2979 
GetUIMargin()2980 CFX_RectF CXFA_Node::GetUIMargin() {
2981   CXFA_Node* pUIChild = GetUIChildNode();
2982   if (!pUIChild)
2983     return CFX_RectF();
2984 
2985   CXFA_Margin* mgUI =
2986       pUIChild->JSObject()->GetProperty<CXFA_Margin>(0, XFA_Element::Margin);
2987   if (!mgUI)
2988     return CFX_RectF();
2989 
2990   CXFA_Border* border = GetUIBorder();
2991   if (border && border->GetPresence() != XFA_AttributeValue::Visible)
2992     return CFX_RectF();
2993 
2994   Optional<float> left = mgUI->TryLeftInset();
2995   Optional<float> top = mgUI->TryTopInset();
2996   Optional<float> right = mgUI->TryRightInset();
2997   Optional<float> bottom = mgUI->TryBottomInset();
2998   if (border) {
2999     bool bVisible = false;
3000     float fThickness = 0;
3001     XFA_AttributeValue iType = XFA_AttributeValue::Unknown;
3002     std::tie(iType, bVisible, fThickness) = border->Get3DStyle();
3003     if (!left || !top || !right || !bottom) {
3004       std::vector<CXFA_Stroke*> strokes = border->GetStrokes();
3005       if (!top)
3006         top = GetEdgeThickness(strokes, bVisible, 0);
3007       if (!right)
3008         right = GetEdgeThickness(strokes, bVisible, 1);
3009       if (!bottom)
3010         bottom = GetEdgeThickness(strokes, bVisible, 2);
3011       if (!left)
3012         left = GetEdgeThickness(strokes, bVisible, 3);
3013     }
3014   }
3015   return CFX_RectF(left.value_or(0.0), top.value_or(0.0), right.value_or(0.0),
3016                    bottom.value_or(0.0));
3017 }
3018 
GetEventByActivity(XFA_AttributeValue iActivity,bool bIsFormReady)3019 std::vector<CXFA_Event*> CXFA_Node::GetEventByActivity(
3020     XFA_AttributeValue iActivity,
3021     bool bIsFormReady) {
3022   std::vector<CXFA_Event*> events;
3023   for (CXFA_Node* node : GetNodeListForType(XFA_Element::Event)) {
3024     auto* event = static_cast<CXFA_Event*>(node);
3025     if (event->GetActivity() != iActivity)
3026       continue;
3027 
3028     if (iActivity != XFA_AttributeValue::Ready) {
3029       events.push_back(event);
3030       continue;
3031     }
3032 
3033     WideString wsRef = event->GetRef();
3034     if (bIsFormReady) {
3035       if (wsRef == WideStringView(L"$form"))
3036         events.push_back(event);
3037       continue;
3038     }
3039 
3040     if (wsRef == WideStringView(L"$layout"))
3041       events.push_back(event);
3042   }
3043   return events;
3044 }
3045 
ResetData()3046 void CXFA_Node::ResetData() {
3047   WideString wsValue;
3048   switch (GetFFWidgetType()) {
3049     case XFA_FFWidgetType::kImageEdit: {
3050       CXFA_Value* imageValue = GetDefaultValueIfExists();
3051       CXFA_Image* image = imageValue ? imageValue->GetImageIfExists() : nullptr;
3052       WideString wsContentType, wsHref;
3053       if (image) {
3054         wsValue = image->GetContent();
3055         wsContentType = image->GetContentType();
3056         wsHref = image->GetHref();
3057       }
3058       SetImageEdit(wsContentType, wsHref, wsValue);
3059       break;
3060     }
3061     case XFA_FFWidgetType::kExclGroup: {
3062       CXFA_Node* pNextChild = GetFirstContainerChild();
3063       while (pNextChild) {
3064         CXFA_Node* pChild = pNextChild;
3065         if (!pChild->IsWidgetReady())
3066           continue;
3067 
3068         bool done = false;
3069         if (wsValue.IsEmpty()) {
3070           CXFA_Value* defValue = pChild->GetDefaultValueIfExists();
3071           if (defValue) {
3072             wsValue = defValue->GetChildValueContent();
3073             SetValue(XFA_VALUEPICTURE_Raw, wsValue);
3074             pChild->SetValue(XFA_VALUEPICTURE_Raw, wsValue);
3075             done = true;
3076           }
3077         }
3078         if (!done) {
3079           CXFA_Items* pItems =
3080               pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3081           if (!pItems)
3082             continue;
3083 
3084           WideString itemText;
3085           if (pItems->CountChildren(XFA_Element::Unknown, false) > 1) {
3086             itemText =
3087                 pItems->GetChild<CXFA_Node>(1, XFA_Element::Unknown, false)
3088                     ->JSObject()
3089                     ->GetContent(false);
3090           }
3091           pChild->SetValue(XFA_VALUEPICTURE_Raw, itemText);
3092         }
3093         pNextChild = pChild->GetNextContainerSibling();
3094       }
3095       break;
3096     }
3097     case XFA_FFWidgetType::kChoiceList:
3098       ClearAllSelections();
3099       FALLTHROUGH;
3100     default: {
3101       CXFA_Value* defValue = GetDefaultValueIfExists();
3102       if (defValue)
3103         wsValue = defValue->GetChildValueContent();
3104 
3105       SetValue(XFA_VALUEPICTURE_Raw, wsValue);
3106       break;
3107     }
3108   }
3109 }
3110 
SetImageEdit(const WideString & wsContentType,const WideString & wsHref,const WideString & wsData)3111 void CXFA_Node::SetImageEdit(const WideString& wsContentType,
3112                              const WideString& wsHref,
3113                              const WideString& wsData) {
3114   CXFA_Value* formValue = GetFormValueIfExists();
3115   CXFA_Image* image = formValue ? formValue->GetImageIfExists() : nullptr;
3116   if (image) {
3117     image->SetContentType(WideString(wsContentType));
3118     image->SetHref(wsHref);
3119   }
3120 
3121   JSObject()->SetContent(wsData, GetFormatDataValue(wsData), true, false, true);
3122 
3123   CXFA_Node* pBind = GetBindData();
3124   if (!pBind) {
3125     if (image)
3126       image->SetTransferEncoding(XFA_AttributeValue::Base64);
3127     return;
3128   }
3129   pBind->JSObject()->SetCData(XFA_Attribute::ContentType, wsContentType);
3130   CXFA_Node* pHrefNode = pBind->GetFirstChild();
3131   if (pHrefNode) {
3132     pHrefNode->JSObject()->SetCData(XFA_Attribute::Value, wsHref);
3133     return;
3134   }
3135   CFX_XMLElement* pElement = ToXMLElement(pBind->GetXMLMappingNode());
3136   pElement->SetAttribute(L"href", wsHref);
3137 }
3138 
CalcCaptionSize(CXFA_FFDoc * doc,CFX_SizeF * pszCap)3139 void CXFA_Node::CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF* pszCap) {
3140   CXFA_Caption* caption = GetCaptionIfExists();
3141   if (!caption || !caption->IsVisible())
3142     return;
3143 
3144   LoadCaption(doc);
3145 
3146   const float fCapReserve = caption->GetReserve();
3147   const XFA_AttributeValue iCapPlacement = caption->GetPlacementType();
3148   const bool bReserveExit = fCapReserve > 0.01;
3149   const bool bVert = iCapPlacement == XFA_AttributeValue::Top ||
3150                      iCapPlacement == XFA_AttributeValue::Bottom;
3151   CXFA_TextLayout* pCapTextLayout =
3152       m_pLayoutData->AsFieldLayoutData()->m_pCapTextLayout;
3153   if (pCapTextLayout) {
3154     if (!bVert && GetFFWidgetType() != XFA_FFWidgetType::kButton)
3155       pszCap->width = fCapReserve;
3156 
3157     CFX_SizeF minSize;
3158     *pszCap = pCapTextLayout->CalcSize(minSize, *pszCap);
3159     if (bReserveExit)
3160       bVert ? pszCap->height = fCapReserve : pszCap->width = fCapReserve;
3161   } else {
3162     float fFontSize = 10.0f;
3163     CXFA_Font* font = caption->GetFontIfExists();
3164     if (font) {
3165       fFontSize = font->GetFontSize();
3166     } else {
3167       CXFA_Font* widgetfont = GetFontIfExists();
3168       if (widgetfont)
3169         fFontSize = widgetfont->GetFontSize();
3170     }
3171 
3172     if (bVert) {
3173       pszCap->height = fCapReserve > 0 ? fCapReserve : fFontSize;
3174     } else {
3175       pszCap->width = fCapReserve > 0 ? fCapReserve : 0;
3176       pszCap->height = fFontSize;
3177     }
3178   }
3179 
3180   CXFA_Margin* captionMargin = caption->GetMarginIfExists();
3181   if (!captionMargin)
3182     return;
3183 
3184   float fLeftInset = captionMargin->GetLeftInset();
3185   float fTopInset = captionMargin->GetTopInset();
3186   float fRightInset = captionMargin->GetRightInset();
3187   float fBottomInset = captionMargin->GetBottomInset();
3188   if (bReserveExit) {
3189     bVert ? (pszCap->width += fLeftInset + fRightInset)
3190           : (pszCap->height += fTopInset + fBottomInset);
3191   } else {
3192     pszCap->width += fLeftInset + fRightInset;
3193     pszCap->height += fTopInset + fBottomInset;
3194   }
3195 }
3196 
CalculateFieldAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3197 bool CXFA_Node::CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3198   CFX_SizeF szCap;
3199   CalcCaptionSize(doc, &szCap);
3200 
3201   CFX_RectF rtUIMargin = GetUIMargin();
3202   pSize->width += rtUIMargin.left + rtUIMargin.width;
3203   pSize->height += rtUIMargin.top + rtUIMargin.height;
3204   if (szCap.width > 0 && szCap.height > 0) {
3205     CXFA_Caption* caption = GetCaptionIfExists();
3206     XFA_AttributeValue placement = caption
3207                                        ? caption->GetPlacementType()
3208                                        : CXFA_Caption::kDefaultPlacementType;
3209     switch (placement) {
3210       case XFA_AttributeValue::Left:
3211       case XFA_AttributeValue::Right:
3212       case XFA_AttributeValue::Inline: {
3213         pSize->width += szCap.width;
3214         pSize->height = std::max(pSize->height, szCap.height);
3215       } break;
3216       case XFA_AttributeValue::Top:
3217       case XFA_AttributeValue::Bottom: {
3218         pSize->height += szCap.height;
3219         pSize->width = std::max(pSize->width, szCap.width);
3220         break;
3221       }
3222       default:
3223         break;
3224     }
3225   }
3226   return CalculateWidgetAutoSize(pSize);
3227 }
3228 
CalculateWidgetAutoSize(CFX_SizeF * pSize)3229 bool CXFA_Node::CalculateWidgetAutoSize(CFX_SizeF* pSize) {
3230   CXFA_Margin* margin = GetMarginIfExists();
3231   if (margin) {
3232     pSize->width += margin->GetLeftInset() + margin->GetRightInset();
3233     pSize->height += margin->GetTopInset() + margin->GetBottomInset();
3234   }
3235 
3236   CXFA_Para* para = GetParaIfExists();
3237   if (para)
3238     pSize->width += para->GetMarginLeft() + para->GetTextIndent();
3239 
3240   Optional<float> width = TryWidth();
3241   if (width) {
3242     pSize->width = *width;
3243   } else {
3244     Optional<float> min = TryMinWidth();
3245     if (min)
3246       pSize->width = std::max(pSize->width, *min);
3247 
3248     Optional<float> max = TryMaxWidth();
3249     if (max && *max > 0)
3250       pSize->width = std::min(pSize->width, *max);
3251   }
3252 
3253   Optional<float> height = TryHeight();
3254   if (height) {
3255     pSize->height = *height;
3256   } else {
3257     Optional<float> min = TryMinHeight();
3258     if (min)
3259       pSize->height = std::max(pSize->height, *min);
3260 
3261     Optional<float> max = TryMaxHeight();
3262     if (max && *max > 0)
3263       pSize->height = std::min(pSize->height, *max);
3264   }
3265   return true;
3266 }
3267 
CalculateTextContentSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3268 void CXFA_Node::CalculateTextContentSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3269   float fFontSize = GetFontSize();
3270   WideString wsText = GetValue(XFA_VALUEPICTURE_Display);
3271   if (wsText.IsEmpty()) {
3272     pSize->height += fFontSize;
3273     return;
3274   }
3275 
3276   if (wsText.Back() == L'\n')
3277     wsText += L'\n';
3278 
3279   CXFA_FieldLayoutData* layoutData = m_pLayoutData->AsFieldLayoutData();
3280   if (!layoutData->m_pTextOut) {
3281     layoutData->m_pTextOut = std::make_unique<CFDE_TextOut>();
3282     CFDE_TextOut* pTextOut = layoutData->m_pTextOut.get();
3283     pTextOut->SetFont(GetFGASFont(doc));
3284     pTextOut->SetFontSize(fFontSize);
3285     pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
3286     pTextOut->SetLineSpace(GetLineHeight());
3287 
3288     FDE_TextStyle dwStyles;
3289     dwStyles.last_line_height_ = true;
3290     if (GetFFWidgetType() == XFA_FFWidgetType::kTextEdit && IsMultiLine())
3291       dwStyles.line_wrap_ = true;
3292 
3293     pTextOut->SetStyles(dwStyles);
3294   }
3295   layoutData->m_pTextOut->CalcLogicSize(wsText.AsStringView(), pSize);
3296 }
3297 
CalculateTextEditAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3298 bool CXFA_Node::CalculateTextEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3299   if (pSize->width > 0) {
3300     CFX_SizeF szOrz = *pSize;
3301     CFX_SizeF szCap;
3302     CalcCaptionSize(doc, &szCap);
3303     bool bCapExit = szCap.width > 0.01 && szCap.height > 0.01;
3304     XFA_AttributeValue iCapPlacement = XFA_AttributeValue::Unknown;
3305     if (bCapExit) {
3306       CXFA_Caption* caption = GetCaptionIfExists();
3307       iCapPlacement = caption ? caption->GetPlacementType()
3308                               : CXFA_Caption::kDefaultPlacementType;
3309       switch (iCapPlacement) {
3310         case XFA_AttributeValue::Left:
3311         case XFA_AttributeValue::Right:
3312         case XFA_AttributeValue::Inline: {
3313           pSize->width -= szCap.width;
3314           break;
3315         }
3316         default:
3317           break;
3318       }
3319     }
3320     CFX_RectF rtUIMargin = GetUIMargin();
3321     pSize->width -= rtUIMargin.left + rtUIMargin.width;
3322     CXFA_Margin* margin = GetMarginIfExists();
3323     if (margin)
3324       pSize->width -= margin->GetLeftInset() + margin->GetRightInset();
3325 
3326     CalculateTextContentSize(doc, pSize);
3327     pSize->height += rtUIMargin.top + rtUIMargin.height;
3328     if (bCapExit) {
3329       switch (iCapPlacement) {
3330         case XFA_AttributeValue::Left:
3331         case XFA_AttributeValue::Right:
3332         case XFA_AttributeValue::Inline: {
3333           pSize->height = std::max(pSize->height, szCap.height);
3334         } break;
3335         case XFA_AttributeValue::Top:
3336         case XFA_AttributeValue::Bottom: {
3337           pSize->height += szCap.height;
3338           break;
3339         }
3340         default:
3341           break;
3342       }
3343     }
3344     pSize->width = szOrz.width;
3345     return CalculateWidgetAutoSize(pSize);
3346   }
3347   CalculateTextContentSize(doc, pSize);
3348   return CalculateFieldAutoSize(doc, pSize);
3349 }
3350 
CalculateCheckButtonAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3351 bool CXFA_Node::CalculateCheckButtonAutoSize(CXFA_FFDoc* doc,
3352                                              CFX_SizeF* pSize) {
3353   float fCheckSize = GetCheckButtonSize();
3354   *pSize = CFX_SizeF(fCheckSize, fCheckSize);
3355   return CalculateFieldAutoSize(doc, pSize);
3356 }
3357 
CalculatePushButtonAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3358 bool CXFA_Node::CalculatePushButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3359   CalcCaptionSize(doc, pSize);
3360   return CalculateWidgetAutoSize(pSize);
3361 }
3362 
CalculateImageSize(float img_width,float img_height,const CFX_Size & dpi)3363 CFX_SizeF CXFA_Node::CalculateImageSize(float img_width,
3364                                         float img_height,
3365                                         const CFX_Size& dpi) {
3366   CFX_RectF rtImage(0, 0, XFA_UnitPx2Pt(img_width, dpi.width),
3367                     XFA_UnitPx2Pt(img_height, dpi.height));
3368 
3369   CFX_RectF rtFit;
3370   Optional<float> width = TryWidth();
3371   if (width) {
3372     rtFit.width = *width;
3373     GetWidthWithoutMargin(rtFit.width);
3374   } else {
3375     rtFit.width = rtImage.width;
3376   }
3377 
3378   Optional<float> height = TryHeight();
3379   if (height) {
3380     rtFit.height = *height;
3381     GetHeightWithoutMargin(rtFit.height);
3382   } else {
3383     rtFit.height = rtImage.height;
3384   }
3385 
3386   return rtFit.Size();
3387 }
3388 
CalculateImageAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3389 bool CXFA_Node::CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3390   if (!GetImageImage())
3391     LoadImageImage(doc);
3392 
3393   pSize->clear();
3394   RetainPtr<CFX_DIBitmap> pBitmap = GetImageImage();
3395   if (!pBitmap)
3396     return CalculateWidgetAutoSize(pSize);
3397 
3398   *pSize = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
3399                               GetImageDpi());
3400   return CalculateWidgetAutoSize(pSize);
3401 }
3402 
CalculateImageEditAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3403 bool CXFA_Node::CalculateImageEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3404   if (!GetImageEditImage())
3405     LoadImageEditImage(doc);
3406 
3407   pSize->clear();
3408   RetainPtr<CFX_DIBitmap> pBitmap = GetImageEditImage();
3409   if (!pBitmap)
3410     return CalculateFieldAutoSize(doc, pSize);
3411 
3412   *pSize = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
3413                               GetImageEditDpi());
3414   return CalculateFieldAutoSize(doc, pSize);
3415 }
3416 
LoadImageImage(CXFA_FFDoc * doc)3417 bool CXFA_Node::LoadImageImage(CXFA_FFDoc* doc) {
3418   InitLayoutData(doc);
3419   return m_pLayoutData->AsImageLayoutData()->LoadImageData(doc, this);
3420 }
3421 
LoadImageEditImage(CXFA_FFDoc * doc)3422 bool CXFA_Node::LoadImageEditImage(CXFA_FFDoc* doc) {
3423   InitLayoutData(doc);
3424   return m_pLayoutData->AsFieldLayoutData()->AsImageEditData()->LoadImageData(
3425       doc, this);
3426 }
3427 
GetImageDpi() const3428 CFX_Size CXFA_Node::GetImageDpi() const {
3429   CXFA_ImageLayoutData* pData = m_pLayoutData->AsImageLayoutData();
3430   return CFX_Size(pData->m_iImageXDpi, pData->m_iImageYDpi);
3431 }
3432 
GetImageEditDpi() const3433 CFX_Size CXFA_Node::GetImageEditDpi() const {
3434   CXFA_ImageEditData* pData =
3435       m_pLayoutData->AsFieldLayoutData()->AsImageEditData();
3436   return CFX_Size(pData->m_iImageXDpi, pData->m_iImageYDpi);
3437 }
3438 
CalculateWidgetAutoWidth(float fWidthCalc)3439 float CXFA_Node::CalculateWidgetAutoWidth(float fWidthCalc) {
3440   CXFA_Margin* margin = GetMarginIfExists();
3441   if (margin)
3442     fWidthCalc += margin->GetLeftInset() + margin->GetRightInset();
3443 
3444   Optional<float> min = TryMinWidth();
3445   if (min)
3446     fWidthCalc = std::max(fWidthCalc, *min);
3447 
3448   Optional<float> max = TryMaxWidth();
3449   if (max && *max > 0)
3450     fWidthCalc = std::min(fWidthCalc, *max);
3451 
3452   return fWidthCalc;
3453 }
3454 
GetWidthWithoutMargin(float fWidthCalc) const3455 float CXFA_Node::GetWidthWithoutMargin(float fWidthCalc) const {
3456   CXFA_Margin* margin = GetMarginIfExists();
3457   if (margin)
3458     fWidthCalc -= margin->GetLeftInset() + margin->GetRightInset();
3459   return fWidthCalc;
3460 }
3461 
CalculateWidgetAutoHeight(float fHeightCalc)3462 float CXFA_Node::CalculateWidgetAutoHeight(float fHeightCalc) {
3463   CXFA_Margin* margin = GetMarginIfExists();
3464   if (margin)
3465     fHeightCalc += margin->GetTopInset() + margin->GetBottomInset();
3466 
3467   Optional<float> min = TryMinHeight();
3468   if (min)
3469     fHeightCalc = std::max(fHeightCalc, *min);
3470 
3471   Optional<float> max = TryMaxHeight();
3472   if (max && *max > 0)
3473     fHeightCalc = std::min(fHeightCalc, *max);
3474 
3475   return fHeightCalc;
3476 }
3477 
GetHeightWithoutMargin(float fHeightCalc) const3478 float CXFA_Node::GetHeightWithoutMargin(float fHeightCalc) const {
3479   CXFA_Margin* margin = GetMarginIfExists();
3480   if (margin)
3481     fHeightCalc -= margin->GetTopInset() + margin->GetBottomInset();
3482   return fHeightCalc;
3483 }
3484 
StartWidgetLayout(CXFA_FFDoc * doc,float * pCalcWidth,float * pCalcHeight)3485 void CXFA_Node::StartWidgetLayout(CXFA_FFDoc* doc,
3486                                   float* pCalcWidth,
3487                                   float* pCalcHeight) {
3488   InitLayoutData(doc);
3489 
3490   if (GetFFWidgetType() == XFA_FFWidgetType::kText) {
3491     m_pLayoutData->m_fWidgetHeight = TryHeight().value_or(-1);
3492     StartTextLayout(doc, pCalcWidth, pCalcHeight);
3493     return;
3494   }
3495   if (*pCalcWidth > 0 && *pCalcHeight > 0)
3496     return;
3497 
3498   m_pLayoutData->m_fWidgetHeight = -1;
3499   float fWidth = 0;
3500   if (*pCalcWidth > 0 && *pCalcHeight < 0) {
3501     Optional<float> height = TryHeight();
3502     if (height) {
3503       *pCalcHeight = *height;
3504     } else {
3505       CFX_SizeF size = CalculateAccWidthAndHeight(doc, *pCalcWidth);
3506       *pCalcWidth = size.width;
3507       *pCalcHeight = size.height;
3508     }
3509 
3510     m_pLayoutData->m_fWidgetHeight = *pCalcHeight;
3511     return;
3512   }
3513   if (*pCalcWidth < 0 && *pCalcHeight < 0) {
3514     Optional<float> height;
3515     Optional<float> width = TryWidth();
3516     if (width) {
3517       fWidth = *width;
3518 
3519       height = TryHeight();
3520       if (height)
3521         *pCalcHeight = *height;
3522     }
3523     if (!width || !height) {
3524       CFX_SizeF size = CalculateAccWidthAndHeight(doc, fWidth);
3525       *pCalcWidth = size.width;
3526       *pCalcHeight = size.height;
3527     } else {
3528       *pCalcWidth = fWidth;
3529     }
3530   }
3531   m_pLayoutData->m_fWidgetHeight = *pCalcHeight;
3532 }
3533 
CalculateAccWidthAndHeight(CXFA_FFDoc * doc,float fWidth)3534 CFX_SizeF CXFA_Node::CalculateAccWidthAndHeight(CXFA_FFDoc* doc, float fWidth) {
3535   CFX_SizeF sz(fWidth, m_pLayoutData->m_fWidgetHeight);
3536   switch (GetFFWidgetType()) {
3537     case XFA_FFWidgetType::kBarcode:
3538     case XFA_FFWidgetType::kChoiceList:
3539     case XFA_FFWidgetType::kSignature:
3540       CalculateFieldAutoSize(doc, &sz);
3541       break;
3542     case XFA_FFWidgetType::kImageEdit:
3543       CalculateImageEditAutoSize(doc, &sz);
3544       break;
3545     case XFA_FFWidgetType::kButton:
3546       CalculatePushButtonAutoSize(doc, &sz);
3547       break;
3548     case XFA_FFWidgetType::kCheckButton:
3549       CalculateCheckButtonAutoSize(doc, &sz);
3550       break;
3551     case XFA_FFWidgetType::kDateTimeEdit:
3552     case XFA_FFWidgetType::kNumericEdit:
3553     case XFA_FFWidgetType::kPasswordEdit:
3554     case XFA_FFWidgetType::kTextEdit:
3555       CalculateTextEditAutoSize(doc, &sz);
3556       break;
3557     case XFA_FFWidgetType::kImage:
3558       CalculateImageAutoSize(doc, &sz);
3559       break;
3560     case XFA_FFWidgetType::kArc:
3561     case XFA_FFWidgetType::kLine:
3562     case XFA_FFWidgetType::kRectangle:
3563     case XFA_FFWidgetType::kSubform:
3564     case XFA_FFWidgetType::kExclGroup:
3565       CalculateWidgetAutoSize(&sz);
3566       break;
3567     case XFA_FFWidgetType::kText:
3568     case XFA_FFWidgetType::kNone:
3569       break;
3570   }
3571 
3572   m_pLayoutData->m_fWidgetHeight = sz.height;
3573   return sz;
3574 }
3575 
FindSplitPos(CXFA_FFDocView * pDocView,size_t szBlockIndex,float fCalcHeight)3576 Optional<float> CXFA_Node::FindSplitPos(CXFA_FFDocView* pDocView,
3577                                         size_t szBlockIndex,
3578                                         float fCalcHeight) {
3579   if (GetFFWidgetType() == XFA_FFWidgetType::kSubform)
3580     return pdfium::nullopt;
3581 
3582   switch (GetFFWidgetType()) {
3583     case XFA_FFWidgetType::kText:
3584     case XFA_FFWidgetType::kTextEdit:
3585     case XFA_FFWidgetType::kNumericEdit:
3586     case XFA_FFWidgetType::kPasswordEdit:
3587       break;
3588     default:
3589       return 0.0f;
3590   }
3591 
3592   float fTopInset = 0;
3593   float fBottomInset = 0;
3594   if (szBlockIndex == 0) {
3595     CXFA_Margin* margin = GetMarginIfExists();
3596     if (margin) {
3597       fTopInset = margin->GetTopInset();
3598       fBottomInset = margin->GetBottomInset();
3599     }
3600 
3601     CFX_RectF rtUIMargin = GetUIMargin();
3602     fTopInset += rtUIMargin.top;
3603     fBottomInset += rtUIMargin.width;
3604   }
3605   if (GetFFWidgetType() == XFA_FFWidgetType::kText) {
3606     float fHeight = fCalcHeight;
3607     if (szBlockIndex == 0) {
3608       fCalcHeight -= fTopInset;
3609       fCalcHeight = std::max(fCalcHeight, 0.0f);
3610     }
3611     CXFA_TextLayout* pTextLayout =
3612         m_pLayoutData->AsTextLayoutData()->GetTextLayout();
3613     fCalcHeight = pTextLayout->DoSplitLayout(
3614         szBlockIndex, fCalcHeight, m_pLayoutData->m_fWidgetHeight - fTopInset);
3615     if (fCalcHeight != 0) {
3616       if (szBlockIndex == 0)
3617         fCalcHeight += fTopInset;
3618       if (fabs(fHeight - fCalcHeight) < kXFAWidgetPrecision)
3619         return pdfium::nullopt;
3620     }
3621     return fCalcHeight;
3622   }
3623 
3624   XFA_AttributeValue iCapPlacement = XFA_AttributeValue::Unknown;
3625   float fCapReserve = 0;
3626   if (szBlockIndex == 0) {
3627     CXFA_Caption* caption = GetCaptionIfExists();
3628     if (caption && !caption->IsHidden()) {
3629       iCapPlacement = caption->GetPlacementType();
3630       fCapReserve = caption->GetReserve();
3631     }
3632     if (iCapPlacement == XFA_AttributeValue::Top &&
3633         fCalcHeight < fCapReserve + fTopInset) {
3634       return 0.0f;
3635     }
3636     if (iCapPlacement == XFA_AttributeValue::Bottom &&
3637         m_pLayoutData->m_fWidgetHeight - fCapReserve - fBottomInset) {
3638       return 0.0f;
3639     }
3640     if (iCapPlacement != XFA_AttributeValue::Top)
3641       fCapReserve = 0;
3642   }
3643   CXFA_FieldLayoutData* pFieldData = m_pLayoutData->AsFieldLayoutData();
3644   int32_t iLinesCount = 0;
3645   float fHeight = m_pLayoutData->m_fWidgetHeight;
3646   if (GetValue(XFA_VALUEPICTURE_Display).IsEmpty()) {
3647     iLinesCount = 1;
3648   } else {
3649     if (!pFieldData->m_pTextOut) {
3650       CFX_SizeF size = CalculateAccWidthAndHeight(pDocView->GetDoc(),
3651                                                   TryWidth().value_or(0));
3652       fHeight = size.height;
3653     }
3654 
3655     iLinesCount = pFieldData->m_pTextOut->GetTotalLines();
3656   }
3657   std::vector<float>* pFieldArray = &pFieldData->m_FieldSplitArray;
3658   size_t szFieldSplitCount = pFieldArray->size();
3659   if (szFieldSplitCount < szBlockIndex * 3)
3660     return pdfium::nullopt;
3661 
3662   for (size_t i = 0; i < szBlockIndex * 3; i += 3) {
3663     iLinesCount -= (int32_t)(*pFieldArray)[i + 1];
3664     fHeight -= (*pFieldArray)[i + 2];
3665   }
3666   if (iLinesCount == 0)
3667     return pdfium::nullopt;
3668 
3669   float fLineHeight = GetLineHeight();
3670   float fFontSize = GetFontSize();
3671   float fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
3672   float fSpaceAbove = 0;
3673   float fStartOffset = 0;
3674   if (fHeight > 0.1f && szBlockIndex == 0) {
3675     fStartOffset = fTopInset;
3676     fHeight -= (fTopInset + fBottomInset);
3677     CXFA_Para* para = GetParaIfExists();
3678     if (para) {
3679       fSpaceAbove = para->GetSpaceAbove();
3680       float fSpaceBelow = para->GetSpaceBelow();
3681       fHeight -= (fSpaceAbove + fSpaceBelow);
3682       switch (para->GetVerticalAlign()) {
3683         case XFA_AttributeValue::Top:
3684           fStartOffset += fSpaceAbove;
3685           break;
3686         case XFA_AttributeValue::Middle:
3687           fStartOffset += ((fHeight - fTextHeight) / 2 + fSpaceAbove);
3688           break;
3689         case XFA_AttributeValue::Bottom:
3690           fStartOffset += (fHeight - fTextHeight + fSpaceAbove);
3691           break;
3692         default:
3693           NOTREACHED();
3694           break;
3695       }
3696     }
3697     if (fStartOffset < 0.1f)
3698       fStartOffset = 0;
3699   }
3700   if (szBlockIndex > 0) {
3701     size_t i = szBlockIndex - 1;
3702     fStartOffset = (*pFieldArray)[i * 3] - (*pFieldArray)[i * 3 + 2];
3703     if (fStartOffset < 0.1f)
3704       fStartOffset = 0;
3705   }
3706   if (szFieldSplitCount / 3 == (szBlockIndex + 1))
3707     (*pFieldArray)[0] = fStartOffset;
3708   else
3709     pFieldArray->push_back(fStartOffset);
3710 
3711   XFA_VERSION version = pDocView->GetDoc()->GetXFADoc()->GetCurVersionMode();
3712   bool bCanSplitNoContent = false;
3713   auto value = GetParent()->JSObject()->TryEnum(XFA_Attribute::Layout, true);
3714   XFA_AttributeValue eLayoutMode = value.value_or(XFA_AttributeValue::Position);
3715   if ((eLayoutMode == XFA_AttributeValue::Position ||
3716        eLayoutMode == XFA_AttributeValue::Tb ||
3717        eLayoutMode == XFA_AttributeValue::Row ||
3718        eLayoutMode == XFA_AttributeValue::Table) &&
3719       version > XFA_VERSION_208) {
3720     bCanSplitNoContent = true;
3721   }
3722   if ((eLayoutMode == XFA_AttributeValue::Tb ||
3723        eLayoutMode == XFA_AttributeValue::Row ||
3724        eLayoutMode == XFA_AttributeValue::Table) &&
3725       version <= XFA_VERSION_208) {
3726     if (fStartOffset >= fCalcHeight)
3727       return 0.0f;
3728 
3729     bCanSplitNoContent = true;
3730   }
3731   if (!bCanSplitNoContent ||
3732       fCalcHeight - fTopInset - fSpaceAbove < fLineHeight) {
3733     return 0.0f;
3734   }
3735 
3736   if (fStartOffset + kXFAWidgetPrecision >= fCalcHeight) {
3737     if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3738       (*pFieldArray)[szBlockIndex * 3 + 1] = 0;
3739       (*pFieldArray)[szBlockIndex * 3 + 2] = fCalcHeight;
3740     } else {
3741       pFieldArray->push_back(0);
3742       pFieldArray->push_back(fCalcHeight);
3743     }
3744     return pdfium::nullopt;
3745   }
3746 
3747   if (fCalcHeight - fStartOffset < fLineHeight) {
3748     fCalcHeight = fStartOffset;
3749     if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3750       (*pFieldArray)[szBlockIndex * 3 + 1] = 0;
3751       (*pFieldArray)[szBlockIndex * 3 + 2] = fCalcHeight;
3752     } else {
3753       pFieldArray->push_back(0);
3754       pFieldArray->push_back(fCalcHeight);
3755     }
3756     return fCalcHeight;
3757   }
3758 
3759   float fTextNum =
3760       fCalcHeight + kXFAWidgetPrecision - fCapReserve - fStartOffset;
3761   int32_t iLineNum =
3762       (int32_t)((fTextNum + (fLineHeight - fFontSize)) / fLineHeight);
3763   if (iLineNum >= iLinesCount) {
3764     if (fCalcHeight - fStartOffset - fTextHeight >= fFontSize) {
3765       if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3766         (*pFieldArray)[szBlockIndex * 3 + 1] = iLinesCount;
3767         (*pFieldArray)[szBlockIndex * 3 + 2] = fCalcHeight;
3768       } else {
3769         pFieldArray->push_back(iLinesCount);
3770         pFieldArray->push_back(fCalcHeight);
3771       }
3772       return pdfium::nullopt;
3773     }
3774     if (fHeight - fStartOffset - fTextHeight < fFontSize) {
3775       iLineNum -= 1;
3776       if (iLineNum == 0)
3777         return 0.0f;
3778     } else {
3779       iLineNum = (int32_t)(fTextNum / fLineHeight);
3780     }
3781   }
3782   if (iLineNum <= 0)
3783     return 0.0f;
3784 
3785   float fSplitHeight = iLineNum * fLineHeight + fCapReserve + fStartOffset;
3786   if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3787     (*pFieldArray)[szBlockIndex * 3 + 1] = iLineNum;
3788     (*pFieldArray)[szBlockIndex * 3 + 2] = fSplitHeight;
3789   } else {
3790     pFieldArray->push_back(iLineNum);
3791     pFieldArray->push_back(fSplitHeight);
3792   }
3793   if (fabs(fSplitHeight - fCalcHeight) < kXFAWidgetPrecision)
3794     return pdfium::nullopt;
3795   return fSplitHeight;
3796 }
3797 
InitLayoutData(CXFA_FFDoc * doc)3798 void CXFA_Node::InitLayoutData(CXFA_FFDoc* doc) {
3799   if (m_pLayoutData)
3800     return;
3801 
3802   switch (GetFFWidgetType()) {
3803     case XFA_FFWidgetType::kText:
3804       m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_TextLayoutData>(
3805           doc->GetHeap()->GetAllocationHandle());
3806       return;
3807     case XFA_FFWidgetType::kTextEdit:
3808       m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_TextEditData>(
3809           doc->GetHeap()->GetAllocationHandle());
3810       return;
3811     case XFA_FFWidgetType::kImage:
3812       m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_ImageLayoutData>(
3813           doc->GetHeap()->GetAllocationHandle());
3814       return;
3815     case XFA_FFWidgetType::kImageEdit:
3816       m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_ImageEditData>(
3817           doc->GetHeap()->GetAllocationHandle());
3818       return;
3819     default:
3820       break;
3821   }
3822   if (GetElementType() == XFA_Element::Field) {
3823     m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_FieldLayoutData>(
3824         doc->GetHeap()->GetAllocationHandle());
3825     return;
3826   }
3827   m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_WidgetLayoutData>(
3828       doc->GetHeap()->GetAllocationHandle());
3829 }
3830 
StartTextLayout(CXFA_FFDoc * doc,float * pCalcWidth,float * pCalcHeight)3831 void CXFA_Node::StartTextLayout(CXFA_FFDoc* doc,
3832                                 float* pCalcWidth,
3833                                 float* pCalcHeight) {
3834   InitLayoutData(doc);
3835 
3836   CXFA_TextLayoutData* pTextLayoutData = m_pLayoutData->AsTextLayoutData();
3837   pTextLayoutData->LoadText(doc, this);
3838 
3839   CXFA_TextLayout* pTextLayout = pTextLayoutData->GetTextLayout();
3840   float fTextHeight = 0;
3841   if (*pCalcWidth > 0 && *pCalcHeight > 0) {
3842     float fWidth = GetWidthWithoutMargin(*pCalcWidth);
3843     pTextLayout->StartLayout(fWidth);
3844     fTextHeight = *pCalcHeight;
3845     fTextHeight = GetHeightWithoutMargin(fTextHeight);
3846     pTextLayout->DoLayout(fTextHeight);
3847     return;
3848   }
3849   if (*pCalcWidth > 0 && *pCalcHeight < 0) {
3850     float fWidth = GetWidthWithoutMargin(*pCalcWidth);
3851     pTextLayout->StartLayout(fWidth);
3852   }
3853   if (*pCalcWidth < 0 && *pCalcHeight < 0) {
3854     Optional<float> width = TryWidth();
3855     if (width) {
3856       pTextLayout->StartLayout(GetWidthWithoutMargin(*width));
3857       *pCalcWidth = *width;
3858     } else {
3859       float fMaxWidth = CalculateWidgetAutoWidth(pTextLayout->StartLayout(-1));
3860       pTextLayout->StartLayout(GetWidthWithoutMargin(fMaxWidth));
3861       *pCalcWidth = fMaxWidth;
3862     }
3863   }
3864   if (m_pLayoutData->m_fWidgetHeight < 0) {
3865     m_pLayoutData->m_fWidgetHeight = pTextLayout->GetLayoutHeight();
3866     m_pLayoutData->m_fWidgetHeight =
3867         CalculateWidgetAutoHeight(m_pLayoutData->m_fWidgetHeight);
3868   }
3869   fTextHeight = m_pLayoutData->m_fWidgetHeight;
3870   fTextHeight = GetHeightWithoutMargin(fTextHeight);
3871   pTextLayout->DoLayout(fTextHeight);
3872   *pCalcHeight = m_pLayoutData->m_fWidgetHeight;
3873 }
3874 
LoadCaption(CXFA_FFDoc * doc)3875 bool CXFA_Node::LoadCaption(CXFA_FFDoc* doc) {
3876   InitLayoutData(doc);
3877   return m_pLayoutData->AsFieldLayoutData()->LoadCaption(doc, this);
3878 }
3879 
GetCaptionTextLayout()3880 CXFA_TextLayout* CXFA_Node::GetCaptionTextLayout() {
3881   return m_pLayoutData ? m_pLayoutData->AsFieldLayoutData()->m_pCapTextLayout
3882                        : nullptr;
3883 }
3884 
GetTextLayout()3885 CXFA_TextLayout* CXFA_Node::GetTextLayout() {
3886   return m_pLayoutData ? m_pLayoutData->AsTextLayoutData()->GetTextLayout()
3887                        : nullptr;
3888 }
3889 
GetImageImage()3890 RetainPtr<CFX_DIBitmap> CXFA_Node::GetImageImage() {
3891   return m_pLayoutData ? m_pLayoutData->AsImageLayoutData()->m_pDIBitmap
3892                        : nullptr;
3893 }
3894 
GetImageEditImage()3895 RetainPtr<CFX_DIBitmap> CXFA_Node::GetImageEditImage() {
3896   return m_pLayoutData ? m_pLayoutData->AsFieldLayoutData()
3897                              ->AsImageEditData()
3898                              ->m_pDIBitmap
3899                        : nullptr;
3900 }
3901 
SetImageImage(const RetainPtr<CFX_DIBitmap> & newImage)3902 void CXFA_Node::SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage) {
3903   CXFA_ImageLayoutData* pData = m_pLayoutData->AsImageLayoutData();
3904   if (pData->m_pDIBitmap != newImage)
3905     pData->m_pDIBitmap = newImage;
3906 }
3907 
SetImageEditImage(const RetainPtr<CFX_DIBitmap> & newImage)3908 void CXFA_Node::SetImageEditImage(const RetainPtr<CFX_DIBitmap>& newImage) {
3909   CXFA_ImageEditData* pData =
3910       m_pLayoutData->AsFieldLayoutData()->AsImageEditData();
3911   if (pData->m_pDIBitmap != newImage)
3912     pData->m_pDIBitmap = newImage;
3913 }
3914 
GetFGASFont(CXFA_FFDoc * doc)3915 RetainPtr<CFGAS_GEFont> CXFA_Node::GetFGASFont(CXFA_FFDoc* doc) {
3916   WideString wsFontName = L"Courier";
3917   uint32_t dwFontStyle = 0;
3918   CXFA_Font* font = GetFontIfExists();
3919   if (font) {
3920     if (font->IsBold())
3921       dwFontStyle |= FXFONT_FORCE_BOLD;
3922     if (font->IsItalic())
3923       dwFontStyle |= FXFONT_ITALIC;
3924 
3925     wsFontName = font->GetTypeface();
3926   }
3927   return doc->GetApp()->GetXFAFontMgr()->GetFont(doc, wsFontName.AsStringView(),
3928                                                  dwFontStyle);
3929 }
3930 
HasButtonRollover()3931 bool CXFA_Node::HasButtonRollover() {
3932   CXFA_Items* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3933   if (!pItems)
3934     return false;
3935 
3936   for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
3937        pText = pText->GetNextSibling()) {
3938     if (pText->JSObject()
3939             ->GetCData(XFA_Attribute::Name)
3940             .EqualsASCII("rollover")) {
3941       return !pText->JSObject()->GetContent(false).IsEmpty();
3942     }
3943   }
3944   return false;
3945 }
3946 
HasButtonDown()3947 bool CXFA_Node::HasButtonDown() {
3948   CXFA_Items* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3949   if (!pItems)
3950     return false;
3951 
3952   for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
3953        pText = pText->GetNextSibling()) {
3954     if (pText->JSObject()->GetCData(XFA_Attribute::Name).EqualsASCII("down")) {
3955       return !pText->JSObject()->GetContent(false).IsEmpty();
3956     }
3957   }
3958   return false;
3959 }
3960 
IsRadioButton()3961 bool CXFA_Node::IsRadioButton() {
3962   CXFA_Node* pParent = GetParent();
3963   return pParent && pParent->GetElementType() == XFA_Element::ExclGroup;
3964 }
3965 
GetCheckButtonSize()3966 float CXFA_Node::GetCheckButtonSize() {
3967   CXFA_Node* pUIChild = GetUIChildNode();
3968   if (pUIChild) {
3969     return pUIChild->JSObject()->GetMeasureInUnit(XFA_Attribute::Size,
3970                                                   XFA_Unit::Pt);
3971   }
3972   return CXFA_Measurement(10, XFA_Unit::Pt).ToUnit(XFA_Unit::Pt);
3973 }
3974 
GetCheckState()3975 XFA_CHECKSTATE CXFA_Node::GetCheckState() {
3976   WideString wsValue = GetRawValue();
3977   if (wsValue.IsEmpty())
3978     return XFA_CHECKSTATE_Off;
3979 
3980   auto* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3981   if (!pItems)
3982     return XFA_CHECKSTATE_Off;
3983 
3984   CXFA_Node* pText = pItems->GetFirstChild();
3985   int32_t i = 0;
3986   while (pText) {
3987     Optional<WideString> wsContent = pText->JSObject()->TryContent(false, true);
3988     if (wsContent && *wsContent == wsValue)
3989       return static_cast<XFA_CHECKSTATE>(i);
3990 
3991     i++;
3992     pText = pText->GetNextSibling();
3993   }
3994   return XFA_CHECKSTATE_Off;
3995 }
3996 
SetCheckState(XFA_CHECKSTATE eCheckState,bool bNotify)3997 void CXFA_Node::SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify) {
3998   CXFA_Node* node = GetExclGroupIfExists();
3999   if (!node) {
4000     CXFA_Items* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
4001     if (!pItems)
4002       return;
4003 
4004     int32_t i = -1;
4005     CXFA_Node* pText = pItems->GetFirstChild();
4006     WideString wsContent;
4007     while (pText) {
4008       i++;
4009       if (i == eCheckState) {
4010         wsContent = pText->JSObject()->GetContent(false);
4011         break;
4012       }
4013       pText = pText->GetNextSibling();
4014     }
4015     SyncValue(wsContent, bNotify);
4016 
4017     return;
4018   }
4019 
4020   WideString wsValue;
4021   if (eCheckState != XFA_CHECKSTATE_Off) {
4022     if (CXFA_Items* pItems =
4023             GetChild<CXFA_Items>(0, XFA_Element::Items, false)) {
4024       CXFA_Node* pText = pItems->GetFirstChild();
4025       if (pText)
4026         wsValue = pText->JSObject()->GetContent(false);
4027     }
4028   }
4029   CXFA_Node* pChild = node->GetFirstChild();
4030   for (; pChild; pChild = pChild->GetNextSibling()) {
4031     if (pChild->GetElementType() != XFA_Element::Field)
4032       continue;
4033 
4034     CXFA_Items* pItem =
4035         pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
4036     if (!pItem)
4037       continue;
4038 
4039     CXFA_Node* pItemchild = pItem->GetFirstChild();
4040     if (!pItemchild)
4041       continue;
4042 
4043     WideString text = pItemchild->JSObject()->GetContent(false);
4044     WideString wsChildValue = text;
4045     if (wsValue != text) {
4046       pItemchild = pItemchild->GetNextSibling();
4047       if (pItemchild)
4048         wsChildValue = pItemchild->JSObject()->GetContent(false);
4049       else
4050         wsChildValue.clear();
4051     }
4052     pChild->SyncValue(wsChildValue, bNotify);
4053   }
4054   node->SyncValue(wsValue, bNotify);
4055 }
4056 
GetSelectedMember()4057 CXFA_Node* CXFA_Node::GetSelectedMember() {
4058   CXFA_Node* pSelectedMember = nullptr;
4059   WideString wsState = GetRawValue();
4060   if (wsState.IsEmpty())
4061     return pSelectedMember;
4062 
4063   for (CXFA_Node* pNode = ToNode(GetFirstChild()); pNode;
4064        pNode = pNode->GetNextSibling()) {
4065     if (pNode->GetCheckState() == XFA_CHECKSTATE_On) {
4066       pSelectedMember = pNode;
4067       break;
4068     }
4069   }
4070   return pSelectedMember;
4071 }
4072 
SetSelectedMember(WideStringView wsName,bool bNotify)4073 CXFA_Node* CXFA_Node::SetSelectedMember(WideStringView wsName, bool bNotify) {
4074   uint32_t nameHash = FX_HashCode_GetW(wsName, false);
4075   for (CXFA_Node* pNode = ToNode(GetFirstChild()); pNode;
4076        pNode = pNode->GetNextSibling()) {
4077     if (pNode->GetNameHash() == nameHash) {
4078       pNode->SetCheckState(XFA_CHECKSTATE_On, bNotify);
4079       return pNode;
4080     }
4081   }
4082   return nullptr;
4083 }
4084 
SetSelectedMemberByValue(WideStringView wsValue,bool bNotify,bool bScriptModify,bool bSyncData)4085 void CXFA_Node::SetSelectedMemberByValue(WideStringView wsValue,
4086                                          bool bNotify,
4087                                          bool bScriptModify,
4088                                          bool bSyncData) {
4089   WideString wsExclGroup;
4090   for (CXFA_Node* pNode = GetFirstChild(); pNode;
4091        pNode = pNode->GetNextSibling()) {
4092     if (pNode->GetElementType() != XFA_Element::Field)
4093       continue;
4094 
4095     CXFA_Items* pItem =
4096         pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
4097     if (!pItem)
4098       continue;
4099 
4100     CXFA_Node* pItemchild = pItem->GetFirstChild();
4101     if (!pItemchild)
4102       continue;
4103 
4104     WideString wsChildValue = pItemchild->JSObject()->GetContent(false);
4105     if (wsValue != wsChildValue) {
4106       pItemchild = pItemchild->GetNextSibling();
4107       if (pItemchild)
4108         wsChildValue = pItemchild->JSObject()->GetContent(false);
4109       else
4110         wsChildValue.clear();
4111     } else {
4112       wsExclGroup = wsValue;
4113     }
4114     pNode->JSObject()->SetContent(wsChildValue, wsChildValue, bNotify,
4115                                   bScriptModify, false);
4116   }
4117   JSObject()->SetContent(wsExclGroup, wsExclGroup, bNotify, bScriptModify,
4118                          bSyncData);
4119 }
4120 
GetExclGroupFirstMember()4121 CXFA_Node* CXFA_Node::GetExclGroupFirstMember() {
4122   CXFA_Node* pNode = GetFirstChild();
4123   while (pNode) {
4124     if (pNode->GetElementType() == XFA_Element::Field)
4125       return pNode;
4126 
4127     pNode = pNode->GetNextSibling();
4128   }
4129   return nullptr;
4130 }
4131 
GetExclGroupNextMember(CXFA_Node * pNode)4132 CXFA_Node* CXFA_Node::GetExclGroupNextMember(CXFA_Node* pNode) {
4133   if (!pNode)
4134     return nullptr;
4135 
4136   CXFA_Node* pNodeField = pNode->GetNextSibling();
4137   while (pNodeField) {
4138     if (pNodeField->GetElementType() == XFA_Element::Field)
4139       return pNodeField;
4140 
4141     pNodeField = pNodeField->GetNextSibling();
4142   }
4143   return nullptr;
4144 }
4145 
IsChoiceListCommitOnSelect()4146 bool CXFA_Node::IsChoiceListCommitOnSelect() {
4147   CXFA_Node* pUIChild = GetUIChildNode();
4148   if (pUIChild) {
4149     return pUIChild->JSObject()->GetEnum(XFA_Attribute::CommitOn) ==
4150            XFA_AttributeValue::Select;
4151   }
4152   return true;
4153 }
4154 
IsChoiceListAllowTextEntry()4155 bool CXFA_Node::IsChoiceListAllowTextEntry() {
4156   CXFA_Node* pUIChild = GetUIChildNode();
4157   return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::TextEntry);
4158 }
4159 
IsChoiceListMultiSelect()4160 bool CXFA_Node::IsChoiceListMultiSelect() {
4161   CXFA_Node* pUIChild = GetUIChildNode();
4162   if (pUIChild) {
4163     return pUIChild->JSObject()->GetEnum(XFA_Attribute::Open) ==
4164            XFA_AttributeValue::MultiSelect;
4165   }
4166   return false;
4167 }
4168 
IsListBox()4169 bool CXFA_Node::IsListBox() {
4170   CXFA_Node* pUIChild = GetUIChildNode();
4171   if (!pUIChild)
4172     return false;
4173 
4174   XFA_AttributeValue attr = pUIChild->JSObject()->GetEnum(XFA_Attribute::Open);
4175   return attr == XFA_AttributeValue::Always ||
4176          attr == XFA_AttributeValue::MultiSelect;
4177 }
4178 
CountChoiceListItems(bool bSaveValue)4179 int32_t CXFA_Node::CountChoiceListItems(bool bSaveValue) {
4180   std::vector<CXFA_Node*> pItems;
4181   int32_t iCount = 0;
4182   for (CXFA_Node* pNode = GetFirstChild(); pNode;
4183        pNode = pNode->GetNextSibling()) {
4184     if (pNode->GetElementType() != XFA_Element::Items)
4185       continue;
4186     iCount++;
4187     pItems.push_back(pNode);
4188     if (iCount == 2)
4189       break;
4190   }
4191   if (iCount == 0)
4192     return 0;
4193 
4194   CXFA_Node* pItem = pItems[0];
4195   if (iCount > 1) {
4196     bool bItemOneHasSave =
4197         pItems[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
4198     bool bItemTwoHasSave =
4199         pItems[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
4200     if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
4201       pItem = pItems[1];
4202   }
4203   return pItem->CountChildren(XFA_Element::Unknown, false);
4204 }
4205 
GetChoiceListItem(int32_t nIndex,bool bSaveValue)4206 Optional<WideString> CXFA_Node::GetChoiceListItem(int32_t nIndex,
4207                                                   bool bSaveValue) {
4208   std::vector<CXFA_Node*> pItemsArray;
4209   int32_t iCount = 0;
4210   for (CXFA_Node* pNode = GetFirstChild(); pNode;
4211        pNode = pNode->GetNextSibling()) {
4212     if (pNode->GetElementType() != XFA_Element::Items)
4213       continue;
4214 
4215     ++iCount;
4216     pItemsArray.push_back(pNode);
4217     if (iCount == 2)
4218       break;
4219   }
4220   if (iCount == 0)
4221     return {};
4222 
4223   CXFA_Node* pItems = pItemsArray[0];
4224   if (iCount > 1) {
4225     bool bItemOneHasSave =
4226         pItemsArray[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
4227     bool bItemTwoHasSave =
4228         pItemsArray[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
4229     if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
4230       pItems = pItemsArray[1];
4231   }
4232   if (!pItems)
4233     return {};
4234 
4235   CXFA_Node* pItem =
4236       pItems->GetChild<CXFA_Node>(nIndex, XFA_Element::Unknown, false);
4237   if (pItem)
4238     return {pItem->JSObject()->GetContent(false)};
4239   return {};
4240 }
4241 
GetChoiceListItems(bool bSaveValue)4242 std::vector<WideString> CXFA_Node::GetChoiceListItems(bool bSaveValue) {
4243   std::vector<CXFA_Node*> items;
4244   for (CXFA_Node* pNode = GetFirstChild(); pNode && items.size() < 2;
4245        pNode = pNode->GetNextSibling()) {
4246     if (pNode->GetElementType() == XFA_Element::Items)
4247       items.push_back(pNode);
4248   }
4249   if (items.empty())
4250     return std::vector<WideString>();
4251 
4252   CXFA_Node* pItem = items.front();
4253   if (items.size() > 1) {
4254     bool bItemOneHasSave =
4255         items[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
4256     bool bItemTwoHasSave =
4257         items[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
4258     if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
4259       pItem = items[1];
4260   }
4261 
4262   std::vector<WideString> wsTextArray;
4263   for (CXFA_Node* pNode = pItem->GetFirstChild(); pNode;
4264        pNode = pNode->GetNextSibling()) {
4265     wsTextArray.emplace_back(pNode->JSObject()->GetContent(false));
4266   }
4267   return wsTextArray;
4268 }
4269 
CountSelectedItems()4270 int32_t CXFA_Node::CountSelectedItems() {
4271   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4272   if (IsListBox() || !IsChoiceListAllowTextEntry())
4273     return pdfium::CollectionSize<int32_t>(wsValueArray);
4274 
4275   int32_t iSelected = 0;
4276   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4277   for (const auto& value : wsValueArray) {
4278     if (pdfium::Contains(wsSaveTextArray, value))
4279       iSelected++;
4280   }
4281   return iSelected;
4282 }
4283 
GetSelectedItem(int32_t nIndex)4284 int32_t CXFA_Node::GetSelectedItem(int32_t nIndex) {
4285   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4286   if (!pdfium::IndexInBounds(wsValueArray, nIndex))
4287     return -1;
4288 
4289   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4290   auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(),
4291                       wsValueArray[nIndex]);
4292   return it != wsSaveTextArray.end() ? it - wsSaveTextArray.begin() : -1;
4293 }
4294 
GetSelectedItems()4295 std::vector<int32_t> CXFA_Node::GetSelectedItems() {
4296   std::vector<int32_t> iSelArray;
4297   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4298   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4299   for (const auto& value : wsValueArray) {
4300     auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(), value);
4301     if (it != wsSaveTextArray.end())
4302       iSelArray.push_back(it - wsSaveTextArray.begin());
4303   }
4304   return iSelArray;
4305 }
4306 
GetSelectedItemsValue()4307 std::vector<WideString> CXFA_Node::GetSelectedItemsValue() {
4308   WideString wsValue = GetRawValue();
4309   if (IsChoiceListMultiSelect())
4310     return fxcrt::Split(wsValue, L'\n');
4311 
4312   std::vector<WideString> wsSelTextArray;
4313   wsSelTextArray.push_back(wsValue);
4314   return wsSelTextArray;
4315 }
4316 
GetItemState(int32_t nIndex)4317 bool CXFA_Node::GetItemState(int32_t nIndex) {
4318   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4319   return pdfium::IndexInBounds(wsSaveTextArray, nIndex) &&
4320          pdfium::Contains(GetSelectedItemsValue(), wsSaveTextArray[nIndex]);
4321 }
4322 
SetItemState(int32_t nIndex,bool bSelected,bool bNotify,bool bScriptModify,bool bSyncData)4323 void CXFA_Node::SetItemState(int32_t nIndex,
4324                              bool bSelected,
4325                              bool bNotify,
4326                              bool bScriptModify,
4327                              bool bSyncData) {
4328   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4329   if (!pdfium::IndexInBounds(wsSaveTextArray, nIndex))
4330     return;
4331 
4332   int32_t iSel = -1;
4333   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4334   auto value_iter = std::find(wsValueArray.begin(), wsValueArray.end(),
4335                               wsSaveTextArray[nIndex]);
4336   if (value_iter != wsValueArray.end())
4337     iSel = value_iter - wsValueArray.begin();
4338 
4339   if (IsChoiceListMultiSelect()) {
4340     if (bSelected) {
4341       if (iSel < 0) {
4342         WideString wsValue = GetRawValue();
4343         if (!wsValue.IsEmpty()) {
4344           wsValue += L"\n";
4345         }
4346         wsValue += wsSaveTextArray[nIndex];
4347         JSObject()->SetContent(wsValue, wsValue, bNotify, bScriptModify,
4348                                bSyncData);
4349       }
4350     } else if (iSel >= 0) {
4351       std::vector<int32_t> iSelArray = GetSelectedItems();
4352       auto selected_iter =
4353           std::find(iSelArray.begin(), iSelArray.end(), nIndex);
4354       if (selected_iter != iSelArray.end())
4355         iSelArray.erase(selected_iter);
4356       SetSelectedItems(iSelArray, bNotify, bScriptModify, bSyncData);
4357     }
4358   } else {
4359     if (bSelected) {
4360       if (iSel < 0) {
4361         WideString wsSaveText = wsSaveTextArray[nIndex];
4362         JSObject()->SetContent(wsSaveText, GetFormatDataValue(wsSaveText),
4363                                bNotify, bScriptModify, bSyncData);
4364       }
4365     } else if (iSel >= 0) {
4366       JSObject()->SetContent(WideString(), WideString(), bNotify, bScriptModify,
4367                              bSyncData);
4368     }
4369   }
4370 }
4371 
SetSelectedItems(const std::vector<int32_t> & iSelArray,bool bNotify,bool bScriptModify,bool bSyncData)4372 void CXFA_Node::SetSelectedItems(const std::vector<int32_t>& iSelArray,
4373                                  bool bNotify,
4374                                  bool bScriptModify,
4375                                  bool bSyncData) {
4376   WideString wsValue;
4377   int32_t iSize = pdfium::CollectionSize<int32_t>(iSelArray);
4378   if (iSize >= 1) {
4379     std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4380     WideString wsItemValue;
4381     for (int32_t i = 0; i < iSize; i++) {
4382       wsItemValue = (iSize == 1) ? wsSaveTextArray[iSelArray[i]]
4383                                  : wsSaveTextArray[iSelArray[i]] + L"\n";
4384       wsValue += wsItemValue;
4385     }
4386   }
4387   WideString wsFormat(wsValue);
4388   if (!IsChoiceListMultiSelect())
4389     wsFormat = GetFormatDataValue(wsValue);
4390 
4391   JSObject()->SetContent(wsValue, wsFormat, bNotify, bScriptModify, bSyncData);
4392 }
4393 
ClearAllSelections()4394 void CXFA_Node::ClearAllSelections() {
4395   CXFA_Node* pBind = GetBindData();
4396   if (!pBind || !IsChoiceListMultiSelect()) {
4397     SyncValue(WideString(), false);
4398     return;
4399   }
4400 
4401   while (CXFA_Node* pChildNode = pBind->GetFirstChild())
4402     pBind->RemoveChildAndNotify(pChildNode, true);
4403 }
4404 
InsertItem(const WideString & wsLabel,const WideString & wsValue,bool bNotify)4405 void CXFA_Node::InsertItem(const WideString& wsLabel,
4406                            const WideString& wsValue,
4407                            bool bNotify) {
4408   int32_t nIndex = -1;
4409   WideString wsNewValue(wsValue);
4410   if (wsNewValue.IsEmpty())
4411     wsNewValue = wsLabel;
4412 
4413   std::vector<CXFA_Node*> listitems;
4414   for (CXFA_Node* pItem = GetFirstChild(); pItem;
4415        pItem = pItem->GetNextSibling()) {
4416     if (pItem->GetElementType() == XFA_Element::Items)
4417       listitems.push_back(pItem);
4418   }
4419   if (listitems.empty()) {
4420     CXFA_Node* pItems = CreateSamePacketNode(XFA_Element::Items);
4421     InsertChildAndNotify(-1, pItems);
4422     InsertListTextItem(pItems, wsLabel, nIndex);
4423     CXFA_Node* pSaveItems = CreateSamePacketNode(XFA_Element::Items);
4424     InsertChildAndNotify(-1, pSaveItems);
4425     pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
4426     InsertListTextItem(pSaveItems, wsNewValue, nIndex);
4427   } else if (listitems.size() > 1) {
4428     for (int32_t i = 0; i < 2; i++) {
4429       CXFA_Node* pNode = listitems[i];
4430       bool bHasSave = pNode->JSObject()->GetBoolean(XFA_Attribute::Save);
4431       if (bHasSave)
4432         InsertListTextItem(pNode, wsNewValue, nIndex);
4433       else
4434         InsertListTextItem(pNode, wsLabel, nIndex);
4435     }
4436   } else {
4437     CXFA_Node* pNode = listitems[0];
4438     pNode->JSObject()->SetBoolean(XFA_Attribute::Save, false, false);
4439     pNode->JSObject()->SetEnum(XFA_Attribute::Presence,
4440                                XFA_AttributeValue::Visible, false);
4441     CXFA_Node* pSaveItems = CreateSamePacketNode(XFA_Element::Items);
4442     InsertChildAndNotify(-1, pSaveItems);
4443     pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
4444     pSaveItems->JSObject()->SetEnum(XFA_Attribute::Presence,
4445                                     XFA_AttributeValue::Hidden, false);
4446     CXFA_Node* pListNode = pNode->GetFirstChild();
4447     int32_t i = 0;
4448     while (pListNode) {
4449       InsertListTextItem(pSaveItems, pListNode->JSObject()->GetContent(false),
4450                          i);
4451       ++i;
4452 
4453       pListNode = pListNode->GetNextSibling();
4454     }
4455     InsertListTextItem(pNode, wsLabel, nIndex);
4456     InsertListTextItem(pSaveItems, wsNewValue, nIndex);
4457   }
4458   if (bNotify)
4459     GetDocument()->GetNotify()->OnWidgetListItemAdded(this, wsLabel, nIndex);
4460 }
4461 
GetItemLabel(WideStringView wsValue) const4462 WideString CXFA_Node::GetItemLabel(WideStringView wsValue) const {
4463   std::vector<CXFA_Node*> listitems;
4464   CXFA_Node* pItems = GetFirstChild();
4465   for (; pItems; pItems = pItems->GetNextSibling()) {
4466     if (pItems->GetElementType() != XFA_Element::Items)
4467       continue;
4468     listitems.push_back(pItems);
4469   }
4470 
4471   if (listitems.size() <= 1)
4472     return WideString(wsValue);
4473 
4474   CXFA_Node* pLabelItems = listitems[0];
4475   bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
4476   CXFA_Node* pSaveItems = nullptr;
4477   if (bSave) {
4478     pSaveItems = pLabelItems;
4479     pLabelItems = listitems[1];
4480   } else {
4481     pSaveItems = listitems[1];
4482   }
4483 
4484   int32_t iCount = 0;
4485   int32_t iSearch = -1;
4486   for (CXFA_Node* pChildItem = pSaveItems->GetFirstChild(); pChildItem;
4487        pChildItem = pChildItem->GetNextSibling()) {
4488     if (pChildItem->JSObject()->GetContent(false) == wsValue) {
4489       iSearch = iCount;
4490       break;
4491     }
4492     iCount++;
4493   }
4494   if (iSearch < 0)
4495     return WideString();
4496 
4497   CXFA_Node* pText =
4498       pLabelItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
4499   return pText ? pText->JSObject()->GetContent(false) : WideString();
4500 }
4501 
GetItemValue(WideStringView wsLabel)4502 WideString CXFA_Node::GetItemValue(WideStringView wsLabel) {
4503   int32_t iCount = 0;
4504   std::vector<CXFA_Node*> listitems;
4505   for (CXFA_Node* pItems = GetFirstChild(); pItems;
4506        pItems = pItems->GetNextSibling()) {
4507     if (pItems->GetElementType() != XFA_Element::Items)
4508       continue;
4509     iCount++;
4510     listitems.push_back(pItems);
4511   }
4512   if (iCount <= 1)
4513     return WideString(wsLabel);
4514 
4515   CXFA_Node* pLabelItems = listitems[0];
4516   bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
4517   CXFA_Node* pSaveItems = nullptr;
4518   if (bSave) {
4519     pSaveItems = pLabelItems;
4520     pLabelItems = listitems[1];
4521   } else {
4522     pSaveItems = listitems[1];
4523   }
4524   iCount = 0;
4525 
4526   int32_t iSearch = -1;
4527   WideString wsContent;
4528   CXFA_Node* pChildItem = pLabelItems->GetFirstChild();
4529   for (; pChildItem; pChildItem = pChildItem->GetNextSibling()) {
4530     if (pChildItem->JSObject()->GetContent(false) == wsLabel) {
4531       iSearch = iCount;
4532       break;
4533     }
4534     iCount++;
4535   }
4536   if (iSearch < 0)
4537     return WideString();
4538 
4539   CXFA_Node* pText =
4540       pSaveItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
4541   return pText ? pText->JSObject()->GetContent(false) : WideString();
4542 }
4543 
DeleteItem(int32_t nIndex,bool bNotify,bool bScriptModify)4544 bool CXFA_Node::DeleteItem(int32_t nIndex, bool bNotify, bool bScriptModify) {
4545   bool bSetValue = false;
4546   CXFA_Node* pItems = GetFirstChild();
4547   for (; pItems; pItems = pItems->GetNextSibling()) {
4548     if (pItems->GetElementType() != XFA_Element::Items)
4549       continue;
4550 
4551     if (nIndex < 0) {
4552       while (CXFA_Node* pNode = pItems->GetFirstChild()) {
4553         pItems->RemoveChildAndNotify(pNode, true);
4554       }
4555     } else {
4556       if (!bSetValue && pItems->JSObject()->GetBoolean(XFA_Attribute::Save)) {
4557         SetItemState(nIndex, false, true, bScriptModify, true);
4558         bSetValue = true;
4559       }
4560       int32_t i = 0;
4561       CXFA_Node* pNode = pItems->GetFirstChild();
4562       while (pNode) {
4563         if (i == nIndex) {
4564           pItems->RemoveChildAndNotify(pNode, true);
4565           break;
4566         }
4567         i++;
4568         pNode = pNode->GetNextSibling();
4569       }
4570     }
4571   }
4572   if (bNotify)
4573     GetDocument()->GetNotify()->OnWidgetListItemRemoved(this, nIndex);
4574   return true;
4575 }
4576 
IsHorizontalScrollPolicyOff()4577 bool CXFA_Node::IsHorizontalScrollPolicyOff() {
4578   CXFA_Node* pUIChild = GetUIChildNode();
4579   if (pUIChild) {
4580     return pUIChild->JSObject()->GetEnum(XFA_Attribute::HScrollPolicy) ==
4581            XFA_AttributeValue::Off;
4582   }
4583   return false;
4584 }
4585 
IsVerticalScrollPolicyOff()4586 bool CXFA_Node::IsVerticalScrollPolicyOff() {
4587   CXFA_Node* pUIChild = GetUIChildNode();
4588   if (pUIChild) {
4589     return pUIChild->JSObject()->GetEnum(XFA_Attribute::VScrollPolicy) ==
4590            XFA_AttributeValue::Off;
4591   }
4592   return false;
4593 }
4594 
GetNumberOfCells()4595 Optional<int32_t> CXFA_Node::GetNumberOfCells() {
4596   CXFA_Node* pUIChild = GetUIChildNode();
4597   if (!pUIChild)
4598     return {};
4599   if (CXFA_Comb* pNode =
4600           pUIChild->GetChild<CXFA_Comb>(0, XFA_Element::Comb, false))
4601     return {pNode->JSObject()->GetInteger(XFA_Attribute::NumberOfCells)};
4602   return {};
4603 }
4604 
IsMultiLine()4605 bool CXFA_Node::IsMultiLine() {
4606   CXFA_Node* pUIChild = GetUIChildNode();
4607   return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::MultiLine);
4608 }
4609 
GetMaxChars()4610 std::pair<XFA_Element, int32_t> CXFA_Node::GetMaxChars() {
4611   if (CXFA_Value* pNode = GetChild<CXFA_Value>(0, XFA_Element::Value, false)) {
4612     if (CXFA_Node* pChild = pNode->GetFirstChild()) {
4613       switch (pChild->GetElementType()) {
4614         case XFA_Element::Text:
4615           return {XFA_Element::Text,
4616                   pChild->JSObject()->GetInteger(XFA_Attribute::MaxChars)};
4617         case XFA_Element::ExData: {
4618           int32_t iMax =
4619               pChild->JSObject()->GetInteger(XFA_Attribute::MaxLength);
4620           return {XFA_Element::ExData, iMax < 0 ? 0 : iMax};
4621         }
4622         default:
4623           break;
4624       }
4625     }
4626   }
4627   return {XFA_Element::Unknown, 0};
4628 }
4629 
GetFracDigits()4630 int32_t CXFA_Node::GetFracDigits() {
4631   CXFA_Value* pNode = GetChild<CXFA_Value>(0, XFA_Element::Value, false);
4632   if (!pNode)
4633     return -1;
4634 
4635   CXFA_Decimal* pChild =
4636       pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
4637   if (!pChild)
4638     return -1;
4639 
4640   return pChild->JSObject()
4641       ->TryInteger(XFA_Attribute::FracDigits, true)
4642       .value_or(-1);
4643 }
4644 
GetLeadDigits()4645 int32_t CXFA_Node::GetLeadDigits() {
4646   CXFA_Value* pNode = GetChild<CXFA_Value>(0, XFA_Element::Value, false);
4647   if (!pNode)
4648     return -1;
4649 
4650   CXFA_Decimal* pChild =
4651       pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
4652   if (!pChild)
4653     return -1;
4654 
4655   return pChild->JSObject()
4656       ->TryInteger(XFA_Attribute::LeadDigits, true)
4657       .value_or(-1);
4658 }
4659 
SetValue(XFA_VALUEPICTURE eValueType,const WideString & wsValue)4660 bool CXFA_Node::SetValue(XFA_VALUEPICTURE eValueType,
4661                          const WideString& wsValue) {
4662   if (wsValue.IsEmpty()) {
4663     SyncValue(wsValue, true);
4664     return true;
4665   }
4666 
4667   SetPreNull(IsNull());
4668   SetIsNull(false);
4669 
4670   WideString wsNewText(wsValue);
4671   WideString wsPicture = GetPictureContent(eValueType);
4672   bool bValidate = true;
4673   bool bSyncData = false;
4674   CXFA_Node* pNode = GetUIChildNode();
4675   if (!pNode)
4676     return true;
4677 
4678   XFA_Element eType = pNode->GetElementType();
4679   if (!wsPicture.IsEmpty()) {
4680     CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4681     GCedLocaleIface* pLocale = GetLocale();
4682     CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4683     bValidate =
4684         widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture);
4685     if (bValidate) {
4686       widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText,
4687                                      wsPicture, pLocale, pLocaleMgr);
4688       wsNewText = widgetValue.GetValue();
4689       if (eType == XFA_Element::NumericEdit)
4690         wsNewText = NumericLimit(wsNewText);
4691 
4692       bSyncData = true;
4693     }
4694   } else if (eType == XFA_Element::NumericEdit) {
4695     if (!wsNewText.EqualsASCII("0"))
4696       wsNewText = NumericLimit(wsNewText);
4697 
4698     bSyncData = true;
4699   }
4700   if (eType != XFA_Element::NumericEdit || bSyncData)
4701     SyncValue(wsNewText, true);
4702 
4703   return bValidate;
4704 }
4705 
GetPictureContent(XFA_VALUEPICTURE ePicture)4706 WideString CXFA_Node::GetPictureContent(XFA_VALUEPICTURE ePicture) {
4707   if (ePicture == XFA_VALUEPICTURE_Raw)
4708     return WideString();
4709 
4710   CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4711   switch (ePicture) {
4712     case XFA_VALUEPICTURE_Display: {
4713       if (CXFA_Format* pFormat =
4714               GetChild<CXFA_Format>(0, XFA_Element::Format, false)) {
4715         if (CXFA_Picture* pPicture = pFormat->GetChild<CXFA_Picture>(
4716                 0, XFA_Element::Picture, false)) {
4717           Optional<WideString> picture =
4718               pPicture->JSObject()->TryContent(false, true);
4719           if (picture)
4720             return *picture;
4721         }
4722       }
4723 
4724       LocaleIface* pLocale = GetLocale();
4725       if (!pLocale)
4726         return WideString();
4727 
4728       uint32_t dwType = widgetValue.GetType();
4729       switch (dwType) {
4730         case XFA_VT_DATE:
4731           return pLocale->GetDatePattern(
4732               LocaleIface::DateTimeSubcategory::kMedium);
4733         case XFA_VT_TIME:
4734           return pLocale->GetTimePattern(
4735               LocaleIface::DateTimeSubcategory::kMedium);
4736         case XFA_VT_DATETIME:
4737           return pLocale->GetDatePattern(
4738                      LocaleIface::DateTimeSubcategory::kMedium) +
4739                  L"T" +
4740                  pLocale->GetTimePattern(
4741                      LocaleIface::DateTimeSubcategory::kMedium);
4742         case XFA_VT_DECIMAL:
4743         case XFA_VT_FLOAT:
4744         default:
4745           return WideString();
4746       }
4747     }
4748     case XFA_VALUEPICTURE_Edit: {
4749       CXFA_Ui* pUI = GetChild<CXFA_Ui>(0, XFA_Element::Ui, false);
4750       if (pUI) {
4751         if (CXFA_Picture* pPicture =
4752                 pUI->GetChild<CXFA_Picture>(0, XFA_Element::Picture, false)) {
4753           Optional<WideString> picture =
4754               pPicture->JSObject()->TryContent(false, true);
4755           if (picture)
4756             return *picture;
4757         }
4758       }
4759 
4760       LocaleIface* pLocale = GetLocale();
4761       if (!pLocale)
4762         return WideString();
4763 
4764       uint32_t dwType = widgetValue.GetType();
4765       switch (dwType) {
4766         case XFA_VT_DATE:
4767           return pLocale->GetDatePattern(
4768               LocaleIface::DateTimeSubcategory::kShort);
4769         case XFA_VT_TIME:
4770           return pLocale->GetTimePattern(
4771               LocaleIface::DateTimeSubcategory::kShort);
4772         case XFA_VT_DATETIME:
4773           return pLocale->GetDatePattern(
4774                      LocaleIface::DateTimeSubcategory::kShort) +
4775                  L"T" +
4776                  pLocale->GetTimePattern(
4777                      LocaleIface::DateTimeSubcategory::kShort);
4778         default:
4779           return WideString();
4780       }
4781     }
4782     case XFA_VALUEPICTURE_DataBind: {
4783       CXFA_Bind* bind = GetBindIfExists();
4784       if (bind)
4785         return bind->GetPicture();
4786       break;
4787     }
4788     default:
4789       break;
4790   }
4791   return WideString();
4792 }
4793 
GetValue(XFA_VALUEPICTURE eValueType)4794 WideString CXFA_Node::GetValue(XFA_VALUEPICTURE eValueType) {
4795   WideString wsValue = JSObject()->GetContent(false);
4796 
4797   if (eValueType == XFA_VALUEPICTURE_Display)
4798     wsValue = GetItemLabel(wsValue.AsStringView());
4799 
4800   WideString wsPicture = GetPictureContent(eValueType);
4801   CXFA_Node* pNode = GetUIChildNode();
4802   if (!pNode)
4803     return wsValue;
4804 
4805   switch (pNode->GetElementType()) {
4806     case XFA_Element::ChoiceList: {
4807       if (eValueType == XFA_VALUEPICTURE_Display) {
4808         int32_t iSelItemIndex = GetSelectedItem(0);
4809         if (iSelItemIndex >= 0) {
4810           wsValue =
4811               GetChoiceListItem(iSelItemIndex, false).value_or(WideString());
4812           wsPicture.clear();
4813         }
4814       }
4815       break;
4816     }
4817     case XFA_Element::NumericEdit:
4818       if (eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
4819         LocaleIface* pLocale = GetLocale();
4820         if (eValueType == XFA_VALUEPICTURE_Display && pLocale)
4821           wsValue = FormatNumStr(NormalizeNumStr(wsValue), pLocale);
4822       }
4823       break;
4824     default:
4825       break;
4826   }
4827   if (wsPicture.IsEmpty())
4828     return wsValue;
4829 
4830   GCedLocaleIface* pLocale = GetLocale();
4831   if (pLocale) {
4832     CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4833     CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4834     switch (widgetValue.GetType()) {
4835       case XFA_VT_DATE: {
4836         WideString wsDate, wsTime;
4837         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4838           CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocaleMgr);
4839           if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
4840             return wsValue;
4841         }
4842         break;
4843       }
4844       case XFA_VT_TIME: {
4845         WideString wsDate, wsTime;
4846         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4847           CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocaleMgr);
4848           if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
4849             return wsValue;
4850         }
4851         break;
4852       }
4853       default:
4854         break;
4855     }
4856     widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
4857   }
4858   return wsValue;
4859 }
4860 
GetNormalizeDataValue(const WideString & wsValue)4861 WideString CXFA_Node::GetNormalizeDataValue(const WideString& wsValue) {
4862   if (wsValue.IsEmpty())
4863     return WideString();
4864 
4865   WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
4866   if (wsPicture.IsEmpty())
4867     return wsValue;
4868 
4869   CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4870   GCedLocaleIface* pLocale = GetLocale();
4871   CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4872   if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
4873     widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsValue, wsPicture,
4874                                    pLocale, pLocaleMgr);
4875     return widgetValue.GetValue();
4876   }
4877   return wsValue;
4878 }
4879 
GetFormatDataValue(const WideString & wsValue)4880 WideString CXFA_Node::GetFormatDataValue(const WideString& wsValue) {
4881   if (wsValue.IsEmpty())
4882     return WideString();
4883 
4884   WideString wsPicture = GetPictureContent(XFA_VALUEPICTURE_DataBind);
4885   if (wsPicture.IsEmpty())
4886     return wsValue;
4887 
4888   WideString wsFormattedValue = wsValue;
4889   GCedLocaleIface* pLocale = GetLocale();
4890   if (pLocale) {
4891     CXFA_Value* pNodeValue = GetChild<CXFA_Value>(0, XFA_Element::Value, false);
4892     if (!pNodeValue)
4893       return wsValue;
4894 
4895     CXFA_Node* pValueChild = pNodeValue->GetFirstChild();
4896     if (!pValueChild)
4897       return wsValue;
4898 
4899     int32_t iVTType = XFA_VT_NULL;
4900     switch (pValueChild->GetElementType()) {
4901       case XFA_Element::Decimal:
4902         iVTType = XFA_VT_DECIMAL;
4903         break;
4904       case XFA_Element::Float:
4905         iVTType = XFA_VT_FLOAT;
4906         break;
4907       case XFA_Element::Date:
4908         iVTType = XFA_VT_DATE;
4909         break;
4910       case XFA_Element::Time:
4911         iVTType = XFA_VT_TIME;
4912         break;
4913       case XFA_Element::DateTime:
4914         iVTType = XFA_VT_DATETIME;
4915         break;
4916       case XFA_Element::Boolean:
4917         iVTType = XFA_VT_BOOLEAN;
4918         break;
4919       case XFA_Element::Integer:
4920         iVTType = XFA_VT_INTEGER;
4921         break;
4922       case XFA_Element::Text:
4923         iVTType = XFA_VT_TEXT;
4924         break;
4925       default:
4926         iVTType = XFA_VT_NULL;
4927         break;
4928     }
4929     CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4930     CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocaleMgr);
4931     switch (widgetValue.GetType()) {
4932       case XFA_VT_DATE: {
4933         WideString wsDate, wsTime;
4934         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4935           CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocaleMgr);
4936           if (date.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
4937                                   XFA_VALUEPICTURE_DataBind)) {
4938             return wsFormattedValue;
4939           }
4940         }
4941         break;
4942       }
4943       case XFA_VT_TIME: {
4944         WideString wsDate, wsTime;
4945         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4946           CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocaleMgr);
4947           if (time.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
4948                                   XFA_VALUEPICTURE_DataBind)) {
4949             return wsFormattedValue;
4950           }
4951         }
4952         break;
4953       }
4954       default:
4955         break;
4956     }
4957     widgetValue.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
4958                                XFA_VALUEPICTURE_DataBind);
4959   }
4960   return wsFormattedValue;
4961 }
4962 
NormalizeNumStr(const WideString & wsValue)4963 WideString CXFA_Node::NormalizeNumStr(const WideString& wsValue) {
4964   if (wsValue.IsEmpty())
4965     return WideString();
4966 
4967   WideString wsOutput = wsValue;
4968   wsOutput.TrimLeft('0');
4969 
4970   if (!wsOutput.IsEmpty() && wsOutput.Contains('.') && GetFracDigits() != -1) {
4971     wsOutput.TrimRight(L"0");
4972     wsOutput.TrimRight(L".");
4973   }
4974   if (wsOutput.IsEmpty() || wsOutput[0] == '.')
4975     wsOutput.InsertAtFront('0');
4976 
4977   return wsOutput;
4978 }
4979 
InsertListTextItem(CXFA_Node * pItems,const WideString & wsText,int32_t nIndex)4980 void CXFA_Node::InsertListTextItem(CXFA_Node* pItems,
4981                                    const WideString& wsText,
4982                                    int32_t nIndex) {
4983   CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_Element::Text);
4984   pItems->InsertChildAndNotify(nIndex, pText);
4985   pText->JSObject()->SetContent(wsText, wsText, false, false, false);
4986 }
4987 
NumericLimit(const WideString & wsValue)4988 WideString CXFA_Node::NumericLimit(const WideString& wsValue) {
4989   int32_t iLead = GetLeadDigits();
4990   int32_t iTread = GetFracDigits();
4991 
4992   if ((iLead == -1) && (iTread == -1))
4993     return wsValue;
4994 
4995   WideString wsRet;
4996   int32_t iLead_ = 0, iTread_ = -1;
4997   int32_t iCount = wsValue.GetLength();
4998   if (iCount == 0)
4999     return wsValue;
5000 
5001   int32_t i = 0;
5002   if (wsValue[i] == L'-') {
5003     wsRet += L'-';
5004     i++;
5005   }
5006   for (; i < iCount; i++) {
5007     wchar_t wc = wsValue[i];
5008     if (FXSYS_IsDecimalDigit(wc)) {
5009       if (iLead >= 0) {
5010         iLead_++;
5011         if (iLead_ > iLead)
5012           return L"0";
5013       } else if (iTread_ >= 0) {
5014         iTread_++;
5015         if (iTread_ > iTread) {
5016           if (iTread != -1) {
5017             CFGAS_Decimal wsDeci = CFGAS_Decimal(wsValue.AsStringView());
5018             wsDeci.SetScale(iTread);
5019             wsRet = wsDeci.ToWideString();
5020           }
5021           return wsRet;
5022         }
5023       }
5024     } else if (wc == L'.') {
5025       iTread_ = 0;
5026       iLead = -1;
5027     }
5028     wsRet += wc;
5029   }
5030   return wsRet;
5031 }
5032 
IsTransparent() const5033 bool CXFA_Node::IsTransparent() const {
5034   XFA_Element type = GetElementType();
5035   return type == XFA_Element::SubformSet || type == XFA_Element::Area ||
5036          type == XFA_Element::Proto || (IsUnnamed() && IsContainerNode());
5037 }
5038 
IsProperty() const5039 bool CXFA_Node::IsProperty() const {
5040   CXFA_Node* parent = GetParent();
5041   return parent && parent->HasProperty(GetElementType());
5042 }
5043 
PresenceRequiresSpace() const5044 bool CXFA_Node::PresenceRequiresSpace() const {
5045   auto value = JSObject()->TryEnum(XFA_Attribute::Presence, true);
5046   XFA_AttributeValue ePresence = value.value_or(XFA_AttributeValue::Visible);
5047   return ePresence == XFA_AttributeValue::Visible ||
5048          ePresence == XFA_AttributeValue::Invisible;
5049 }
5050 
SetBindingNode(CXFA_Node * node)5051 void CXFA_Node::SetBindingNode(CXFA_Node* node) {
5052   binding_nodes_.clear();
5053   if (node)
5054     binding_nodes_.emplace_back(node);
5055 }
5056 
SetNodeAndDescendantsUnused()5057 void CXFA_Node::SetNodeAndDescendantsUnused() {
5058   CXFA_NodeIterator sIterator(this);
5059   for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
5060        pNode = sIterator.MoveToNext()) {
5061     pNode->SetFlag(XFA_NodeFlag_UnusedNode);
5062   }
5063 }
5064 
SetToXML(const WideString & value)5065 void CXFA_Node::SetToXML(const WideString& value) {
5066   auto* pNode = GetXMLMappingNode();
5067   switch (pNode->GetType()) {
5068     case CFX_XMLNode::Type::kElement: {
5069       auto* elem = static_cast<CFX_XMLElement*>(pNode);
5070       if (IsAttributeInXML()) {
5071         elem->SetAttribute(JSObject()->GetCData(XFA_Attribute::QualifiedName),
5072                            value);
5073         return;
5074       }
5075 
5076       bool bDeleteChildren = true;
5077       if (GetPacketType() == XFA_PacketType::Datasets) {
5078         for (CXFA_Node* pChildDataNode = GetFirstChild(); pChildDataNode;
5079              pChildDataNode = pChildDataNode->GetNextSibling()) {
5080           if (pChildDataNode->HasBindItems()) {
5081             bDeleteChildren = false;
5082             break;
5083           }
5084         }
5085       }
5086       if (bDeleteChildren)
5087         elem->RemoveAllChildren();
5088 
5089       auto* text = GetXMLDocument()->CreateNode<CFX_XMLText>(value);
5090       elem->AppendLastChild(text);
5091       break;
5092     }
5093     case CFX_XMLNode::Type::kText:
5094       ToXMLText(GetXMLMappingNode())->SetText(value);
5095       break;
5096     default:
5097       NOTREACHED();
5098   }
5099 }
5100 
GetTransparentParent()5101 CXFA_Node* CXFA_Node::GetTransparentParent() {
5102   CXFA_Node* parent = GetParent();
5103   while (parent) {
5104     XFA_Element type = parent->GetElementType();
5105     if (type == XFA_Element::Variables ||
5106         (type != XFA_Element::SubformSet && !parent->IsUnnamed())) {
5107       return parent;
5108     }
5109     parent = parent->GetParent();
5110   }
5111   return nullptr;
5112 }
5113 
GetXMLDocument() const5114 CFX_XMLDocument* CXFA_Node::GetXMLDocument() const {
5115   return GetDocument()->GetNotify()->GetFFDoc()->GetXMLDocument();
5116 }
5117 
5118 // static
Create(CXFA_Document * doc,XFA_Element element,XFA_PacketType packet)5119 CXFA_Node* CXFA_Node::Create(CXFA_Document* doc,
5120                              XFA_Element element,
5121                              XFA_PacketType packet) {
5122   CXFA_Node* node = nullptr;
5123   switch (element) {
5124     case XFA_Element::Ps:
5125       node = cppgc::MakeGarbageCollected<CXFA_Ps>(
5126           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5127       break;
5128     case XFA_Element::To:
5129       node = cppgc::MakeGarbageCollected<CXFA_To>(
5130           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5131       break;
5132     case XFA_Element::Ui:
5133       node = cppgc::MakeGarbageCollected<CXFA_Ui>(
5134           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5135       break;
5136     case XFA_Element::RecordSet:
5137       node = cppgc::MakeGarbageCollected<CXFA_RecordSet>(
5138           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5139       break;
5140     case XFA_Element::SubsetBelow:
5141       node = cppgc::MakeGarbageCollected<CXFA_SubsetBelow>(
5142           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5143       break;
5144     case XFA_Element::SubformSet:
5145       node = cppgc::MakeGarbageCollected<CXFA_SubformSet>(
5146           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5147       break;
5148     case XFA_Element::AdobeExtensionLevel:
5149       node = cppgc::MakeGarbageCollected<CXFA_AdobeExtensionLevel>(
5150           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5151       break;
5152     case XFA_Element::Typeface:
5153       node = cppgc::MakeGarbageCollected<CXFA_Typeface>(
5154           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5155       break;
5156     case XFA_Element::Break:
5157       node = cppgc::MakeGarbageCollected<CXFA_Break>(
5158           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5159       break;
5160     case XFA_Element::FontInfo:
5161       node = cppgc::MakeGarbageCollected<CXFA_FontInfo>(
5162           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5163       break;
5164     case XFA_Element::NumberPattern:
5165       node = cppgc::MakeGarbageCollected<CXFA_NumberPattern>(
5166           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5167       break;
5168     case XFA_Element::DynamicRender:
5169       node = cppgc::MakeGarbageCollected<CXFA_DynamicRender>(
5170           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5171       break;
5172     case XFA_Element::PrintScaling:
5173       node = cppgc::MakeGarbageCollected<CXFA_PrintScaling>(
5174           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5175       break;
5176     case XFA_Element::CheckButton:
5177       node = cppgc::MakeGarbageCollected<CXFA_CheckButton>(
5178           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5179       break;
5180     case XFA_Element::DatePatterns:
5181       node = cppgc::MakeGarbageCollected<CXFA_DatePatterns>(
5182           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5183       break;
5184     case XFA_Element::SourceSet:
5185       node = cppgc::MakeGarbageCollected<CXFA_SourceSet>(
5186           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5187       break;
5188     case XFA_Element::Amd:
5189       node = cppgc::MakeGarbageCollected<CXFA_Amd>(
5190           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5191       break;
5192     case XFA_Element::Arc:
5193       node = cppgc::MakeGarbageCollected<CXFA_Arc>(
5194           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5195       break;
5196     case XFA_Element::Day:
5197       node = cppgc::MakeGarbageCollected<CXFA_Day>(
5198           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5199       break;
5200     case XFA_Element::Era:
5201       node = cppgc::MakeGarbageCollected<CXFA_Era>(
5202           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5203       break;
5204     case XFA_Element::Jog:
5205       node = cppgc::MakeGarbageCollected<CXFA_Jog>(
5206           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5207       break;
5208     case XFA_Element::Log:
5209       node = cppgc::MakeGarbageCollected<CXFA_Log>(
5210           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5211       break;
5212     case XFA_Element::Map:
5213       node = cppgc::MakeGarbageCollected<CXFA_Map>(
5214           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5215       break;
5216     case XFA_Element::Mdp:
5217       node = cppgc::MakeGarbageCollected<CXFA_Mdp>(
5218           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5219       break;
5220     case XFA_Element::BreakBefore:
5221       node = cppgc::MakeGarbageCollected<CXFA_BreakBefore>(
5222           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5223       break;
5224     case XFA_Element::Oid:
5225       node = cppgc::MakeGarbageCollected<CXFA_Oid>(
5226           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5227       break;
5228     case XFA_Element::Pcl:
5229       node = cppgc::MakeGarbageCollected<CXFA_Pcl>(
5230           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5231       break;
5232     case XFA_Element::Pdf:
5233       node = cppgc::MakeGarbageCollected<CXFA_Pdf>(
5234           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5235       break;
5236     case XFA_Element::Ref:
5237       node = cppgc::MakeGarbageCollected<CXFA_Ref>(
5238           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5239       break;
5240     case XFA_Element::Uri:
5241       node = cppgc::MakeGarbageCollected<CXFA_Uri>(
5242           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5243       break;
5244     case XFA_Element::Xdc:
5245       node = cppgc::MakeGarbageCollected<CXFA_Xdc>(
5246           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5247       break;
5248     case XFA_Element::Xdp:
5249       node = cppgc::MakeGarbageCollected<CXFA_Xdp>(
5250           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5251       break;
5252     case XFA_Element::Xfa:
5253       node = cppgc::MakeGarbageCollected<CXFA_Xfa>(
5254           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5255       break;
5256     case XFA_Element::Xsl:
5257       node = cppgc::MakeGarbageCollected<CXFA_Xsl>(
5258           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5259       break;
5260     case XFA_Element::Zpl:
5261       node = cppgc::MakeGarbageCollected<CXFA_Zpl>(
5262           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5263       break;
5264     case XFA_Element::Cache:
5265       node = cppgc::MakeGarbageCollected<CXFA_Cache>(
5266           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5267       break;
5268     case XFA_Element::Margin:
5269       node = cppgc::MakeGarbageCollected<CXFA_Margin>(
5270           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5271       break;
5272     case XFA_Element::KeyUsage:
5273       node = cppgc::MakeGarbageCollected<CXFA_KeyUsage>(
5274           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5275       break;
5276     case XFA_Element::Exclude:
5277       node = cppgc::MakeGarbageCollected<CXFA_Exclude>(
5278           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5279       break;
5280     case XFA_Element::ChoiceList:
5281       node = cppgc::MakeGarbageCollected<CXFA_ChoiceList>(
5282           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5283       break;
5284     case XFA_Element::Level:
5285       node = cppgc::MakeGarbageCollected<CXFA_Level>(
5286           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5287       break;
5288     case XFA_Element::LabelPrinter:
5289       node = cppgc::MakeGarbageCollected<CXFA_LabelPrinter>(
5290           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5291       break;
5292     case XFA_Element::CalendarSymbols:
5293       node = cppgc::MakeGarbageCollected<CXFA_CalendarSymbols>(
5294           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5295       break;
5296     case XFA_Element::Para:
5297       node = cppgc::MakeGarbageCollected<CXFA_Para>(
5298           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5299       break;
5300     case XFA_Element::Part:
5301       node = cppgc::MakeGarbageCollected<CXFA_Part>(
5302           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5303       break;
5304     case XFA_Element::Pdfa:
5305       node = cppgc::MakeGarbageCollected<CXFA_Pdfa>(
5306           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5307       break;
5308     case XFA_Element::Filter:
5309       node = cppgc::MakeGarbageCollected<CXFA_Filter>(
5310           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5311       break;
5312     case XFA_Element::Present:
5313       node = cppgc::MakeGarbageCollected<CXFA_Present>(
5314           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5315       break;
5316     case XFA_Element::Pagination:
5317       node = cppgc::MakeGarbageCollected<CXFA_Pagination>(
5318           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5319       break;
5320     case XFA_Element::Encoding:
5321       node = cppgc::MakeGarbageCollected<CXFA_Encoding>(
5322           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5323       break;
5324     case XFA_Element::Event:
5325       node = cppgc::MakeGarbageCollected<CXFA_Event>(
5326           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5327       break;
5328     case XFA_Element::Whitespace:
5329       node = cppgc::MakeGarbageCollected<CXFA_Whitespace>(
5330           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5331       break;
5332     case XFA_Element::DefaultUi:
5333       node = cppgc::MakeGarbageCollected<CXFA_DefaultUi>(
5334           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5335       break;
5336     case XFA_Element::DataModel:
5337       node = cppgc::MakeGarbageCollected<CXFA_DataModel>(
5338           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5339       break;
5340     case XFA_Element::Barcode:
5341       node = cppgc::MakeGarbageCollected<CXFA_Barcode>(
5342           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5343       break;
5344     case XFA_Element::TimePattern:
5345       node = cppgc::MakeGarbageCollected<CXFA_TimePattern>(
5346           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5347       break;
5348     case XFA_Element::BatchOutput:
5349       node = cppgc::MakeGarbageCollected<CXFA_BatchOutput>(
5350           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5351       break;
5352     case XFA_Element::Enforce:
5353       node = cppgc::MakeGarbageCollected<CXFA_Enforce>(
5354           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5355       break;
5356     case XFA_Element::CurrencySymbols:
5357       node = cppgc::MakeGarbageCollected<CXFA_CurrencySymbols>(
5358           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5359       break;
5360     case XFA_Element::AddSilentPrint:
5361       node = cppgc::MakeGarbageCollected<CXFA_AddSilentPrint>(
5362           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5363       break;
5364     case XFA_Element::Rename:
5365       node = cppgc::MakeGarbageCollected<CXFA_Rename>(
5366           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5367       break;
5368     case XFA_Element::Operation:
5369       node = cppgc::MakeGarbageCollected<CXFA_Operation>(
5370           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5371       break;
5372     case XFA_Element::Typefaces:
5373       node = cppgc::MakeGarbageCollected<CXFA_Typefaces>(
5374           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5375       break;
5376     case XFA_Element::SubjectDNs:
5377       node = cppgc::MakeGarbageCollected<CXFA_SubjectDNs>(
5378           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5379       break;
5380     case XFA_Element::Issuers:
5381       node = cppgc::MakeGarbageCollected<CXFA_Issuers>(
5382           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5383       break;
5384     case XFA_Element::WsdlConnection:
5385       node = cppgc::MakeGarbageCollected<CXFA_WsdlConnection>(
5386           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5387       break;
5388     case XFA_Element::Debug:
5389       node = cppgc::MakeGarbageCollected<CXFA_Debug>(
5390           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5391       break;
5392     case XFA_Element::Delta:
5393       node = cppgc::MakeGarbageCollected<CXFA_Delta>(
5394           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5395       break;
5396     case XFA_Element::EraNames:
5397       node = cppgc::MakeGarbageCollected<CXFA_EraNames>(
5398           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5399       break;
5400     case XFA_Element::ModifyAnnots:
5401       node = cppgc::MakeGarbageCollected<CXFA_ModifyAnnots>(
5402           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5403       break;
5404     case XFA_Element::StartNode:
5405       node = cppgc::MakeGarbageCollected<CXFA_StartNode>(
5406           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5407       break;
5408     case XFA_Element::Button:
5409       node = cppgc::MakeGarbageCollected<CXFA_Button>(
5410           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5411       break;
5412     case XFA_Element::Format:
5413       node = cppgc::MakeGarbageCollected<CXFA_Format>(
5414           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5415       break;
5416     case XFA_Element::Border:
5417       node = cppgc::MakeGarbageCollected<CXFA_Border>(
5418           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5419       break;
5420     case XFA_Element::Area:
5421       node = cppgc::MakeGarbageCollected<CXFA_Area>(
5422           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5423       break;
5424     case XFA_Element::Hyphenation:
5425       node = cppgc::MakeGarbageCollected<CXFA_Hyphenation>(
5426           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5427       break;
5428     case XFA_Element::Text:
5429       node = cppgc::MakeGarbageCollected<CXFA_Text>(
5430           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5431       break;
5432     case XFA_Element::Time:
5433       node = cppgc::MakeGarbageCollected<CXFA_Time>(
5434           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5435       break;
5436     case XFA_Element::Type:
5437       node = cppgc::MakeGarbageCollected<CXFA_Type>(
5438           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5439       break;
5440     case XFA_Element::Overprint:
5441       node = cppgc::MakeGarbageCollected<CXFA_Overprint>(
5442           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5443       break;
5444     case XFA_Element::Certificates:
5445       node = cppgc::MakeGarbageCollected<CXFA_Certificates>(
5446           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5447       break;
5448     case XFA_Element::EncryptionMethods:
5449       node = cppgc::MakeGarbageCollected<CXFA_EncryptionMethods>(
5450           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5451       break;
5452     case XFA_Element::SetProperty:
5453       node = cppgc::MakeGarbageCollected<CXFA_SetProperty>(
5454           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5455       break;
5456     case XFA_Element::PrinterName:
5457       node = cppgc::MakeGarbageCollected<CXFA_PrinterName>(
5458           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5459       break;
5460     case XFA_Element::StartPage:
5461       node = cppgc::MakeGarbageCollected<CXFA_StartPage>(
5462           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5463       break;
5464     case XFA_Element::PageOffset:
5465       node = cppgc::MakeGarbageCollected<CXFA_PageOffset>(
5466           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5467       break;
5468     case XFA_Element::DateTime:
5469       node = cppgc::MakeGarbageCollected<CXFA_DateTime>(
5470           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5471       break;
5472     case XFA_Element::Comb:
5473       node = cppgc::MakeGarbageCollected<CXFA_Comb>(
5474           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5475       break;
5476     case XFA_Element::Pattern:
5477       node = cppgc::MakeGarbageCollected<CXFA_Pattern>(
5478           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5479       break;
5480     case XFA_Element::IfEmpty:
5481       node = cppgc::MakeGarbageCollected<CXFA_IfEmpty>(
5482           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5483       break;
5484     case XFA_Element::SuppressBanner:
5485       node = cppgc::MakeGarbageCollected<CXFA_SuppressBanner>(
5486           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5487       break;
5488     case XFA_Element::OutputBin:
5489       node = cppgc::MakeGarbageCollected<CXFA_OutputBin>(
5490           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5491       break;
5492     case XFA_Element::Field:
5493       node = cppgc::MakeGarbageCollected<CXFA_Field>(
5494           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5495       break;
5496     case XFA_Element::Agent:
5497       node = cppgc::MakeGarbageCollected<CXFA_Agent>(
5498           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5499       break;
5500     case XFA_Element::OutputXSL:
5501       node = cppgc::MakeGarbageCollected<CXFA_OutputXSL>(
5502           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5503       break;
5504     case XFA_Element::AdjustData:
5505       node = cppgc::MakeGarbageCollected<CXFA_AdjustData>(
5506           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5507       break;
5508     case XFA_Element::AutoSave:
5509       node = cppgc::MakeGarbageCollected<CXFA_AutoSave>(
5510           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5511       break;
5512     case XFA_Element::ContentArea:
5513       node = cppgc::MakeGarbageCollected<CXFA_ContentArea>(
5514           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5515       break;
5516     case XFA_Element::WsdlAddress:
5517       node = cppgc::MakeGarbageCollected<CXFA_WsdlAddress>(
5518           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5519       break;
5520     case XFA_Element::Solid:
5521       node = cppgc::MakeGarbageCollected<CXFA_Solid>(
5522           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5523       break;
5524     case XFA_Element::DateTimeSymbols:
5525       node = cppgc::MakeGarbageCollected<CXFA_DateTimeSymbols>(
5526           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5527       break;
5528     case XFA_Element::EncryptionLevel:
5529       node = cppgc::MakeGarbageCollected<CXFA_EncryptionLevel>(
5530           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5531       break;
5532     case XFA_Element::Edge:
5533       node = cppgc::MakeGarbageCollected<CXFA_Edge>(
5534           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5535       break;
5536     case XFA_Element::Stipple:
5537       node = cppgc::MakeGarbageCollected<CXFA_Stipple>(
5538           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5539       break;
5540     case XFA_Element::Attributes:
5541       node = cppgc::MakeGarbageCollected<CXFA_Attributes>(
5542           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5543       break;
5544     case XFA_Element::VersionControl:
5545       node = cppgc::MakeGarbageCollected<CXFA_VersionControl>(
5546           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5547       break;
5548     case XFA_Element::Meridiem:
5549       node = cppgc::MakeGarbageCollected<CXFA_Meridiem>(
5550           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5551       break;
5552     case XFA_Element::ExclGroup:
5553       node = cppgc::MakeGarbageCollected<CXFA_ExclGroup>(
5554           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5555       break;
5556     case XFA_Element::ToolTip:
5557       node = cppgc::MakeGarbageCollected<CXFA_ToolTip>(
5558           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5559       break;
5560     case XFA_Element::Compress:
5561       node = cppgc::MakeGarbageCollected<CXFA_Compress>(
5562           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5563       break;
5564     case XFA_Element::Reason:
5565       node = cppgc::MakeGarbageCollected<CXFA_Reason>(
5566           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5567       break;
5568     case XFA_Element::Execute:
5569       node = cppgc::MakeGarbageCollected<CXFA_Execute>(
5570           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5571       break;
5572     case XFA_Element::ContentCopy:
5573       node = cppgc::MakeGarbageCollected<CXFA_ContentCopy>(
5574           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5575       break;
5576     case XFA_Element::DateTimeEdit:
5577       node = cppgc::MakeGarbageCollected<CXFA_DateTimeEdit>(
5578           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5579       break;
5580     case XFA_Element::Config:
5581       node = cppgc::MakeGarbageCollected<CXFA_Config>(
5582           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5583       break;
5584     case XFA_Element::Image:
5585       node = cppgc::MakeGarbageCollected<CXFA_Image>(
5586           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5587       break;
5588     case XFA_Element::SharpxHTML:
5589       node = cppgc::MakeGarbageCollected<CXFA_SharpxHTML>(
5590           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5591       break;
5592     case XFA_Element::NumberOfCopies:
5593       node = cppgc::MakeGarbageCollected<CXFA_NumberOfCopies>(
5594           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5595       break;
5596     case XFA_Element::BehaviorOverride:
5597       node = cppgc::MakeGarbageCollected<CXFA_BehaviorOverride>(
5598           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5599       break;
5600     case XFA_Element::TimeStamp:
5601       node = cppgc::MakeGarbageCollected<CXFA_TimeStamp>(
5602           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5603       break;
5604     case XFA_Element::Month:
5605       node = cppgc::MakeGarbageCollected<CXFA_Month>(
5606           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5607       break;
5608     case XFA_Element::ViewerPreferences:
5609       node = cppgc::MakeGarbageCollected<CXFA_ViewerPreferences>(
5610           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5611       break;
5612     case XFA_Element::ScriptModel:
5613       node = cppgc::MakeGarbageCollected<CXFA_ScriptModel>(
5614           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5615       break;
5616     case XFA_Element::Decimal:
5617       node = cppgc::MakeGarbageCollected<CXFA_Decimal>(
5618           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5619       break;
5620     case XFA_Element::Subform:
5621       node = cppgc::MakeGarbageCollected<CXFA_Subform>(
5622           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5623       break;
5624     case XFA_Element::Select:
5625       node = cppgc::MakeGarbageCollected<CXFA_Select>(
5626           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5627       break;
5628     case XFA_Element::Window:
5629       node = cppgc::MakeGarbageCollected<CXFA_Window>(
5630           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5631       break;
5632     case XFA_Element::LocaleSet:
5633       node = cppgc::MakeGarbageCollected<CXFA_LocaleSet>(
5634           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5635       break;
5636     case XFA_Element::Handler:
5637       node = cppgc::MakeGarbageCollected<CXFA_Handler>(
5638           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5639       break;
5640     case XFA_Element::Presence:
5641       node = cppgc::MakeGarbageCollected<CXFA_Presence>(
5642           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5643       break;
5644     case XFA_Element::Record:
5645       node = cppgc::MakeGarbageCollected<CXFA_Record>(
5646           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5647       break;
5648     case XFA_Element::Embed:
5649       node = cppgc::MakeGarbageCollected<CXFA_Embed>(
5650           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5651       break;
5652     case XFA_Element::Version:
5653       node = cppgc::MakeGarbageCollected<CXFA_Version>(
5654           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5655       break;
5656     case XFA_Element::Command:
5657       node = cppgc::MakeGarbageCollected<CXFA_Command>(
5658           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5659       break;
5660     case XFA_Element::Copies:
5661       node = cppgc::MakeGarbageCollected<CXFA_Copies>(
5662           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5663       break;
5664     case XFA_Element::Staple:
5665       node = cppgc::MakeGarbageCollected<CXFA_Staple>(
5666           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5667       break;
5668     case XFA_Element::SubmitFormat:
5669       node = cppgc::MakeGarbageCollected<CXFA_SubmitFormat>(
5670           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5671       break;
5672     case XFA_Element::Boolean:
5673       node = cppgc::MakeGarbageCollected<CXFA_Boolean>(
5674           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5675       break;
5676     case XFA_Element::Message:
5677       node = cppgc::MakeGarbageCollected<CXFA_Message>(
5678           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5679       break;
5680     case XFA_Element::Output:
5681       node = cppgc::MakeGarbageCollected<CXFA_Output>(
5682           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5683       break;
5684     case XFA_Element::PsMap:
5685       node = cppgc::MakeGarbageCollected<CXFA_PsMap>(
5686           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5687       break;
5688     case XFA_Element::ExcludeNS:
5689       node = cppgc::MakeGarbageCollected<CXFA_ExcludeNS>(
5690           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5691       break;
5692     case XFA_Element::Assist:
5693       node = cppgc::MakeGarbageCollected<CXFA_Assist>(
5694           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5695       break;
5696     case XFA_Element::Picture:
5697       node = cppgc::MakeGarbageCollected<CXFA_Picture>(
5698           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5699       break;
5700     case XFA_Element::Traversal:
5701       node = cppgc::MakeGarbageCollected<CXFA_Traversal>(
5702           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5703       break;
5704     case XFA_Element::SilentPrint:
5705       node = cppgc::MakeGarbageCollected<CXFA_SilentPrint>(
5706           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5707       break;
5708     case XFA_Element::WebClient:
5709       node = cppgc::MakeGarbageCollected<CXFA_WebClient>(
5710           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5711       break;
5712     case XFA_Element::Producer:
5713       node = cppgc::MakeGarbageCollected<CXFA_Producer>(
5714           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5715       break;
5716     case XFA_Element::Corner:
5717       node = cppgc::MakeGarbageCollected<CXFA_Corner>(
5718           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5719       break;
5720     case XFA_Element::MsgId:
5721       node = cppgc::MakeGarbageCollected<CXFA_MsgId>(
5722           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5723       break;
5724     case XFA_Element::Color:
5725       node = cppgc::MakeGarbageCollected<CXFA_Color>(
5726           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5727       break;
5728     case XFA_Element::Keep:
5729       node = cppgc::MakeGarbageCollected<CXFA_Keep>(
5730           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5731       break;
5732     case XFA_Element::Query:
5733       node = cppgc::MakeGarbageCollected<CXFA_Query>(
5734           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5735       break;
5736     case XFA_Element::Insert:
5737       node = cppgc::MakeGarbageCollected<CXFA_Insert>(
5738           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5739       break;
5740     case XFA_Element::ImageEdit:
5741       node = cppgc::MakeGarbageCollected<CXFA_ImageEdit>(
5742           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5743       break;
5744     case XFA_Element::Validate:
5745       node = cppgc::MakeGarbageCollected<CXFA_Validate>(
5746           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5747       break;
5748     case XFA_Element::DigestMethods:
5749       node = cppgc::MakeGarbageCollected<CXFA_DigestMethods>(
5750           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5751       break;
5752     case XFA_Element::NumberPatterns:
5753       node = cppgc::MakeGarbageCollected<CXFA_NumberPatterns>(
5754           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5755       break;
5756     case XFA_Element::PageSet:
5757       node = cppgc::MakeGarbageCollected<CXFA_PageSet>(
5758           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5759       break;
5760     case XFA_Element::Integer:
5761       node = cppgc::MakeGarbageCollected<CXFA_Integer>(
5762           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5763       break;
5764     case XFA_Element::SoapAddress:
5765       node = cppgc::MakeGarbageCollected<CXFA_SoapAddress>(
5766           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5767       break;
5768     case XFA_Element::Equate:
5769       node = cppgc::MakeGarbageCollected<CXFA_Equate>(
5770           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5771       break;
5772     case XFA_Element::FormFieldFilling:
5773       node = cppgc::MakeGarbageCollected<CXFA_FormFieldFilling>(
5774           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5775       break;
5776     case XFA_Element::PageRange:
5777       node = cppgc::MakeGarbageCollected<CXFA_PageRange>(
5778           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5779       break;
5780     case XFA_Element::Update:
5781       node = cppgc::MakeGarbageCollected<CXFA_Update>(
5782           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5783       break;
5784     case XFA_Element::ConnectString:
5785       node = cppgc::MakeGarbageCollected<CXFA_ConnectString>(
5786           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5787       break;
5788     case XFA_Element::Mode:
5789       node = cppgc::MakeGarbageCollected<CXFA_Mode>(
5790           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5791       break;
5792     case XFA_Element::Layout:
5793       node = cppgc::MakeGarbageCollected<CXFA_Layout>(
5794           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5795       break;
5796     case XFA_Element::Sharpxml:
5797       node = cppgc::MakeGarbageCollected<CXFA_Sharpxml>(
5798           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5799       break;
5800     case XFA_Element::XsdConnection:
5801       node = cppgc::MakeGarbageCollected<CXFA_XsdConnection>(
5802           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5803       break;
5804     case XFA_Element::Traverse:
5805       node = cppgc::MakeGarbageCollected<CXFA_Traverse>(
5806           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5807       break;
5808     case XFA_Element::Encodings:
5809       node = cppgc::MakeGarbageCollected<CXFA_Encodings>(
5810           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5811       break;
5812     case XFA_Element::Template:
5813       node = cppgc::MakeGarbageCollected<CXFA_Template>(
5814           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5815       break;
5816     case XFA_Element::Acrobat:
5817       node = cppgc::MakeGarbageCollected<CXFA_Acrobat>(
5818           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5819       break;
5820     case XFA_Element::ValidationMessaging:
5821       node = cppgc::MakeGarbageCollected<CXFA_ValidationMessaging>(
5822           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5823       break;
5824     case XFA_Element::Signing:
5825       node = cppgc::MakeGarbageCollected<CXFA_Signing>(
5826           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5827       break;
5828     case XFA_Element::Script:
5829       node = cppgc::MakeGarbageCollected<CXFA_Script>(
5830           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5831       break;
5832     case XFA_Element::AddViewerPreferences:
5833       node = cppgc::MakeGarbageCollected<CXFA_AddViewerPreferences>(
5834           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5835       break;
5836     case XFA_Element::AlwaysEmbed:
5837       node = cppgc::MakeGarbageCollected<CXFA_AlwaysEmbed>(
5838           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5839       break;
5840     case XFA_Element::PasswordEdit:
5841       node = cppgc::MakeGarbageCollected<CXFA_PasswordEdit>(
5842           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5843       break;
5844     case XFA_Element::NumericEdit:
5845       node = cppgc::MakeGarbageCollected<CXFA_NumericEdit>(
5846           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5847       break;
5848     case XFA_Element::EncryptionMethod:
5849       node = cppgc::MakeGarbageCollected<CXFA_EncryptionMethod>(
5850           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5851       break;
5852     case XFA_Element::Change:
5853       node = cppgc::MakeGarbageCollected<CXFA_Change>(
5854           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5855       break;
5856     case XFA_Element::PageArea:
5857       node = cppgc::MakeGarbageCollected<CXFA_PageArea>(
5858           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5859       break;
5860     case XFA_Element::SubmitUrl:
5861       node = cppgc::MakeGarbageCollected<CXFA_SubmitUrl>(
5862           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5863       break;
5864     case XFA_Element::Oids:
5865       node = cppgc::MakeGarbageCollected<CXFA_Oids>(
5866           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5867       break;
5868     case XFA_Element::Signature:
5869       node = cppgc::MakeGarbageCollected<CXFA_Signature>(
5870           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5871       break;
5872     case XFA_Element::ADBE_JSConsole:
5873       node = cppgc::MakeGarbageCollected<CXFA_ADBE_JSConsole>(
5874           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5875       break;
5876     case XFA_Element::Caption:
5877       node = cppgc::MakeGarbageCollected<CXFA_Caption>(
5878           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5879       break;
5880     case XFA_Element::Relevant:
5881       node = cppgc::MakeGarbageCollected<CXFA_Relevant>(
5882           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5883       break;
5884     case XFA_Element::FlipLabel:
5885       node = cppgc::MakeGarbageCollected<CXFA_FlipLabel>(
5886           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5887       break;
5888     case XFA_Element::ExData:
5889       node = cppgc::MakeGarbageCollected<CXFA_ExData>(
5890           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5891       break;
5892     case XFA_Element::DayNames:
5893       node = cppgc::MakeGarbageCollected<CXFA_DayNames>(
5894           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5895       break;
5896     case XFA_Element::SoapAction:
5897       node = cppgc::MakeGarbageCollected<CXFA_SoapAction>(
5898           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5899       break;
5900     case XFA_Element::DefaultTypeface:
5901       node = cppgc::MakeGarbageCollected<CXFA_DefaultTypeface>(
5902           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5903       break;
5904     case XFA_Element::Manifest:
5905       node = cppgc::MakeGarbageCollected<CXFA_Manifest>(
5906           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5907       break;
5908     case XFA_Element::Overflow:
5909       node = cppgc::MakeGarbageCollected<CXFA_Overflow>(
5910           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5911       break;
5912     case XFA_Element::Linear:
5913       node = cppgc::MakeGarbageCollected<CXFA_Linear>(
5914           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5915       break;
5916     case XFA_Element::CurrencySymbol:
5917       node = cppgc::MakeGarbageCollected<CXFA_CurrencySymbol>(
5918           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5919       break;
5920     case XFA_Element::Delete:
5921       node = cppgc::MakeGarbageCollected<CXFA_Delete>(
5922           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5923       break;
5924     case XFA_Element::DigestMethod:
5925       node = cppgc::MakeGarbageCollected<CXFA_DigestMethod>(
5926           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5927       break;
5928     case XFA_Element::InstanceManager:
5929       node = cppgc::MakeGarbageCollected<CXFA_InstanceManager>(
5930           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5931       break;
5932     case XFA_Element::EquateRange:
5933       node = cppgc::MakeGarbageCollected<CXFA_EquateRange>(
5934           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5935       break;
5936     case XFA_Element::Medium:
5937       node = cppgc::MakeGarbageCollected<CXFA_Medium>(
5938           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5939       break;
5940     case XFA_Element::TextEdit:
5941       node = cppgc::MakeGarbageCollected<CXFA_TextEdit>(
5942           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5943       break;
5944     case XFA_Element::TemplateCache:
5945       node = cppgc::MakeGarbageCollected<CXFA_TemplateCache>(
5946           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5947       break;
5948     case XFA_Element::CompressObjectStream:
5949       node = cppgc::MakeGarbageCollected<CXFA_CompressObjectStream>(
5950           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5951       break;
5952     case XFA_Element::DataValue:
5953       node = cppgc::MakeGarbageCollected<CXFA_DataValue>(
5954           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5955       break;
5956     case XFA_Element::AccessibleContent:
5957       node = cppgc::MakeGarbageCollected<CXFA_AccessibleContent>(
5958           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5959       break;
5960     case XFA_Element::IncludeXDPContent:
5961       node = cppgc::MakeGarbageCollected<CXFA_IncludeXDPContent>(
5962           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5963       break;
5964     case XFA_Element::XmlConnection:
5965       node = cppgc::MakeGarbageCollected<CXFA_XmlConnection>(
5966           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5967       break;
5968     case XFA_Element::ValidateApprovalSignatures:
5969       node = cppgc::MakeGarbageCollected<CXFA_ValidateApprovalSignatures>(
5970           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5971       break;
5972     case XFA_Element::SignData:
5973       node = cppgc::MakeGarbageCollected<CXFA_SignData>(
5974           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5975       break;
5976     case XFA_Element::Packets:
5977       node = cppgc::MakeGarbageCollected<CXFA_Packets>(
5978           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5979       break;
5980     case XFA_Element::DatePattern:
5981       node = cppgc::MakeGarbageCollected<CXFA_DatePattern>(
5982           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5983       break;
5984     case XFA_Element::DuplexOption:
5985       node = cppgc::MakeGarbageCollected<CXFA_DuplexOption>(
5986           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5987       break;
5988     case XFA_Element::Base:
5989       node = cppgc::MakeGarbageCollected<CXFA_Base>(
5990           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5991       break;
5992     case XFA_Element::Bind:
5993       node = cppgc::MakeGarbageCollected<CXFA_Bind>(
5994           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5995       break;
5996     case XFA_Element::Compression:
5997       node = cppgc::MakeGarbageCollected<CXFA_Compression>(
5998           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5999       break;
6000     case XFA_Element::User:
6001       node = cppgc::MakeGarbageCollected<CXFA_User>(
6002           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6003       break;
6004     case XFA_Element::Rectangle:
6005       node = cppgc::MakeGarbageCollected<CXFA_Rectangle>(
6006           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6007       break;
6008     case XFA_Element::EffectiveOutputPolicy:
6009       node = cppgc::MakeGarbageCollected<CXFA_EffectiveOutputPolicy>(
6010           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6011       break;
6012     case XFA_Element::ADBE_JSDebugger:
6013       node = cppgc::MakeGarbageCollected<CXFA_ADBE_JSDebugger>(
6014           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6015       break;
6016     case XFA_Element::Acrobat7:
6017       node = cppgc::MakeGarbageCollected<CXFA_Acrobat7>(
6018           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6019       break;
6020     case XFA_Element::Interactive:
6021       node = cppgc::MakeGarbageCollected<CXFA_Interactive>(
6022           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6023       break;
6024     case XFA_Element::Locale:
6025       node = cppgc::MakeGarbageCollected<CXFA_Locale>(
6026           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6027       break;
6028     case XFA_Element::CurrentPage:
6029       node = cppgc::MakeGarbageCollected<CXFA_CurrentPage>(
6030           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6031       break;
6032     case XFA_Element::Data:
6033       node = cppgc::MakeGarbageCollected<CXFA_Data>(
6034           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6035       break;
6036     case XFA_Element::Date:
6037       node = cppgc::MakeGarbageCollected<CXFA_Date>(
6038           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6039       break;
6040     case XFA_Element::Desc:
6041       node = cppgc::MakeGarbageCollected<CXFA_Desc>(
6042           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6043       break;
6044     case XFA_Element::Encrypt:
6045       node = cppgc::MakeGarbageCollected<CXFA_Encrypt>(
6046           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6047       break;
6048     case XFA_Element::Draw:
6049       node = cppgc::MakeGarbageCollected<CXFA_Draw>(
6050           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6051       break;
6052     case XFA_Element::Encryption:
6053       node = cppgc::MakeGarbageCollected<CXFA_Encryption>(
6054           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6055       break;
6056     case XFA_Element::MeridiemNames:
6057       node = cppgc::MakeGarbageCollected<CXFA_MeridiemNames>(
6058           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6059       break;
6060     case XFA_Element::Messaging:
6061       node = cppgc::MakeGarbageCollected<CXFA_Messaging>(
6062           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6063       break;
6064     case XFA_Element::Speak:
6065       node = cppgc::MakeGarbageCollected<CXFA_Speak>(
6066           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6067       break;
6068     case XFA_Element::DataGroup:
6069       node = cppgc::MakeGarbageCollected<CXFA_DataGroup>(
6070           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6071       break;
6072     case XFA_Element::Common:
6073       node = cppgc::MakeGarbageCollected<CXFA_Common>(
6074           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6075       break;
6076     case XFA_Element::Sharptext:
6077       node = cppgc::MakeGarbageCollected<CXFA_Sharptext>(
6078           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6079       break;
6080     case XFA_Element::PaginationOverride:
6081       node = cppgc::MakeGarbageCollected<CXFA_PaginationOverride>(
6082           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6083       break;
6084     case XFA_Element::Reasons:
6085       node = cppgc::MakeGarbageCollected<CXFA_Reasons>(
6086           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6087       break;
6088     case XFA_Element::SignatureProperties:
6089       node = cppgc::MakeGarbageCollected<CXFA_SignatureProperties>(
6090           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6091       break;
6092     case XFA_Element::Threshold:
6093       node = cppgc::MakeGarbageCollected<CXFA_Threshold>(
6094           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6095       break;
6096     case XFA_Element::AppearanceFilter:
6097       node = cppgc::MakeGarbageCollected<CXFA_AppearanceFilter>(
6098           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6099       break;
6100     case XFA_Element::Fill:
6101       node = cppgc::MakeGarbageCollected<CXFA_Fill>(
6102           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6103       break;
6104     case XFA_Element::Font:
6105       node = cppgc::MakeGarbageCollected<CXFA_Font>(
6106           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6107       break;
6108     case XFA_Element::Form:
6109       node = cppgc::MakeGarbageCollected<CXFA_Form>(
6110           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6111       break;
6112     case XFA_Element::MediumInfo:
6113       node = cppgc::MakeGarbageCollected<CXFA_MediumInfo>(
6114           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6115       break;
6116     case XFA_Element::Certificate:
6117       node = cppgc::MakeGarbageCollected<CXFA_Certificate>(
6118           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6119       break;
6120     case XFA_Element::Password:
6121       node = cppgc::MakeGarbageCollected<CXFA_Password>(
6122           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6123       break;
6124     case XFA_Element::RunScripts:
6125       node = cppgc::MakeGarbageCollected<CXFA_RunScripts>(
6126           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6127       break;
6128     case XFA_Element::Trace:
6129       node = cppgc::MakeGarbageCollected<CXFA_Trace>(
6130           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6131       break;
6132     case XFA_Element::Float:
6133       node = cppgc::MakeGarbageCollected<CXFA_Float>(
6134           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6135       break;
6136     case XFA_Element::RenderPolicy:
6137       node = cppgc::MakeGarbageCollected<CXFA_RenderPolicy>(
6138           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6139       break;
6140     case XFA_Element::Destination:
6141       node = cppgc::MakeGarbageCollected<CXFA_Destination>(
6142           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6143       break;
6144     case XFA_Element::Value:
6145       node = cppgc::MakeGarbageCollected<CXFA_Value>(
6146           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6147       break;
6148     case XFA_Element::Bookend:
6149       node = cppgc::MakeGarbageCollected<CXFA_Bookend>(
6150           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6151       break;
6152     case XFA_Element::ExObject:
6153       node = cppgc::MakeGarbageCollected<CXFA_ExObject>(
6154           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6155       break;
6156     case XFA_Element::OpenAction:
6157       node = cppgc::MakeGarbageCollected<CXFA_OpenAction>(
6158           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6159       break;
6160     case XFA_Element::NeverEmbed:
6161       node = cppgc::MakeGarbageCollected<CXFA_NeverEmbed>(
6162           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6163       break;
6164     case XFA_Element::BindItems:
6165       node = cppgc::MakeGarbageCollected<CXFA_BindItems>(
6166           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6167       break;
6168     case XFA_Element::Calculate:
6169       node = cppgc::MakeGarbageCollected<CXFA_Calculate>(
6170           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6171       break;
6172     case XFA_Element::Print:
6173       node = cppgc::MakeGarbageCollected<CXFA_Print>(
6174           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6175       break;
6176     case XFA_Element::Extras:
6177       node = cppgc::MakeGarbageCollected<CXFA_Extras>(
6178           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6179       break;
6180     case XFA_Element::Proto:
6181       node = cppgc::MakeGarbageCollected<CXFA_Proto>(
6182           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6183       break;
6184     case XFA_Element::DSigData:
6185       node = cppgc::MakeGarbageCollected<CXFA_DSigData>(
6186           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6187       break;
6188     case XFA_Element::Creator:
6189       node = cppgc::MakeGarbageCollected<CXFA_Creator>(
6190           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6191       break;
6192     case XFA_Element::Connect:
6193       node = cppgc::MakeGarbageCollected<CXFA_Connect>(
6194           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6195       break;
6196     case XFA_Element::Permissions:
6197       node = cppgc::MakeGarbageCollected<CXFA_Permissions>(
6198           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6199       break;
6200     case XFA_Element::ConnectionSet:
6201       node = cppgc::MakeGarbageCollected<CXFA_ConnectionSet>(
6202           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6203       break;
6204     case XFA_Element::Submit:
6205       node = cppgc::MakeGarbageCollected<CXFA_Submit>(
6206           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6207       break;
6208     case XFA_Element::Range:
6209       node = cppgc::MakeGarbageCollected<CXFA_Range>(
6210           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6211       break;
6212     case XFA_Element::Linearized:
6213       node = cppgc::MakeGarbageCollected<CXFA_Linearized>(
6214           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6215       break;
6216     case XFA_Element::Packet:
6217       node = cppgc::MakeGarbageCollected<CXFA_Packet>(
6218           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6219       break;
6220     case XFA_Element::RootElement:
6221       node = cppgc::MakeGarbageCollected<CXFA_RootElement>(
6222           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6223       break;
6224     case XFA_Element::PlaintextMetadata:
6225       node = cppgc::MakeGarbageCollected<CXFA_PlaintextMetadata>(
6226           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6227       break;
6228     case XFA_Element::NumberSymbols:
6229       node = cppgc::MakeGarbageCollected<CXFA_NumberSymbols>(
6230           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6231       break;
6232     case XFA_Element::PrintHighQuality:
6233       node = cppgc::MakeGarbageCollected<CXFA_PrintHighQuality>(
6234           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6235       break;
6236     case XFA_Element::Driver:
6237       node = cppgc::MakeGarbageCollected<CXFA_Driver>(
6238           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6239       break;
6240     case XFA_Element::IncrementalLoad:
6241       node = cppgc::MakeGarbageCollected<CXFA_IncrementalLoad>(
6242           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6243       break;
6244     case XFA_Element::SubjectDN:
6245       node = cppgc::MakeGarbageCollected<CXFA_SubjectDN>(
6246           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6247       break;
6248     case XFA_Element::CompressLogicalStructure:
6249       node = cppgc::MakeGarbageCollected<CXFA_CompressLogicalStructure>(
6250           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6251       break;
6252     case XFA_Element::IncrementalMerge:
6253       node = cppgc::MakeGarbageCollected<CXFA_IncrementalMerge>(
6254           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6255       break;
6256     case XFA_Element::Radial:
6257       node = cppgc::MakeGarbageCollected<CXFA_Radial>(
6258           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6259       break;
6260     case XFA_Element::Variables:
6261       node = cppgc::MakeGarbageCollected<CXFA_Variables>(
6262           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6263       break;
6264     case XFA_Element::TimePatterns:
6265       node = cppgc::MakeGarbageCollected<CXFA_TimePatterns>(
6266           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6267       break;
6268     case XFA_Element::EffectiveInputPolicy:
6269       node = cppgc::MakeGarbageCollected<CXFA_EffectiveInputPolicy>(
6270           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6271       break;
6272     case XFA_Element::NameAttr:
6273       node = cppgc::MakeGarbageCollected<CXFA_NameAttr>(
6274           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6275       break;
6276     case XFA_Element::Conformance:
6277       node = cppgc::MakeGarbageCollected<CXFA_Conformance>(
6278           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6279       break;
6280     case XFA_Element::Transform:
6281       node = cppgc::MakeGarbageCollected<CXFA_Transform>(
6282           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6283       break;
6284     case XFA_Element::LockDocument:
6285       node = cppgc::MakeGarbageCollected<CXFA_LockDocument>(
6286           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6287       break;
6288     case XFA_Element::BreakAfter:
6289       node = cppgc::MakeGarbageCollected<CXFA_BreakAfter>(
6290           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6291       break;
6292     case XFA_Element::Line:
6293       node = cppgc::MakeGarbageCollected<CXFA_Line>(
6294           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6295       break;
6296     case XFA_Element::Source:
6297       node = cppgc::MakeGarbageCollected<CXFA_Source>(
6298           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6299       break;
6300     case XFA_Element::Occur:
6301       node = cppgc::MakeGarbageCollected<CXFA_Occur>(
6302           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6303       break;
6304     case XFA_Element::PickTrayByPDFSize:
6305       node = cppgc::MakeGarbageCollected<CXFA_PickTrayByPDFSize>(
6306           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6307       break;
6308     case XFA_Element::MonthNames:
6309       node = cppgc::MakeGarbageCollected<CXFA_MonthNames>(
6310           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6311       break;
6312     case XFA_Element::Severity:
6313       node = cppgc::MakeGarbageCollected<CXFA_Severity>(
6314           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6315       break;
6316     case XFA_Element::GroupParent:
6317       node = cppgc::MakeGarbageCollected<CXFA_GroupParent>(
6318           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6319       break;
6320     case XFA_Element::DocumentAssembly:
6321       node = cppgc::MakeGarbageCollected<CXFA_DocumentAssembly>(
6322           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6323       break;
6324     case XFA_Element::NumberSymbol:
6325       node = cppgc::MakeGarbageCollected<CXFA_NumberSymbol>(
6326           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6327       break;
6328     case XFA_Element::Tagged:
6329       node = cppgc::MakeGarbageCollected<CXFA_Tagged>(
6330           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6331       break;
6332     case XFA_Element::Items:
6333       node = cppgc::MakeGarbageCollected<CXFA_Items>(
6334           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6335       break;
6336     default:
6337       NOTREACHED();
6338       return nullptr;
6339   }
6340   if (!node || !node->IsValidInPacket(packet))
6341     return nullptr;
6342   return node;
6343 }
6344