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