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