• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "xfa/fxfa/parser/cxfa_node.h"
8 
9 #include <math.h>
10 #include <stdint.h>
11 
12 #include <algorithm>
13 #include <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/notreached.h"
40 #include "third_party/base/span.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();
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();
2937   return XFA_FFWidgetType::kNone;
2938 }
2939 
CreateUINodeIfNeeded(CXFA_Ui * ui,XFA_Element type)2940 CXFA_Node* CXFA_Node::CreateUINodeIfNeeded(CXFA_Ui* ui, XFA_Element type) {
2941   return ui->JSObject()->GetOrCreateProperty<CXFA_Node>(0, type);
2942 }
2943 
CreateValueNodeIfNeeded(CXFA_Value * value,CXFA_Node * pUIChild)2944 void CXFA_Node::CreateValueNodeIfNeeded(CXFA_Value* value,
2945                                         CXFA_Node* pUIChild) {
2946   // Value nodes only have one child. If we have one already we're done.
2947   if (value->GetFirstChild())
2948     return;
2949 
2950   // Create the Value node for our UI if needed.
2951   XFA_Element valueType = pUIChild->GetValueNodeType();
2952   if (pUIChild->GetElementType() == XFA_Element::CheckButton) {
2953     CXFA_Items* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
2954     if (pItems) {
2955       CXFA_Node* pItem =
2956           pItems->GetChild<CXFA_Node>(0, XFA_Element::Unknown, false);
2957       if (pItem)
2958         valueType = pItem->GetElementType();
2959     }
2960   }
2961   value->JSObject()->GetOrCreateProperty<CXFA_Node>(0, valueType);
2962 }
2963 
GetValueNodeType() const2964 XFA_Element CXFA_Node::GetValueNodeType() const {
2965   return XFA_Element::Text;
2966 }
2967 
GetUIChildNode()2968 CXFA_Node* CXFA_Node::GetUIChildNode() {
2969   DCHECK(HasCreatedUIWidget());
2970 
2971   if (ff_widget_type_ != XFA_FFWidgetType::kNone)
2972     return ui_ ? ui_->GetFirstChild() : nullptr;
2973 
2974   XFA_Element type = GetElementType();
2975   if (type == XFA_Element::Field || type == XFA_Element::Draw) {
2976     std::tie(ff_widget_type_, ui_) = CreateChildUIAndValueNodesIfNeeded();
2977   } else if (type == XFA_Element::Subform) {
2978     ff_widget_type_ = XFA_FFWidgetType::kSubform;
2979   } else if (type == XFA_Element::ExclGroup) {
2980     ff_widget_type_ = XFA_FFWidgetType::kExclGroup;
2981   } else {
2982     NOTREACHED();
2983   }
2984   return ui_ ? ui_->GetFirstChild() : nullptr;
2985 }
2986 
GetFFWidgetType()2987 XFA_FFWidgetType CXFA_Node::GetFFWidgetType() {
2988   GetUIChildNode();
2989   return ff_widget_type_;
2990 }
2991 
GetUIBorder()2992 CXFA_Border* CXFA_Node::GetUIBorder() {
2993   CXFA_Node* pUIChild = GetUIChildNode();
2994   return pUIChild ? pUIChild->JSObject()->GetProperty<CXFA_Border>(
2995                         0, XFA_Element::Border)
2996                   : nullptr;
2997 }
2998 
GetUIMargin()2999 CFX_RectF CXFA_Node::GetUIMargin() {
3000   CXFA_Node* pUIChild = GetUIChildNode();
3001   if (!pUIChild)
3002     return CFX_RectF();
3003 
3004   CXFA_Margin* mgUI =
3005       pUIChild->JSObject()->GetProperty<CXFA_Margin>(0, XFA_Element::Margin);
3006   if (!mgUI)
3007     return CFX_RectF();
3008 
3009   CXFA_Border* border = GetUIBorder();
3010   if (border && border->GetPresence() != XFA_AttributeValue::Visible)
3011     return CFX_RectF();
3012 
3013   absl::optional<float> left = mgUI->TryLeftInset();
3014   absl::optional<float> top = mgUI->TryTopInset();
3015   absl::optional<float> right = mgUI->TryRightInset();
3016   absl::optional<float> bottom = mgUI->TryBottomInset();
3017   if (border) {
3018     bool bVisible = false;
3019     float fThickness = 0;
3020     XFA_AttributeValue iType = XFA_AttributeValue::Unknown;
3021     std::tie(iType, bVisible, fThickness) = border->Get3DStyle();
3022     if (!left.has_value() || !top.has_value() || !right.has_value() ||
3023         !bottom.has_value()) {
3024       std::vector<CXFA_Stroke*> strokes = border->GetStrokes();
3025       if (!top.has_value())
3026         top = GetEdgeThickness(strokes, bVisible, 0);
3027       if (!right.has_value())
3028         right = GetEdgeThickness(strokes, bVisible, 1);
3029       if (!bottom.has_value())
3030         bottom = GetEdgeThickness(strokes, bVisible, 2);
3031       if (!left.has_value())
3032         left = GetEdgeThickness(strokes, bVisible, 3);
3033     }
3034   }
3035   return CFX_RectF(left.value_or(0.0), top.value_or(0.0), right.value_or(0.0),
3036                    bottom.value_or(0.0));
3037 }
3038 
GetEventByActivity(XFA_AttributeValue iActivity,bool bIsFormReady)3039 std::vector<CXFA_Event*> CXFA_Node::GetEventByActivity(
3040     XFA_AttributeValue iActivity,
3041     bool bIsFormReady) {
3042   std::vector<CXFA_Event*> events;
3043   for (CXFA_Node* node : GetNodeListForType(XFA_Element::Event)) {
3044     auto* event = static_cast<CXFA_Event*>(node);
3045     if (event->GetActivity() != iActivity)
3046       continue;
3047 
3048     if (iActivity != XFA_AttributeValue::Ready) {
3049       events.push_back(event);
3050       continue;
3051     }
3052 
3053     WideString wsRef = event->GetRef();
3054     if (bIsFormReady) {
3055       if (wsRef == WideStringView(L"$form"))
3056         events.push_back(event);
3057       continue;
3058     }
3059 
3060     if (wsRef == WideStringView(L"$layout"))
3061       events.push_back(event);
3062   }
3063   return events;
3064 }
3065 
ResetData()3066 void CXFA_Node::ResetData() {
3067   WideString wsValue;
3068   switch (GetFFWidgetType()) {
3069     case XFA_FFWidgetType::kImageEdit: {
3070       CXFA_Value* imageValue = GetDefaultValueIfExists();
3071       CXFA_Image* image = imageValue ? imageValue->GetImageIfExists() : nullptr;
3072       WideString wsContentType, wsHref;
3073       if (image) {
3074         wsValue = image->GetContent();
3075         wsContentType = image->GetContentType();
3076         wsHref = image->GetHref();
3077       }
3078       SetImageEdit(wsContentType, wsHref, wsValue);
3079       break;
3080     }
3081     case XFA_FFWidgetType::kExclGroup: {
3082       CXFA_Node* pNextChild = GetFirstContainerChild();
3083       while (pNextChild) {
3084         CXFA_Node* pChild = pNextChild;
3085         if (!pChild->IsWidgetReady())
3086           continue;
3087 
3088         bool done = false;
3089         if (wsValue.IsEmpty()) {
3090           CXFA_Value* defValue = pChild->GetDefaultValueIfExists();
3091           if (defValue) {
3092             wsValue = defValue->GetChildValueContent();
3093             SetValue(XFA_ValuePicture::kRaw, wsValue);
3094             pChild->SetValue(XFA_ValuePicture::kRaw, wsValue);
3095             done = true;
3096           }
3097         }
3098         if (!done) {
3099           CXFA_Items* pItems =
3100               pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3101           if (!pItems)
3102             continue;
3103 
3104           WideString itemText;
3105           if (pItems->CountChildren(XFA_Element::Unknown, false) > 1) {
3106             itemText =
3107                 pItems->GetChild<CXFA_Node>(1, XFA_Element::Unknown, false)
3108                     ->JSObject()
3109                     ->GetContent(false);
3110           }
3111           pChild->SetValue(XFA_ValuePicture::kRaw, itemText);
3112         }
3113         pNextChild = pChild->GetNextContainerSibling();
3114       }
3115       break;
3116     }
3117     case XFA_FFWidgetType::kChoiceList:
3118       ClearAllSelections();
3119       [[fallthrough]];
3120     default: {
3121       CXFA_Value* defValue = GetDefaultValueIfExists();
3122       if (defValue)
3123         wsValue = defValue->GetChildValueContent();
3124 
3125       SetValue(XFA_ValuePicture::kRaw, wsValue);
3126       break;
3127     }
3128   }
3129 }
3130 
SetImageEdit(const WideString & wsContentType,const WideString & wsHref,const WideString & wsData)3131 void CXFA_Node::SetImageEdit(const WideString& wsContentType,
3132                              const WideString& wsHref,
3133                              const WideString& wsData) {
3134   CXFA_Value* formValue = GetFormValueIfExists();
3135   CXFA_Image* image = formValue ? formValue->GetImageIfExists() : nullptr;
3136   if (image) {
3137     image->SetContentType(WideString(wsContentType));
3138     image->SetHref(wsHref);
3139   }
3140 
3141   JSObject()->SetContent(wsData, GetFormatDataValue(wsData), true, false, true);
3142 
3143   CXFA_Node* pBind = GetBindData();
3144   if (!pBind) {
3145     if (image)
3146       image->SetTransferEncoding(XFA_AttributeValue::Base64);
3147     return;
3148   }
3149   pBind->JSObject()->SetCData(XFA_Attribute::ContentType, wsContentType);
3150   CXFA_Node* pHrefNode = pBind->GetFirstChild();
3151   if (pHrefNode) {
3152     pHrefNode->JSObject()->SetCData(XFA_Attribute::Value, wsHref);
3153     return;
3154   }
3155   CFX_XMLElement* pElement = ToXMLElement(pBind->GetXMLMappingNode());
3156   pElement->SetAttribute(L"href", wsHref);
3157 }
3158 
CalcCaptionSize(CXFA_FFDoc * doc,CFX_SizeF * pszCap)3159 void CXFA_Node::CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF* pszCap) {
3160   CXFA_Caption* caption = GetCaptionIfExists();
3161   if (!caption || !caption->IsVisible())
3162     return;
3163 
3164   LoadCaption(doc);
3165 
3166   const float fCapReserve = caption->GetReserve();
3167   const XFA_AttributeValue iCapPlacement = caption->GetPlacementType();
3168   const bool bReserveExit = fCapReserve > 0.01;
3169   const bool bVert = iCapPlacement == XFA_AttributeValue::Top ||
3170                      iCapPlacement == XFA_AttributeValue::Bottom;
3171   CXFA_TextLayout* pCapTextLayout =
3172       m_pLayoutData->AsFieldLayoutData()->m_pCapTextLayout;
3173   if (pCapTextLayout) {
3174     if (!bVert && GetFFWidgetType() != XFA_FFWidgetType::kButton)
3175       pszCap->width = fCapReserve;
3176 
3177     CFX_SizeF minSize;
3178     *pszCap = pCapTextLayout->CalcSize(minSize, *pszCap);
3179     if (bReserveExit)
3180       bVert ? pszCap->height = fCapReserve : pszCap->width = fCapReserve;
3181   } else {
3182     float fFontSize = 10.0f;
3183     CXFA_Font* font = caption->GetFontIfExists();
3184     if (font) {
3185       fFontSize = font->GetFontSize();
3186     } else {
3187       CXFA_Font* widgetfont = GetFontIfExists();
3188       if (widgetfont)
3189         fFontSize = widgetfont->GetFontSize();
3190     }
3191 
3192     if (bVert) {
3193       pszCap->height = fCapReserve > 0 ? fCapReserve : fFontSize;
3194     } else {
3195       pszCap->width = fCapReserve > 0 ? fCapReserve : 0;
3196       pszCap->height = fFontSize;
3197     }
3198   }
3199 
3200   CXFA_Margin* captionMargin = caption->GetMarginIfExists();
3201   if (!captionMargin)
3202     return;
3203 
3204   float fLeftInset = captionMargin->GetLeftInset();
3205   float fTopInset = captionMargin->GetTopInset();
3206   float fRightInset = captionMargin->GetRightInset();
3207   float fBottomInset = captionMargin->GetBottomInset();
3208   if (bReserveExit) {
3209     bVert ? (pszCap->width += fLeftInset + fRightInset)
3210           : (pszCap->height += fTopInset + fBottomInset);
3211   } else {
3212     pszCap->width += fLeftInset + fRightInset;
3213     pszCap->height += fTopInset + fBottomInset;
3214   }
3215 }
3216 
CalculateFieldAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3217 bool CXFA_Node::CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3218   CFX_SizeF szCap;
3219   CalcCaptionSize(doc, &szCap);
3220 
3221   CFX_RectF rtUIMargin = GetUIMargin();
3222   pSize->width += rtUIMargin.left + rtUIMargin.width;
3223   pSize->height += rtUIMargin.top + rtUIMargin.height;
3224   if (szCap.width > 0 && szCap.height > 0) {
3225     CXFA_Caption* caption = GetCaptionIfExists();
3226     XFA_AttributeValue placement = caption
3227                                        ? caption->GetPlacementType()
3228                                        : CXFA_Caption::kDefaultPlacementType;
3229     switch (placement) {
3230       case XFA_AttributeValue::Left:
3231       case XFA_AttributeValue::Right:
3232       case XFA_AttributeValue::Inline: {
3233         pSize->width += szCap.width;
3234         pSize->height = std::max(pSize->height, szCap.height);
3235       } break;
3236       case XFA_AttributeValue::Top:
3237       case XFA_AttributeValue::Bottom: {
3238         pSize->height += szCap.height;
3239         pSize->width = std::max(pSize->width, szCap.width);
3240         break;
3241       }
3242       default:
3243         break;
3244     }
3245   }
3246   return CalculateWidgetAutoSize(pSize);
3247 }
3248 
CalculateWidgetAutoSize(CFX_SizeF * pSize)3249 bool CXFA_Node::CalculateWidgetAutoSize(CFX_SizeF* pSize) {
3250   CXFA_Margin* margin = GetMarginIfExists();
3251   if (margin) {
3252     pSize->width += margin->GetLeftInset() + margin->GetRightInset();
3253     pSize->height += margin->GetTopInset() + margin->GetBottomInset();
3254   }
3255 
3256   CXFA_Para* para = GetParaIfExists();
3257   if (para)
3258     pSize->width += para->GetMarginLeft() + para->GetTextIndent();
3259 
3260   absl::optional<float> width = TryWidth();
3261   if (width.has_value()) {
3262     pSize->width = width.value();
3263   } else {
3264     absl::optional<float> min = TryMinWidth();
3265     if (min.has_value())
3266       pSize->width = std::max(pSize->width, min.value());
3267 
3268     absl::optional<float> max = TryMaxWidth();
3269     if (max.has_value() && max.value() > 0)
3270       pSize->width = std::min(pSize->width, max.value());
3271   }
3272 
3273   absl::optional<float> height = TryHeight();
3274   if (height.has_value()) {
3275     pSize->height = height.value();
3276   } else {
3277     absl::optional<float> min = TryMinHeight();
3278     if (min.has_value())
3279       pSize->height = std::max(pSize->height, min.value());
3280 
3281     absl::optional<float> max = TryMaxHeight();
3282     if (max.has_value() && max.value() > 0)
3283       pSize->height = std::min(pSize->height, max.value());
3284   }
3285   return true;
3286 }
3287 
CalculateTextContentSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3288 void CXFA_Node::CalculateTextContentSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3289   float fFontSize = GetFontSize();
3290   WideString wsText = GetValue(XFA_ValuePicture::kDisplay);
3291   if (wsText.IsEmpty()) {
3292     pSize->height += fFontSize;
3293     return;
3294   }
3295 
3296   if (wsText.Back() == L'\n')
3297     wsText += L'\n';
3298 
3299   CXFA_FieldLayoutData* layoutData = m_pLayoutData->AsFieldLayoutData();
3300   if (!layoutData->m_pTextOut) {
3301     layoutData->m_pTextOut = std::make_unique<CFDE_TextOut>();
3302     CFDE_TextOut* pTextOut = layoutData->m_pTextOut.get();
3303     pTextOut->SetFont(GetFGASFont(doc));
3304     pTextOut->SetFontSize(fFontSize);
3305     pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
3306     pTextOut->SetLineSpace(GetLineHeight());
3307 
3308     FDE_TextStyle dwStyles;
3309     dwStyles.last_line_height_ = true;
3310     if (GetFFWidgetType() == XFA_FFWidgetType::kTextEdit && IsMultiLine())
3311       dwStyles.line_wrap_ = true;
3312 
3313     pTextOut->SetStyles(dwStyles);
3314   }
3315   layoutData->m_pTextOut->CalcLogicSize(wsText.AsStringView(), pSize);
3316 }
3317 
CalculateTextEditAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3318 bool CXFA_Node::CalculateTextEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3319   if (pSize->width > 0) {
3320     CFX_SizeF szOrz = *pSize;
3321     CFX_SizeF szCap;
3322     CalcCaptionSize(doc, &szCap);
3323     bool bCapExit = szCap.width > 0.01 && szCap.height > 0.01;
3324     XFA_AttributeValue iCapPlacement = XFA_AttributeValue::Unknown;
3325     if (bCapExit) {
3326       CXFA_Caption* caption = GetCaptionIfExists();
3327       iCapPlacement = caption ? caption->GetPlacementType()
3328                               : CXFA_Caption::kDefaultPlacementType;
3329       switch (iCapPlacement) {
3330         case XFA_AttributeValue::Left:
3331         case XFA_AttributeValue::Right:
3332         case XFA_AttributeValue::Inline: {
3333           pSize->width -= szCap.width;
3334           break;
3335         }
3336         default:
3337           break;
3338       }
3339     }
3340     CFX_RectF rtUIMargin = GetUIMargin();
3341     pSize->width -= rtUIMargin.left + rtUIMargin.width;
3342     CXFA_Margin* margin = GetMarginIfExists();
3343     if (margin)
3344       pSize->width -= margin->GetLeftInset() + margin->GetRightInset();
3345 
3346     CalculateTextContentSize(doc, pSize);
3347     pSize->height += rtUIMargin.top + rtUIMargin.height;
3348     if (bCapExit) {
3349       switch (iCapPlacement) {
3350         case XFA_AttributeValue::Left:
3351         case XFA_AttributeValue::Right:
3352         case XFA_AttributeValue::Inline: {
3353           pSize->height = std::max(pSize->height, szCap.height);
3354         } break;
3355         case XFA_AttributeValue::Top:
3356         case XFA_AttributeValue::Bottom: {
3357           pSize->height += szCap.height;
3358           break;
3359         }
3360         default:
3361           break;
3362       }
3363     }
3364     pSize->width = szOrz.width;
3365     return CalculateWidgetAutoSize(pSize);
3366   }
3367   CalculateTextContentSize(doc, pSize);
3368   return CalculateFieldAutoSize(doc, pSize);
3369 }
3370 
CalculateCheckButtonAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3371 bool CXFA_Node::CalculateCheckButtonAutoSize(CXFA_FFDoc* doc,
3372                                              CFX_SizeF* pSize) {
3373   float fCheckSize = GetCheckButtonSize();
3374   *pSize = CFX_SizeF(fCheckSize, fCheckSize);
3375   return CalculateFieldAutoSize(doc, pSize);
3376 }
3377 
CalculatePushButtonAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3378 bool CXFA_Node::CalculatePushButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3379   CalcCaptionSize(doc, pSize);
3380   return CalculateWidgetAutoSize(pSize);
3381 }
3382 
CalculateImageSize(float img_width,float img_height,const CFX_Size & dpi)3383 CFX_SizeF CXFA_Node::CalculateImageSize(float img_width,
3384                                         float img_height,
3385                                         const CFX_Size& dpi) {
3386   CFX_RectF rtImage(0, 0, XFA_UnitPx2Pt(img_width, dpi.width),
3387                     XFA_UnitPx2Pt(img_height, dpi.height));
3388 
3389   CFX_RectF rtFit;
3390   absl::optional<float> width = TryWidth();
3391   if (width.has_value()) {
3392     rtFit.width = width.value();
3393     GetWidthWithoutMargin(rtFit.width);
3394   } else {
3395     rtFit.width = rtImage.width;
3396   }
3397 
3398   absl::optional<float> height = TryHeight();
3399   if (height.has_value()) {
3400     rtFit.height = height.value();
3401     GetHeightWithoutMargin(rtFit.height);
3402   } else {
3403     rtFit.height = rtImage.height;
3404   }
3405 
3406   return rtFit.Size();
3407 }
3408 
CalculateImageAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3409 bool CXFA_Node::CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3410   if (!GetLayoutImage())
3411     LoadLayoutImage(doc);
3412 
3413   pSize->clear();
3414   RetainPtr<CFX_DIBitmap> pBitmap = GetLayoutImage();
3415   if (!pBitmap)
3416     return CalculateWidgetAutoSize(pSize);
3417 
3418   *pSize = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
3419                               GetLayoutImageDpi());
3420   return CalculateWidgetAutoSize(pSize);
3421 }
3422 
CalculateImageEditAutoSize(CXFA_FFDoc * doc,CFX_SizeF * pSize)3423 bool CXFA_Node::CalculateImageEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize) {
3424   if (!GetEditImage())
3425     LoadEditImage(doc);
3426 
3427   pSize->clear();
3428   RetainPtr<CFX_DIBitmap> pBitmap = GetEditImage();
3429   if (!pBitmap)
3430     return CalculateFieldAutoSize(doc, pSize);
3431 
3432   *pSize = CalculateImageSize(pBitmap->GetWidth(), pBitmap->GetHeight(),
3433                               GetEditImageDpi());
3434   return CalculateFieldAutoSize(doc, pSize);
3435 }
3436 
LoadLayoutImage(CXFA_FFDoc * doc)3437 bool CXFA_Node::LoadLayoutImage(CXFA_FFDoc* doc) {
3438   InitLayoutData(doc);
3439   return m_pLayoutData->AsImageLayoutData()->LoadImageData(doc, this);
3440 }
3441 
LoadEditImage(CXFA_FFDoc * doc)3442 bool CXFA_Node::LoadEditImage(CXFA_FFDoc* doc) {
3443   InitLayoutData(doc);
3444   return m_pLayoutData->AsFieldLayoutData()->AsImageEditData()->LoadImageData(
3445       doc, this);
3446 }
3447 
GetLayoutImageDpi() const3448 CFX_Size CXFA_Node::GetLayoutImageDpi() const {
3449   return m_pLayoutData->AsImageLayoutData()->GetDpi();
3450 }
3451 
GetEditImageDpi() const3452 CFX_Size CXFA_Node::GetEditImageDpi() const {
3453   CXFA_ImageEditData* pData =
3454       m_pLayoutData->AsFieldLayoutData()->AsImageEditData();
3455   return pData->GetDpi();
3456 }
3457 
CalculateWidgetAutoWidth(float fWidthCalc)3458 float CXFA_Node::CalculateWidgetAutoWidth(float fWidthCalc) {
3459   CXFA_Margin* margin = GetMarginIfExists();
3460   if (margin)
3461     fWidthCalc += margin->GetLeftInset() + margin->GetRightInset();
3462 
3463   absl::optional<float> min = TryMinWidth();
3464   if (min.has_value())
3465     fWidthCalc = std::max(fWidthCalc, min.value());
3466 
3467   absl::optional<float> max = TryMaxWidth();
3468   if (max.has_value() && max.value() > 0)
3469     fWidthCalc = std::min(fWidthCalc, max.value());
3470 
3471   return fWidthCalc;
3472 }
3473 
GetWidthWithoutMargin(float fWidthCalc) const3474 float CXFA_Node::GetWidthWithoutMargin(float fWidthCalc) const {
3475   CXFA_Margin* margin = GetMarginIfExists();
3476   if (margin)
3477     fWidthCalc -= margin->GetLeftInset() + margin->GetRightInset();
3478   return fWidthCalc;
3479 }
3480 
CalculateWidgetAutoHeight(float fHeightCalc)3481 float CXFA_Node::CalculateWidgetAutoHeight(float fHeightCalc) {
3482   CXFA_Margin* margin = GetMarginIfExists();
3483   if (margin)
3484     fHeightCalc += margin->GetTopInset() + margin->GetBottomInset();
3485 
3486   absl::optional<float> min = TryMinHeight();
3487   if (min.has_value())
3488     fHeightCalc = std::max(fHeightCalc, min.value());
3489 
3490   absl::optional<float> max = TryMaxHeight();
3491   if (max.has_value() && max.value() > 0)
3492     fHeightCalc = std::min(fHeightCalc, max.value());
3493 
3494   return fHeightCalc;
3495 }
3496 
GetHeightWithoutMargin(float fHeightCalc) const3497 float CXFA_Node::GetHeightWithoutMargin(float fHeightCalc) const {
3498   CXFA_Margin* margin = GetMarginIfExists();
3499   if (margin)
3500     fHeightCalc -= margin->GetTopInset() + margin->GetBottomInset();
3501   return fHeightCalc;
3502 }
3503 
StartWidgetLayout(CXFA_FFDoc * doc,float * pCalcWidth,float * pCalcHeight)3504 void CXFA_Node::StartWidgetLayout(CXFA_FFDoc* doc,
3505                                   float* pCalcWidth,
3506                                   float* pCalcHeight) {
3507   InitLayoutData(doc);
3508 
3509   if (GetFFWidgetType() == XFA_FFWidgetType::kText) {
3510     m_pLayoutData->SetWidgetHeight(TryHeight().value_or(-1));
3511     StartTextLayout(doc, pCalcWidth, pCalcHeight);
3512     return;
3513   }
3514   if (*pCalcWidth > 0 && *pCalcHeight > 0)
3515     return;
3516 
3517   m_pLayoutData->SetWidgetHeight(-1.0f);
3518   float fWidth = 0;
3519   if (*pCalcWidth > 0 && *pCalcHeight < 0) {
3520     absl::optional<float> height = TryHeight();
3521     if (height.has_value()) {
3522       *pCalcHeight = height.value();
3523     } else {
3524       CFX_SizeF size = CalculateAccWidthAndHeight(doc, *pCalcWidth);
3525       *pCalcWidth = size.width;
3526       *pCalcHeight = size.height;
3527     }
3528     m_pLayoutData->SetWidgetHeight(*pCalcHeight);
3529     return;
3530   }
3531   if (*pCalcWidth < 0 && *pCalcHeight < 0) {
3532     absl::optional<float> height;
3533     absl::optional<float> width = TryWidth();
3534     if (width.has_value()) {
3535       fWidth = width.value();
3536       height = TryHeight();
3537       if (height.has_value())
3538         *pCalcHeight = height.value();
3539     }
3540     if (!width.has_value() || !height.has_value()) {
3541       CFX_SizeF size = CalculateAccWidthAndHeight(doc, fWidth);
3542       *pCalcWidth = size.width;
3543       *pCalcHeight = size.height;
3544     } else {
3545       *pCalcWidth = fWidth;
3546     }
3547   }
3548   m_pLayoutData->SetWidgetHeight(*pCalcHeight);
3549 }
3550 
CalculateAccWidthAndHeight(CXFA_FFDoc * doc,float fWidth)3551 CFX_SizeF CXFA_Node::CalculateAccWidthAndHeight(CXFA_FFDoc* doc, float fWidth) {
3552   CFX_SizeF sz(fWidth, m_pLayoutData->GetWidgetHeight());
3553   switch (GetFFWidgetType()) {
3554     case XFA_FFWidgetType::kBarcode:
3555     case XFA_FFWidgetType::kChoiceList:
3556     case XFA_FFWidgetType::kSignature:
3557       CalculateFieldAutoSize(doc, &sz);
3558       break;
3559     case XFA_FFWidgetType::kImageEdit:
3560       CalculateImageEditAutoSize(doc, &sz);
3561       break;
3562     case XFA_FFWidgetType::kButton:
3563       CalculatePushButtonAutoSize(doc, &sz);
3564       break;
3565     case XFA_FFWidgetType::kCheckButton:
3566       CalculateCheckButtonAutoSize(doc, &sz);
3567       break;
3568     case XFA_FFWidgetType::kDateTimeEdit:
3569     case XFA_FFWidgetType::kNumericEdit:
3570     case XFA_FFWidgetType::kPasswordEdit:
3571     case XFA_FFWidgetType::kTextEdit:
3572       CalculateTextEditAutoSize(doc, &sz);
3573       break;
3574     case XFA_FFWidgetType::kImage:
3575       CalculateImageAutoSize(doc, &sz);
3576       break;
3577     case XFA_FFWidgetType::kArc:
3578     case XFA_FFWidgetType::kLine:
3579     case XFA_FFWidgetType::kRectangle:
3580     case XFA_FFWidgetType::kSubform:
3581     case XFA_FFWidgetType::kExclGroup:
3582       CalculateWidgetAutoSize(&sz);
3583       break;
3584     case XFA_FFWidgetType::kText:
3585     case XFA_FFWidgetType::kNone:
3586       break;
3587   }
3588   m_pLayoutData->SetWidgetHeight(sz.height);
3589   return sz;
3590 }
3591 
FindSplitPos(CXFA_FFDocView * pDocView,size_t szBlockIndex,float fCalcHeight)3592 absl::optional<float> CXFA_Node::FindSplitPos(CXFA_FFDocView* pDocView,
3593                                               size_t szBlockIndex,
3594                                               float fCalcHeight) {
3595   if (!HasCreatedUIWidget())
3596     return absl::nullopt;
3597 
3598   if (GetFFWidgetType() == XFA_FFWidgetType::kSubform)
3599     return absl::nullopt;
3600 
3601   switch (GetFFWidgetType()) {
3602     case XFA_FFWidgetType::kText:
3603     case XFA_FFWidgetType::kTextEdit:
3604     case XFA_FFWidgetType::kNumericEdit:
3605     case XFA_FFWidgetType::kPasswordEdit:
3606       break;
3607     default:
3608       return 0.0f;
3609   }
3610 
3611   float fTopInset = 0;
3612   float fBottomInset = 0;
3613   if (szBlockIndex == 0) {
3614     CXFA_Margin* margin = GetMarginIfExists();
3615     if (margin) {
3616       fTopInset = margin->GetTopInset();
3617       fBottomInset = margin->GetBottomInset();
3618     }
3619 
3620     CFX_RectF rtUIMargin = GetUIMargin();
3621     fTopInset += rtUIMargin.top;
3622     fBottomInset += rtUIMargin.width;
3623   }
3624   if (GetFFWidgetType() == XFA_FFWidgetType::kText) {
3625     float fHeight = fCalcHeight;
3626     if (szBlockIndex == 0) {
3627       fCalcHeight -= fTopInset;
3628       fCalcHeight = std::max(fCalcHeight, 0.0f);
3629     }
3630     CXFA_TextLayout* pTextLayout =
3631         m_pLayoutData->AsTextLayoutData()->GetTextLayout();
3632     fCalcHeight = pTextLayout->DoSplitLayout(
3633         szBlockIndex, fCalcHeight,
3634         m_pLayoutData->GetWidgetHeight() - fTopInset);
3635     if (fCalcHeight != 0) {
3636       if (szBlockIndex == 0)
3637         fCalcHeight += fTopInset;
3638       if (fabs(fHeight - fCalcHeight) < kXFAWidgetPrecision)
3639         return absl::nullopt;
3640     }
3641     return fCalcHeight;
3642   }
3643 
3644   XFA_AttributeValue iCapPlacement = XFA_AttributeValue::Unknown;
3645   float fCapReserve = 0;
3646   if (szBlockIndex == 0) {
3647     CXFA_Caption* caption = GetCaptionIfExists();
3648     if (caption && !caption->IsHidden()) {
3649       iCapPlacement = caption->GetPlacementType();
3650       fCapReserve = caption->GetReserve();
3651     }
3652     if (iCapPlacement == XFA_AttributeValue::Top &&
3653         fCalcHeight < fCapReserve + fTopInset) {
3654       return 0.0f;
3655     }
3656     if (iCapPlacement == XFA_AttributeValue::Bottom &&
3657         m_pLayoutData->GetWidgetHeight() - fCapReserve - fBottomInset) {
3658       return 0.0f;
3659     }
3660     if (iCapPlacement != XFA_AttributeValue::Top)
3661       fCapReserve = 0;
3662   }
3663   CXFA_FieldLayoutData* pFieldData = m_pLayoutData->AsFieldLayoutData();
3664   int32_t iLinesCount = 0;
3665   float fHeight = m_pLayoutData->GetWidgetHeight();
3666   if (GetValue(XFA_ValuePicture::kDisplay).IsEmpty()) {
3667     iLinesCount = 1;
3668   } else {
3669     if (!pFieldData->m_pTextOut) {
3670       CFX_SizeF size = CalculateAccWidthAndHeight(pDocView->GetDoc(),
3671                                                   TryWidth().value_or(0));
3672       fHeight = size.height;
3673     }
3674 
3675     iLinesCount = pFieldData->m_pTextOut->GetTotalLines();
3676   }
3677   std::vector<float>* pFieldArray = &pFieldData->m_FieldSplitArray;
3678   size_t szFieldSplitCount = pFieldArray->size();
3679   if (szFieldSplitCount < szBlockIndex * 3)
3680     return absl::nullopt;
3681 
3682   for (size_t i = 0; i < szBlockIndex * 3; i += 3) {
3683     iLinesCount -= static_cast<int32_t>((*pFieldArray)[i + 1]);
3684     fHeight -= (*pFieldArray)[i + 2];
3685   }
3686   if (iLinesCount == 0)
3687     return absl::nullopt;
3688 
3689   float fLineHeight = GetLineHeight();
3690   float fFontSize = GetFontSize();
3691   float fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
3692   float fSpaceAbove = 0;
3693   float fStartOffset = 0;
3694   if (fHeight > 0.1f && szBlockIndex == 0) {
3695     fStartOffset = fTopInset;
3696     fHeight -= (fTopInset + fBottomInset);
3697     CXFA_Para* para = GetParaIfExists();
3698     if (para) {
3699       fSpaceAbove = para->GetSpaceAbove();
3700       float fSpaceBelow = para->GetSpaceBelow();
3701       fHeight -= (fSpaceAbove + fSpaceBelow);
3702       switch (para->GetVerticalAlign()) {
3703         case XFA_AttributeValue::Top:
3704           fStartOffset += fSpaceAbove;
3705           break;
3706         case XFA_AttributeValue::Middle:
3707           fStartOffset += ((fHeight - fTextHeight) / 2 + fSpaceAbove);
3708           break;
3709         case XFA_AttributeValue::Bottom:
3710           fStartOffset += (fHeight - fTextHeight + fSpaceAbove);
3711           break;
3712         default:
3713           NOTREACHED();
3714           break;
3715       }
3716     }
3717     if (fStartOffset < 0.1f)
3718       fStartOffset = 0;
3719   }
3720   if (szBlockIndex > 0) {
3721     size_t i = szBlockIndex - 1;
3722     fStartOffset = (*pFieldArray)[i * 3] - (*pFieldArray)[i * 3 + 2];
3723     if (fStartOffset < 0.1f)
3724       fStartOffset = 0;
3725   }
3726   if (szFieldSplitCount / 3 == (szBlockIndex + 1))
3727     (*pFieldArray)[0] = fStartOffset;
3728   else
3729     pFieldArray->push_back(fStartOffset);
3730 
3731   XFA_VERSION version = pDocView->GetDoc()->GetXFADoc()->GetCurVersionMode();
3732   bool bCanSplitNoContent = false;
3733   auto value = GetParent()->JSObject()->TryEnum(XFA_Attribute::Layout, true);
3734   XFA_AttributeValue eLayoutMode = value.value_or(XFA_AttributeValue::Position);
3735   if ((eLayoutMode == XFA_AttributeValue::Position ||
3736        eLayoutMode == XFA_AttributeValue::Tb ||
3737        eLayoutMode == XFA_AttributeValue::Row ||
3738        eLayoutMode == XFA_AttributeValue::Table) &&
3739       version > XFA_VERSION_208) {
3740     bCanSplitNoContent = true;
3741   }
3742   if ((eLayoutMode == XFA_AttributeValue::Tb ||
3743        eLayoutMode == XFA_AttributeValue::Row ||
3744        eLayoutMode == XFA_AttributeValue::Table) &&
3745       version <= XFA_VERSION_208) {
3746     if (fStartOffset >= fCalcHeight)
3747       return 0.0f;
3748 
3749     bCanSplitNoContent = true;
3750   }
3751   if (!bCanSplitNoContent ||
3752       fCalcHeight - fTopInset - fSpaceAbove < fLineHeight) {
3753     return 0.0f;
3754   }
3755 
3756   if (fStartOffset + kXFAWidgetPrecision >= fCalcHeight) {
3757     if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3758       (*pFieldArray)[szBlockIndex * 3 + 1] = 0;
3759       (*pFieldArray)[szBlockIndex * 3 + 2] = fCalcHeight;
3760     } else {
3761       pFieldArray->push_back(0);
3762       pFieldArray->push_back(fCalcHeight);
3763     }
3764     return absl::nullopt;
3765   }
3766 
3767   if (fCalcHeight - fStartOffset < fLineHeight) {
3768     fCalcHeight = fStartOffset;
3769     if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3770       (*pFieldArray)[szBlockIndex * 3 + 1] = 0;
3771       (*pFieldArray)[szBlockIndex * 3 + 2] = fCalcHeight;
3772     } else {
3773       pFieldArray->push_back(0);
3774       pFieldArray->push_back(fCalcHeight);
3775     }
3776     return fCalcHeight;
3777   }
3778 
3779   float fTextNum =
3780       fCalcHeight + kXFAWidgetPrecision - fCapReserve - fStartOffset;
3781   int32_t iLineNum = static_cast<int32_t>(
3782       (fTextNum + (fLineHeight - fFontSize)) / fLineHeight);
3783   if (iLineNum >= iLinesCount) {
3784     if (fCalcHeight - fStartOffset - fTextHeight >= fFontSize) {
3785       if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3786         (*pFieldArray)[szBlockIndex * 3 + 1] = iLinesCount;
3787         (*pFieldArray)[szBlockIndex * 3 + 2] = fCalcHeight;
3788       } else {
3789         pFieldArray->push_back(iLinesCount);
3790         pFieldArray->push_back(fCalcHeight);
3791       }
3792       return absl::nullopt;
3793     }
3794     if (fHeight - fStartOffset - fTextHeight < fFontSize) {
3795       iLineNum -= 1;
3796       if (iLineNum == 0)
3797         return 0.0f;
3798     } else {
3799       iLineNum = static_cast<int32_t>(fTextNum / fLineHeight);
3800     }
3801   }
3802   if (iLineNum <= 0)
3803     return 0.0f;
3804 
3805   float fSplitHeight = iLineNum * fLineHeight + fCapReserve + fStartOffset;
3806   if (szFieldSplitCount / 3 == (szBlockIndex + 1)) {
3807     (*pFieldArray)[szBlockIndex * 3 + 1] = iLineNum;
3808     (*pFieldArray)[szBlockIndex * 3 + 2] = fSplitHeight;
3809   } else {
3810     pFieldArray->push_back(iLineNum);
3811     pFieldArray->push_back(fSplitHeight);
3812   }
3813   if (fabs(fSplitHeight - fCalcHeight) < kXFAWidgetPrecision)
3814     return absl::nullopt;
3815   return fSplitHeight;
3816 }
3817 
InitLayoutData(CXFA_FFDoc * doc)3818 void CXFA_Node::InitLayoutData(CXFA_FFDoc* doc) {
3819   if (m_pLayoutData)
3820     return;
3821 
3822   switch (GetFFWidgetType()) {
3823     case XFA_FFWidgetType::kText:
3824       m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_TextLayoutData>(
3825           doc->GetHeap()->GetAllocationHandle());
3826       return;
3827     case XFA_FFWidgetType::kTextEdit:
3828       m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_TextEditData>(
3829           doc->GetHeap()->GetAllocationHandle());
3830       return;
3831     case XFA_FFWidgetType::kImage:
3832       m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_ImageLayoutData>(
3833           doc->GetHeap()->GetAllocationHandle());
3834       return;
3835     case XFA_FFWidgetType::kImageEdit:
3836       m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_ImageEditData>(
3837           doc->GetHeap()->GetAllocationHandle());
3838       return;
3839     default:
3840       break;
3841   }
3842   if (GetElementType() == XFA_Element::Field) {
3843     m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_FieldLayoutData>(
3844         doc->GetHeap()->GetAllocationHandle());
3845     return;
3846   }
3847   m_pLayoutData = cppgc::MakeGarbageCollected<CXFA_WidgetLayoutData>(
3848       doc->GetHeap()->GetAllocationHandle());
3849 }
3850 
StartTextLayout(CXFA_FFDoc * doc,float * pCalcWidth,float * pCalcHeight)3851 void CXFA_Node::StartTextLayout(CXFA_FFDoc* doc,
3852                                 float* pCalcWidth,
3853                                 float* pCalcHeight) {
3854   InitLayoutData(doc);
3855 
3856   CXFA_TextLayoutData* pTextLayoutData = m_pLayoutData->AsTextLayoutData();
3857   pTextLayoutData->LoadText(doc, this);
3858 
3859   CXFA_TextLayout* pTextLayout = pTextLayoutData->GetTextLayout();
3860   float fTextHeight = 0;
3861   if (*pCalcWidth > 0 && *pCalcHeight > 0) {
3862     float fWidth = GetWidthWithoutMargin(*pCalcWidth);
3863     pTextLayout->StartLayout(fWidth);
3864     fTextHeight = *pCalcHeight;
3865     fTextHeight = GetHeightWithoutMargin(fTextHeight);
3866     pTextLayout->DoLayout(fTextHeight);
3867     return;
3868   }
3869   if (*pCalcWidth > 0 && *pCalcHeight < 0) {
3870     float fWidth = GetWidthWithoutMargin(*pCalcWidth);
3871     pTextLayout->StartLayout(fWidth);
3872   }
3873   if (*pCalcWidth < 0 && *pCalcHeight < 0) {
3874     absl::optional<float> width = TryWidth();
3875     if (width.has_value()) {
3876       pTextLayout->StartLayout(GetWidthWithoutMargin(width.value()));
3877       *pCalcWidth = width.value();
3878     } else {
3879       float fMaxWidth = CalculateWidgetAutoWidth(pTextLayout->StartLayout(-1));
3880       pTextLayout->StartLayout(GetWidthWithoutMargin(fMaxWidth));
3881       *pCalcWidth = fMaxWidth;
3882     }
3883   }
3884   if (m_pLayoutData->GetWidgetHeight() < 0) {
3885     m_pLayoutData->SetWidgetHeight(
3886         CalculateWidgetAutoHeight(pTextLayout->GetLayoutHeight()));
3887   }
3888   fTextHeight = m_pLayoutData->GetWidgetHeight();
3889   fTextHeight = GetHeightWithoutMargin(fTextHeight);
3890   pTextLayout->DoLayout(fTextHeight);
3891   *pCalcHeight = m_pLayoutData->GetWidgetHeight();
3892 }
3893 
LoadCaption(CXFA_FFDoc * doc)3894 bool CXFA_Node::LoadCaption(CXFA_FFDoc* doc) {
3895   InitLayoutData(doc);
3896   return m_pLayoutData->AsFieldLayoutData()->LoadCaption(doc, this);
3897 }
3898 
GetCaptionTextLayout()3899 CXFA_TextLayout* CXFA_Node::GetCaptionTextLayout() {
3900   return m_pLayoutData ? m_pLayoutData->AsFieldLayoutData()->m_pCapTextLayout
3901                        : nullptr;
3902 }
3903 
GetTextLayout()3904 CXFA_TextLayout* CXFA_Node::GetTextLayout() {
3905   return m_pLayoutData ? m_pLayoutData->AsTextLayoutData()->GetTextLayout()
3906                        : nullptr;
3907 }
3908 
GetLayoutImage()3909 RetainPtr<CFX_DIBitmap> CXFA_Node::GetLayoutImage() {
3910   return m_pLayoutData ? m_pLayoutData->AsImageLayoutData()->GetBitmap()
3911                        : nullptr;
3912 }
3913 
GetEditImage()3914 RetainPtr<CFX_DIBitmap> CXFA_Node::GetEditImage() {
3915   return m_pLayoutData ? m_pLayoutData->AsFieldLayoutData()
3916                              ->AsImageEditData()
3917                              ->GetBitmap()
3918                        : nullptr;
3919 }
3920 
SetLayoutImage(RetainPtr<CFX_DIBitmap> newImage)3921 void CXFA_Node::SetLayoutImage(RetainPtr<CFX_DIBitmap> newImage) {
3922   CXFA_ImageLayoutData* pData = m_pLayoutData->AsImageLayoutData();
3923   if (pData->GetBitmap() != newImage)
3924     pData->SetBitmap(std::move(newImage));
3925 }
3926 
SetEditImage(RetainPtr<CFX_DIBitmap> newImage)3927 void CXFA_Node::SetEditImage(RetainPtr<CFX_DIBitmap> newImage) {
3928   CXFA_ImageEditData* pData =
3929       m_pLayoutData->AsFieldLayoutData()->AsImageEditData();
3930   if (pData->GetBitmap() != newImage)
3931     pData->SetBitmap(std::move(newImage));
3932 }
3933 
GetFGASFont(CXFA_FFDoc * doc)3934 RetainPtr<CFGAS_GEFont> CXFA_Node::GetFGASFont(CXFA_FFDoc* doc) {
3935   WideString wsFontName = L"Courier";
3936   uint32_t dwFontStyle = 0;
3937   CXFA_Font* font = GetFontIfExists();
3938   if (font) {
3939     if (font->IsBold())
3940       dwFontStyle |= FXFONT_FORCE_BOLD;
3941     if (font->IsItalic())
3942       dwFontStyle |= FXFONT_ITALIC;
3943 
3944     wsFontName = font->GetTypeface();
3945   }
3946   return doc->GetApp()->GetXFAFontMgr()->GetFont(doc, wsFontName, dwFontStyle);
3947 }
3948 
HasButtonRollover() const3949 bool CXFA_Node::HasButtonRollover() const {
3950   const auto* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3951   if (!pItems)
3952     return false;
3953 
3954   for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
3955        pText = pText->GetNextSibling()) {
3956     if (pText->JSObject()
3957             ->GetCData(XFA_Attribute::Name)
3958             .EqualsASCII("rollover")) {
3959       return !pText->JSObject()->GetContent(false).IsEmpty();
3960     }
3961   }
3962   return false;
3963 }
3964 
HasButtonDown() const3965 bool CXFA_Node::HasButtonDown() const {
3966   const auto* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3967   if (!pItems)
3968     return false;
3969 
3970   for (CXFA_Node* pText = pItems->GetFirstChild(); pText;
3971        pText = pText->GetNextSibling()) {
3972     if (pText->JSObject()->GetCData(XFA_Attribute::Name).EqualsASCII("down")) {
3973       return !pText->JSObject()->GetContent(false).IsEmpty();
3974     }
3975   }
3976   return false;
3977 }
3978 
IsRadioButton()3979 bool CXFA_Node::IsRadioButton() {
3980   CXFA_Node* pParent = GetParent();
3981   return pParent && pParent->GetElementType() == XFA_Element::ExclGroup;
3982 }
3983 
GetCheckButtonSize()3984 float CXFA_Node::GetCheckButtonSize() {
3985   CXFA_Node* pUIChild = GetUIChildNode();
3986   if (pUIChild) {
3987     return pUIChild->JSObject()->GetMeasureInUnit(XFA_Attribute::Size,
3988                                                   XFA_Unit::Pt);
3989   }
3990   return CXFA_Measurement(10, XFA_Unit::Pt).ToUnit(XFA_Unit::Pt);
3991 }
3992 
GetCheckState()3993 XFA_CheckState CXFA_Node::GetCheckState() {
3994   WideString wsValue = GetRawValue();
3995   if (wsValue.IsEmpty())
3996     return XFA_CheckState::kOff;
3997 
3998   auto* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
3999   if (!pItems)
4000     return XFA_CheckState::kOff;
4001 
4002   CXFA_Node* pText = pItems->GetFirstChild();
4003   int32_t i = 0;
4004   while (pText) {
4005     absl::optional<WideString> wsContent =
4006         pText->JSObject()->TryContent(false, true);
4007     if (wsContent == wsValue)
4008       return static_cast<XFA_CheckState>(i);
4009 
4010     i++;
4011     pText = pText->GetNextSibling();
4012   }
4013   return XFA_CheckState::kOff;
4014 }
4015 
SetCheckState(XFA_CheckState eCheckState)4016 void CXFA_Node::SetCheckState(XFA_CheckState eCheckState) {
4017   CXFA_Node* node = GetExclGroupIfExists();
4018   if (!node) {
4019     CXFA_Items* pItems = GetChild<CXFA_Items>(0, XFA_Element::Items, false);
4020     if (!pItems)
4021       return;
4022 
4023     int32_t i = -1;
4024     CXFA_Node* pText = pItems->GetFirstChild();
4025     WideString wsContent;
4026     while (pText) {
4027       i++;
4028       if (i == static_cast<int32_t>(eCheckState)) {
4029         wsContent = pText->JSObject()->GetContent(false);
4030         break;
4031       }
4032       pText = pText->GetNextSibling();
4033     }
4034     SyncValue(wsContent, true);
4035 
4036     return;
4037   }
4038 
4039   WideString wsValue;
4040   if (eCheckState != XFA_CheckState::kOff) {
4041     if (CXFA_Items* pItems =
4042             GetChild<CXFA_Items>(0, XFA_Element::Items, false)) {
4043       CXFA_Node* pText = pItems->GetFirstChild();
4044       if (pText)
4045         wsValue = pText->JSObject()->GetContent(false);
4046     }
4047   }
4048   CXFA_Node* pChild = node->GetFirstChild();
4049   for (; pChild; pChild = pChild->GetNextSibling()) {
4050     if (pChild->GetElementType() != XFA_Element::Field)
4051       continue;
4052 
4053     CXFA_Items* pItem =
4054         pChild->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
4055     if (!pItem)
4056       continue;
4057 
4058     CXFA_Node* pItemchild = pItem->GetFirstChild();
4059     if (!pItemchild)
4060       continue;
4061 
4062     WideString text = pItemchild->JSObject()->GetContent(false);
4063     WideString wsChildValue = text;
4064     if (wsValue != text) {
4065       pItemchild = pItemchild->GetNextSibling();
4066       if (pItemchild)
4067         wsChildValue = pItemchild->JSObject()->GetContent(false);
4068       else
4069         wsChildValue.clear();
4070     }
4071     pChild->SyncValue(wsChildValue, true);
4072   }
4073   node->SyncValue(wsValue, true);
4074 }
4075 
GetSelectedMember()4076 CXFA_Node* CXFA_Node::GetSelectedMember() {
4077   CXFA_Node* pSelectedMember = nullptr;
4078   WideString wsState = GetRawValue();
4079   if (wsState.IsEmpty())
4080     return pSelectedMember;
4081 
4082   for (CXFA_Node* pNode = ToNode(GetFirstChild()); pNode;
4083        pNode = pNode->GetNextSibling()) {
4084     if (pNode->GetCheckState() == XFA_CheckState::kOn) {
4085       pSelectedMember = pNode;
4086       break;
4087     }
4088   }
4089   return pSelectedMember;
4090 }
4091 
SetSelectedMember(WideStringView wsName)4092 CXFA_Node* CXFA_Node::SetSelectedMember(WideStringView wsName) {
4093   uint32_t nameHash = FX_HashCode_GetW(wsName);
4094   for (CXFA_Node* pNode = ToNode(GetFirstChild()); pNode;
4095        pNode = pNode->GetNextSibling()) {
4096     if (pNode->GetNameHash() == nameHash) {
4097       pNode->SetCheckState(XFA_CheckState::kOn);
4098       return pNode;
4099     }
4100   }
4101   return nullptr;
4102 }
4103 
SetSelectedMemberByValue(WideStringView wsValue,bool bNotify,bool bScriptModify,bool bSyncData)4104 void CXFA_Node::SetSelectedMemberByValue(WideStringView wsValue,
4105                                          bool bNotify,
4106                                          bool bScriptModify,
4107                                          bool bSyncData) {
4108   WideString wsExclGroup;
4109   for (CXFA_Node* pNode = GetFirstChild(); pNode;
4110        pNode = pNode->GetNextSibling()) {
4111     if (pNode->GetElementType() != XFA_Element::Field)
4112       continue;
4113 
4114     CXFA_Items* pItem =
4115         pNode->GetChild<CXFA_Items>(0, XFA_Element::Items, false);
4116     if (!pItem)
4117       continue;
4118 
4119     CXFA_Node* pItemchild = pItem->GetFirstChild();
4120     if (!pItemchild)
4121       continue;
4122 
4123     WideString wsChildValue = pItemchild->JSObject()->GetContent(false);
4124     if (wsValue != wsChildValue) {
4125       pItemchild = pItemchild->GetNextSibling();
4126       if (pItemchild)
4127         wsChildValue = pItemchild->JSObject()->GetContent(false);
4128       else
4129         wsChildValue.clear();
4130     } else {
4131       wsExclGroup = wsValue;
4132     }
4133     pNode->JSObject()->SetContent(wsChildValue, wsChildValue, bNotify,
4134                                   bScriptModify, false);
4135   }
4136   JSObject()->SetContent(wsExclGroup, wsExclGroup, bNotify, bScriptModify,
4137                          bSyncData);
4138 }
4139 
GetExclGroupFirstMember()4140 CXFA_Node* CXFA_Node::GetExclGroupFirstMember() {
4141   CXFA_Node* pNode = GetFirstChild();
4142   while (pNode) {
4143     if (pNode->GetElementType() == XFA_Element::Field)
4144       return pNode;
4145 
4146     pNode = pNode->GetNextSibling();
4147   }
4148   return nullptr;
4149 }
4150 
GetExclGroupNextMember(CXFA_Node * pNode)4151 CXFA_Node* CXFA_Node::GetExclGroupNextMember(CXFA_Node* pNode) {
4152   if (!pNode)
4153     return nullptr;
4154 
4155   CXFA_Node* pNodeField = pNode->GetNextSibling();
4156   while (pNodeField) {
4157     if (pNodeField->GetElementType() == XFA_Element::Field)
4158       return pNodeField;
4159 
4160     pNodeField = pNodeField->GetNextSibling();
4161   }
4162   return nullptr;
4163 }
4164 
IsChoiceListCommitOnSelect()4165 bool CXFA_Node::IsChoiceListCommitOnSelect() {
4166   CXFA_Node* pUIChild = GetUIChildNode();
4167   if (pUIChild) {
4168     return pUIChild->JSObject()->GetEnum(XFA_Attribute::CommitOn) ==
4169            XFA_AttributeValue::Select;
4170   }
4171   return true;
4172 }
4173 
IsChoiceListAllowTextEntry()4174 bool CXFA_Node::IsChoiceListAllowTextEntry() {
4175   CXFA_Node* pUIChild = GetUIChildNode();
4176   return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::TextEntry);
4177 }
4178 
IsChoiceListMultiSelect()4179 bool CXFA_Node::IsChoiceListMultiSelect() {
4180   CXFA_Node* pUIChild = GetUIChildNode();
4181   if (pUIChild) {
4182     return pUIChild->JSObject()->GetEnum(XFA_Attribute::Open) ==
4183            XFA_AttributeValue::MultiSelect;
4184   }
4185   return false;
4186 }
4187 
IsListBox()4188 bool CXFA_Node::IsListBox() {
4189   CXFA_Node* pUIChild = GetUIChildNode();
4190   if (!pUIChild)
4191     return false;
4192 
4193   XFA_AttributeValue attr = pUIChild->JSObject()->GetEnum(XFA_Attribute::Open);
4194   return attr == XFA_AttributeValue::Always ||
4195          attr == XFA_AttributeValue::MultiSelect;
4196 }
4197 
CountChoiceListItems(bool bSaveValue)4198 size_t CXFA_Node::CountChoiceListItems(bool bSaveValue) {
4199   std::vector<CXFA_Node*> pItems;
4200   int32_t iCount = 0;
4201   for (CXFA_Node* pNode = GetFirstChild(); pNode;
4202        pNode = pNode->GetNextSibling()) {
4203     if (pNode->GetElementType() != XFA_Element::Items)
4204       continue;
4205     iCount++;
4206     pItems.push_back(pNode);
4207     if (iCount == 2)
4208       break;
4209   }
4210   if (iCount == 0)
4211     return 0;
4212 
4213   CXFA_Node* pItem = pItems[0];
4214   if (iCount > 1) {
4215     bool bItemOneHasSave =
4216         pItems[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
4217     bool bItemTwoHasSave =
4218         pItems[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
4219     if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
4220       pItem = pItems[1];
4221   }
4222   return pItem->CountChildren(XFA_Element::Unknown, false);
4223 }
4224 
GetChoiceListItem(int32_t nIndex,bool bSaveValue)4225 absl::optional<WideString> CXFA_Node::GetChoiceListItem(int32_t nIndex,
4226                                                         bool bSaveValue) {
4227   std::vector<CXFA_Node*> pItemsArray;
4228   int32_t iCount = 0;
4229   for (CXFA_Node* pNode = GetFirstChild(); pNode;
4230        pNode = pNode->GetNextSibling()) {
4231     if (pNode->GetElementType() != XFA_Element::Items)
4232       continue;
4233 
4234     ++iCount;
4235     pItemsArray.push_back(pNode);
4236     if (iCount == 2)
4237       break;
4238   }
4239   if (iCount == 0)
4240     return absl::nullopt;
4241 
4242   CXFA_Node* pItems = pItemsArray[0];
4243   if (iCount > 1) {
4244     bool bItemOneHasSave =
4245         pItemsArray[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
4246     bool bItemTwoHasSave =
4247         pItemsArray[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
4248     if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
4249       pItems = pItemsArray[1];
4250   }
4251   if (!pItems)
4252     return absl::nullopt;
4253 
4254   CXFA_Node* pItem =
4255       pItems->GetChild<CXFA_Node>(nIndex, XFA_Element::Unknown, false);
4256   if (!pItem)
4257     return absl::nullopt;
4258 
4259   return pItem->JSObject()->GetContent(false);
4260 }
4261 
GetChoiceListItems(bool bSaveValue)4262 std::vector<WideString> CXFA_Node::GetChoiceListItems(bool bSaveValue) {
4263   std::vector<CXFA_Node*> items;
4264   for (CXFA_Node* pNode = GetFirstChild(); pNode && items.size() < 2;
4265        pNode = pNode->GetNextSibling()) {
4266     if (pNode->GetElementType() == XFA_Element::Items)
4267       items.push_back(pNode);
4268   }
4269   if (items.empty())
4270     return std::vector<WideString>();
4271 
4272   CXFA_Node* pItem = items.front();
4273   if (items.size() > 1) {
4274     bool bItemOneHasSave =
4275         items[0]->JSObject()->GetBoolean(XFA_Attribute::Save);
4276     bool bItemTwoHasSave =
4277         items[1]->JSObject()->GetBoolean(XFA_Attribute::Save);
4278     if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave)
4279       pItem = items[1];
4280   }
4281 
4282   std::vector<WideString> wsTextArray;
4283   for (CXFA_Node* pNode = pItem->GetFirstChild(); pNode;
4284        pNode = pNode->GetNextSibling()) {
4285     wsTextArray.emplace_back(pNode->JSObject()->GetContent(false));
4286   }
4287   return wsTextArray;
4288 }
4289 
CountSelectedItems()4290 int32_t CXFA_Node::CountSelectedItems() {
4291   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4292   if (IsListBox() || !IsChoiceListAllowTextEntry())
4293     return fxcrt::CollectionSize<int32_t>(wsValueArray);
4294 
4295   int32_t iSelected = 0;
4296   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4297   for (const auto& value : wsValueArray) {
4298     if (pdfium::Contains(wsSaveTextArray, value))
4299       iSelected++;
4300   }
4301   return iSelected;
4302 }
4303 
GetSelectedItem(int32_t nIndex)4304 int32_t CXFA_Node::GetSelectedItem(int32_t nIndex) {
4305   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4306   if (!fxcrt::IndexInBounds(wsValueArray, nIndex))
4307     return -1;
4308 
4309   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4310   auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(),
4311                       wsValueArray[nIndex]);
4312   return it != wsSaveTextArray.end()
4313              ? pdfium::base::checked_cast<int32_t>(it - wsSaveTextArray.begin())
4314              : -1;
4315 }
4316 
GetSelectedItems()4317 std::vector<int32_t> CXFA_Node::GetSelectedItems() {
4318   std::vector<int32_t> iSelArray;
4319   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4320   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4321   for (const auto& value : wsValueArray) {
4322     auto it = std::find(wsSaveTextArray.begin(), wsSaveTextArray.end(), value);
4323     if (it != wsSaveTextArray.end()) {
4324       iSelArray.push_back(
4325           pdfium::base::checked_cast<int32_t>(it - wsSaveTextArray.begin()));
4326     }
4327   }
4328   return iSelArray;
4329 }
4330 
GetSelectedItemsValue()4331 std::vector<WideString> CXFA_Node::GetSelectedItemsValue() {
4332   WideString wsValue = GetRawValue();
4333   if (IsChoiceListMultiSelect())
4334     return fxcrt::Split(wsValue, L'\n');
4335 
4336   std::vector<WideString> wsSelTextArray;
4337   wsSelTextArray.push_back(wsValue);
4338   return wsSelTextArray;
4339 }
4340 
GetItemState(int32_t nIndex)4341 bool CXFA_Node::GetItemState(int32_t nIndex) {
4342   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4343   return fxcrt::IndexInBounds(wsSaveTextArray, nIndex) &&
4344          pdfium::Contains(GetSelectedItemsValue(), wsSaveTextArray[nIndex]);
4345 }
4346 
SetItemState(int32_t nIndex,bool bSelected,bool bNotify,bool bScriptModify)4347 void CXFA_Node::SetItemState(int32_t nIndex,
4348                              bool bSelected,
4349                              bool bNotify,
4350                              bool bScriptModify) {
4351   std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4352   if (!fxcrt::IndexInBounds(wsSaveTextArray, nIndex))
4353     return;
4354 
4355   int32_t iSel = -1;
4356   std::vector<WideString> wsValueArray = GetSelectedItemsValue();
4357   auto value_iter = std::find(wsValueArray.begin(), wsValueArray.end(),
4358                               wsSaveTextArray[nIndex]);
4359   if (value_iter != wsValueArray.end()) {
4360     iSel =
4361         pdfium::base::checked_cast<int32_t>(value_iter - wsValueArray.begin());
4362   }
4363   if (IsChoiceListMultiSelect()) {
4364     if (bSelected) {
4365       if (iSel < 0) {
4366         WideString wsValue = GetRawValue();
4367         if (!wsValue.IsEmpty()) {
4368           wsValue += L"\n";
4369         }
4370         wsValue += wsSaveTextArray[nIndex];
4371         JSObject()->SetContent(wsValue, wsValue, bNotify, bScriptModify, true);
4372       }
4373     } else if (iSel >= 0) {
4374       std::vector<int32_t> iSelArray = GetSelectedItems();
4375       auto selected_iter =
4376           std::find(iSelArray.begin(), iSelArray.end(), nIndex);
4377       if (selected_iter != iSelArray.end())
4378         iSelArray.erase(selected_iter);
4379       SetSelectedItems(iSelArray, bNotify, bScriptModify, true);
4380     }
4381   } else {
4382     if (bSelected) {
4383       if (iSel < 0) {
4384         WideString wsSaveText = wsSaveTextArray[nIndex];
4385         JSObject()->SetContent(wsSaveText, GetFormatDataValue(wsSaveText),
4386                                bNotify, bScriptModify, true);
4387       }
4388     } else if (iSel >= 0) {
4389       JSObject()->SetContent(WideString(), WideString(), bNotify, bScriptModify,
4390                              true);
4391     }
4392   }
4393 }
4394 
SetSelectedItems(const std::vector<int32_t> & iSelArray,bool bNotify,bool bScriptModify,bool bSyncData)4395 void CXFA_Node::SetSelectedItems(const std::vector<int32_t>& iSelArray,
4396                                  bool bNotify,
4397                                  bool bScriptModify,
4398                                  bool bSyncData) {
4399   WideString wsValue;
4400   int32_t iSize = fxcrt::CollectionSize<int32_t>(iSelArray);
4401   if (iSize >= 1) {
4402     std::vector<WideString> wsSaveTextArray = GetChoiceListItems(true);
4403     WideString wsItemValue;
4404     for (int32_t i = 0; i < iSize; i++) {
4405       wsItemValue = (iSize == 1) ? wsSaveTextArray[iSelArray[i]]
4406                                  : wsSaveTextArray[iSelArray[i]] + L"\n";
4407       wsValue += wsItemValue;
4408     }
4409   }
4410   WideString wsFormat(wsValue);
4411   if (!IsChoiceListMultiSelect())
4412     wsFormat = GetFormatDataValue(wsValue);
4413 
4414   JSObject()->SetContent(wsValue, wsFormat, bNotify, bScriptModify, bSyncData);
4415 }
4416 
ClearAllSelections()4417 void CXFA_Node::ClearAllSelections() {
4418   CXFA_Node* pBind = GetBindData();
4419   if (!pBind || !IsChoiceListMultiSelect()) {
4420     SyncValue(WideString(), false);
4421     return;
4422   }
4423 
4424   while (CXFA_Node* pChildNode = pBind->GetFirstChild())
4425     pBind->RemoveChildAndNotify(pChildNode, true);
4426 }
4427 
InsertItem(const WideString & wsLabel,const WideString & wsValue,bool bNotify)4428 void CXFA_Node::InsertItem(const WideString& wsLabel,
4429                            const WideString& wsValue,
4430                            bool bNotify) {
4431   int32_t nIndex = -1;
4432   WideString wsNewValue(wsValue);
4433   if (wsNewValue.IsEmpty())
4434     wsNewValue = wsLabel;
4435 
4436   std::vector<CXFA_Node*> listitems;
4437   for (CXFA_Node* pItem = GetFirstChild(); pItem;
4438        pItem = pItem->GetNextSibling()) {
4439     if (pItem->GetElementType() == XFA_Element::Items)
4440       listitems.push_back(pItem);
4441   }
4442   if (listitems.empty()) {
4443     CXFA_Node* pItems = CreateSamePacketNode(XFA_Element::Items);
4444     InsertChildAndNotify(-1, pItems);
4445     InsertListTextItem(pItems, wsLabel, nIndex);
4446     CXFA_Node* pSaveItems = CreateSamePacketNode(XFA_Element::Items);
4447     InsertChildAndNotify(-1, pSaveItems);
4448     pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
4449     InsertListTextItem(pSaveItems, wsNewValue, nIndex);
4450   } else if (listitems.size() > 1) {
4451     for (int32_t i = 0; i < 2; i++) {
4452       CXFA_Node* pNode = listitems[i];
4453       bool bHasSave = pNode->JSObject()->GetBoolean(XFA_Attribute::Save);
4454       if (bHasSave)
4455         InsertListTextItem(pNode, wsNewValue, nIndex);
4456       else
4457         InsertListTextItem(pNode, wsLabel, nIndex);
4458     }
4459   } else {
4460     CXFA_Node* pNode = listitems[0];
4461     pNode->JSObject()->SetBoolean(XFA_Attribute::Save, false, false);
4462     pNode->JSObject()->SetEnum(XFA_Attribute::Presence,
4463                                XFA_AttributeValue::Visible, false);
4464     CXFA_Node* pSaveItems = CreateSamePacketNode(XFA_Element::Items);
4465     InsertChildAndNotify(-1, pSaveItems);
4466     pSaveItems->JSObject()->SetBoolean(XFA_Attribute::Save, true, false);
4467     pSaveItems->JSObject()->SetEnum(XFA_Attribute::Presence,
4468                                     XFA_AttributeValue::Hidden, false);
4469     CXFA_Node* pListNode = pNode->GetFirstChild();
4470     int32_t i = 0;
4471     while (pListNode) {
4472       InsertListTextItem(pSaveItems, pListNode->JSObject()->GetContent(false),
4473                          i);
4474       ++i;
4475 
4476       pListNode = pListNode->GetNextSibling();
4477     }
4478     InsertListTextItem(pNode, wsLabel, nIndex);
4479     InsertListTextItem(pSaveItems, wsNewValue, nIndex);
4480   }
4481   if (bNotify)
4482     GetDocument()->GetNotify()->OnWidgetListItemAdded(this, wsLabel, nIndex);
4483 }
4484 
GetItemLabel(WideStringView wsValue) const4485 WideString CXFA_Node::GetItemLabel(WideStringView wsValue) const {
4486   std::vector<CXFA_Node*> listitems;
4487   CXFA_Node* pItems = GetFirstChild();
4488   for (; pItems; pItems = pItems->GetNextSibling()) {
4489     if (pItems->GetElementType() != XFA_Element::Items)
4490       continue;
4491     listitems.push_back(pItems);
4492   }
4493 
4494   if (listitems.size() <= 1)
4495     return WideString(wsValue);
4496 
4497   CXFA_Node* pLabelItems = listitems[0];
4498   bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
4499   CXFA_Node* pSaveItems = nullptr;
4500   if (bSave) {
4501     pSaveItems = pLabelItems;
4502     pLabelItems = listitems[1];
4503   } else {
4504     pSaveItems = listitems[1];
4505   }
4506 
4507   int32_t iCount = 0;
4508   int32_t iSearch = -1;
4509   for (CXFA_Node* pChildItem = pSaveItems->GetFirstChild(); pChildItem;
4510        pChildItem = pChildItem->GetNextSibling()) {
4511     if (pChildItem->JSObject()->GetContent(false) == wsValue) {
4512       iSearch = iCount;
4513       break;
4514     }
4515     iCount++;
4516   }
4517   if (iSearch < 0)
4518     return WideString();
4519 
4520   CXFA_Node* pText =
4521       pLabelItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
4522   return pText ? pText->JSObject()->GetContent(false) : WideString();
4523 }
4524 
GetItemValue(WideStringView wsLabel)4525 WideString CXFA_Node::GetItemValue(WideStringView wsLabel) {
4526   int32_t iCount = 0;
4527   std::vector<CXFA_Node*> listitems;
4528   for (CXFA_Node* pItems = GetFirstChild(); pItems;
4529        pItems = pItems->GetNextSibling()) {
4530     if (pItems->GetElementType() != XFA_Element::Items)
4531       continue;
4532     iCount++;
4533     listitems.push_back(pItems);
4534   }
4535   if (iCount <= 1)
4536     return WideString(wsLabel);
4537 
4538   CXFA_Node* pLabelItems = listitems[0];
4539   bool bSave = pLabelItems->JSObject()->GetBoolean(XFA_Attribute::Save);
4540   CXFA_Node* pSaveItems = nullptr;
4541   if (bSave) {
4542     pSaveItems = pLabelItems;
4543     pLabelItems = listitems[1];
4544   } else {
4545     pSaveItems = listitems[1];
4546   }
4547   iCount = 0;
4548 
4549   int32_t iSearch = -1;
4550   WideString wsContent;
4551   CXFA_Node* pChildItem = pLabelItems->GetFirstChild();
4552   for (; pChildItem; pChildItem = pChildItem->GetNextSibling()) {
4553     if (pChildItem->JSObject()->GetContent(false) == wsLabel) {
4554       iSearch = iCount;
4555       break;
4556     }
4557     iCount++;
4558   }
4559   if (iSearch < 0)
4560     return WideString();
4561 
4562   CXFA_Node* pText =
4563       pSaveItems->GetChild<CXFA_Node>(iSearch, XFA_Element::Unknown, false);
4564   return pText ? pText->JSObject()->GetContent(false) : WideString();
4565 }
4566 
DeleteItem(int32_t nIndex,bool bNotify,bool bScriptModify)4567 bool CXFA_Node::DeleteItem(int32_t nIndex, bool bNotify, bool bScriptModify) {
4568   bool bSetValue = false;
4569   CXFA_Node* pItems = GetFirstChild();
4570   for (; pItems; pItems = pItems->GetNextSibling()) {
4571     if (pItems->GetElementType() != XFA_Element::Items)
4572       continue;
4573 
4574     if (nIndex < 0) {
4575       while (CXFA_Node* pNode = pItems->GetFirstChild()) {
4576         pItems->RemoveChildAndNotify(pNode, true);
4577       }
4578     } else {
4579       if (!bSetValue && pItems->JSObject()->GetBoolean(XFA_Attribute::Save)) {
4580         SetItemState(nIndex, false, true, bScriptModify);
4581         bSetValue = true;
4582       }
4583       int32_t i = 0;
4584       CXFA_Node* pNode = pItems->GetFirstChild();
4585       while (pNode) {
4586         if (i == nIndex) {
4587           pItems->RemoveChildAndNotify(pNode, true);
4588           break;
4589         }
4590         i++;
4591         pNode = pNode->GetNextSibling();
4592       }
4593     }
4594   }
4595   if (bNotify)
4596     GetDocument()->GetNotify()->OnWidgetListItemRemoved(this, nIndex);
4597   return true;
4598 }
4599 
IsHorizontalScrollPolicyOff()4600 bool CXFA_Node::IsHorizontalScrollPolicyOff() {
4601   CXFA_Node* pUIChild = GetUIChildNode();
4602   if (pUIChild) {
4603     return pUIChild->JSObject()->GetEnum(XFA_Attribute::HScrollPolicy) ==
4604            XFA_AttributeValue::Off;
4605   }
4606   return false;
4607 }
4608 
IsVerticalScrollPolicyOff()4609 bool CXFA_Node::IsVerticalScrollPolicyOff() {
4610   CXFA_Node* pUIChild = GetUIChildNode();
4611   if (pUIChild) {
4612     return pUIChild->JSObject()->GetEnum(XFA_Attribute::VScrollPolicy) ==
4613            XFA_AttributeValue::Off;
4614   }
4615   return false;
4616 }
4617 
GetNumberOfCells()4618 absl::optional<int32_t> CXFA_Node::GetNumberOfCells() {
4619   CXFA_Node* pUIChild = GetUIChildNode();
4620   if (!pUIChild)
4621     return absl::nullopt;
4622 
4623   CXFA_Comb* pNode = pUIChild->GetChild<CXFA_Comb>(0, XFA_Element::Comb, false);
4624   if (!pNode)
4625     return absl::nullopt;
4626 
4627   return pNode->JSObject()->GetInteger(XFA_Attribute::NumberOfCells);
4628 }
4629 
IsMultiLine()4630 bool CXFA_Node::IsMultiLine() {
4631   CXFA_Node* pUIChild = GetUIChildNode();
4632   return pUIChild && pUIChild->JSObject()->GetBoolean(XFA_Attribute::MultiLine);
4633 }
4634 
GetMaxChars() const4635 std::pair<XFA_Element, int32_t> CXFA_Node::GetMaxChars() const {
4636   const auto* pNode = GetChild<CXFA_Value>(0, XFA_Element::Value, false);
4637   if (pNode) {
4638     if (CXFA_Node* pChild = pNode->GetFirstChild()) {
4639       switch (pChild->GetElementType()) {
4640         case XFA_Element::Text:
4641           return {XFA_Element::Text,
4642                   pChild->JSObject()->GetInteger(XFA_Attribute::MaxChars)};
4643         case XFA_Element::ExData: {
4644           int32_t iMax =
4645               pChild->JSObject()->GetInteger(XFA_Attribute::MaxLength);
4646           return {XFA_Element::ExData, iMax < 0 ? 0 : iMax};
4647         }
4648         default:
4649           break;
4650       }
4651     }
4652   }
4653   return {XFA_Element::Unknown, 0};
4654 }
4655 
GetFracDigits() const4656 int32_t CXFA_Node::GetFracDigits() const {
4657   const auto* pNode = GetChild<CXFA_Value>(0, XFA_Element::Value, false);
4658   if (!pNode)
4659     return -1;
4660 
4661   const auto* pChild =
4662       pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
4663   if (!pChild)
4664     return -1;
4665 
4666   return pChild->JSObject()
4667       ->TryInteger(XFA_Attribute::FracDigits, true)
4668       .value_or(-1);
4669 }
4670 
GetLeadDigits() const4671 int32_t CXFA_Node::GetLeadDigits() const {
4672   const auto* pNode = GetChild<CXFA_Value>(0, XFA_Element::Value, false);
4673   if (!pNode)
4674     return -1;
4675 
4676   const auto* pChild =
4677       pNode->GetChild<CXFA_Decimal>(0, XFA_Element::Decimal, false);
4678   if (!pChild)
4679     return -1;
4680 
4681   return pChild->JSObject()
4682       ->TryInteger(XFA_Attribute::LeadDigits, true)
4683       .value_or(-1);
4684 }
4685 
SetValue(XFA_ValuePicture eValueType,const WideString & wsValue)4686 bool CXFA_Node::SetValue(XFA_ValuePicture eValueType,
4687                          const WideString& wsValue) {
4688   if (wsValue.IsEmpty()) {
4689     SyncValue(wsValue, true);
4690     return true;
4691   }
4692 
4693   SetPreNull(IsNull());
4694   SetIsNull(false);
4695 
4696   WideString wsNewText(wsValue);
4697   WideString wsPicture = GetPictureContent(eValueType);
4698   bool bValidate = true;
4699   bool bSyncData = false;
4700   CXFA_Node* pNode = GetUIChildNode();
4701   if (!pNode)
4702     return true;
4703 
4704   XFA_Element eType = pNode->GetElementType();
4705   if (!wsPicture.IsEmpty()) {
4706     CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4707     GCedLocaleIface* pLocale = GetLocale();
4708     CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4709     bValidate =
4710         widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture);
4711     if (bValidate) {
4712       widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText,
4713                                      wsPicture, pLocale, pLocaleMgr);
4714       wsNewText = widgetValue.GetValue();
4715       if (eType == XFA_Element::NumericEdit)
4716         wsNewText = NumericLimit(wsNewText);
4717 
4718       bSyncData = true;
4719     }
4720   } else if (eType == XFA_Element::NumericEdit) {
4721     if (!wsNewText.EqualsASCII("0"))
4722       wsNewText = NumericLimit(wsNewText);
4723 
4724     bSyncData = true;
4725   }
4726   if (eType != XFA_Element::NumericEdit || bSyncData)
4727     SyncValue(wsNewText, true);
4728 
4729   return bValidate;
4730 }
4731 
GetPictureContent(XFA_ValuePicture ePicture)4732 WideString CXFA_Node::GetPictureContent(XFA_ValuePicture ePicture) {
4733   if (ePicture == XFA_ValuePicture::kRaw)
4734     return WideString();
4735 
4736   CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4737   switch (ePicture) {
4738     case XFA_ValuePicture::kDisplay: {
4739       auto* pFormat = GetChild<CXFA_Format>(0, XFA_Element::Format, false);
4740       if (pFormat) {
4741         auto* pPicture =
4742             pFormat->GetChild<CXFA_Picture>(0, XFA_Element::Picture, false);
4743         if (pPicture) {
4744           absl::optional<WideString> picture =
4745               pPicture->JSObject()->TryContent(false, true);
4746           if (picture.has_value())
4747             return picture.value();
4748         }
4749       }
4750 
4751       LocaleIface* pLocale = GetLocale();
4752       if (!pLocale)
4753         return WideString();
4754 
4755       switch (widgetValue.GetType()) {
4756         case CXFA_LocaleValue::ValueType::kDate:
4757           return pLocale->GetDatePattern(
4758               LocaleIface::DateTimeSubcategory::kMedium);
4759         case CXFA_LocaleValue::ValueType::kTime:
4760           return pLocale->GetTimePattern(
4761               LocaleIface::DateTimeSubcategory::kMedium);
4762         case CXFA_LocaleValue::ValueType::kDateTime:
4763           return pLocale->GetDatePattern(
4764                      LocaleIface::DateTimeSubcategory::kMedium) +
4765                  L"T" +
4766                  pLocale->GetTimePattern(
4767                      LocaleIface::DateTimeSubcategory::kMedium);
4768         case CXFA_LocaleValue::ValueType::kDecimal:
4769         case CXFA_LocaleValue::ValueType::kFloat:
4770         default:
4771           return WideString();
4772       }
4773     }
4774     case XFA_ValuePicture::kEdit: {
4775       CXFA_Ui* pUI = GetChild<CXFA_Ui>(0, XFA_Element::Ui, false);
4776       if (pUI) {
4777         if (CXFA_Picture* pPicture =
4778                 pUI->GetChild<CXFA_Picture>(0, XFA_Element::Picture, false)) {
4779           absl::optional<WideString> picture =
4780               pPicture->JSObject()->TryContent(false, true);
4781           if (picture.has_value())
4782             return picture.value();
4783         }
4784       }
4785 
4786       LocaleIface* pLocale = GetLocale();
4787       if (!pLocale)
4788         return WideString();
4789 
4790       switch (widgetValue.GetType()) {
4791         case CXFA_LocaleValue::ValueType::kDate:
4792           return pLocale->GetDatePattern(
4793               LocaleIface::DateTimeSubcategory::kShort);
4794         case CXFA_LocaleValue::ValueType::kTime:
4795           return pLocale->GetTimePattern(
4796               LocaleIface::DateTimeSubcategory::kShort);
4797         case CXFA_LocaleValue::ValueType::kDateTime:
4798           return pLocale->GetDatePattern(
4799                      LocaleIface::DateTimeSubcategory::kShort) +
4800                  L"T" +
4801                  pLocale->GetTimePattern(
4802                      LocaleIface::DateTimeSubcategory::kShort);
4803         default:
4804           return WideString();
4805       }
4806     }
4807     case XFA_ValuePicture::kDataBind: {
4808       CXFA_Bind* bind = GetBindIfExists();
4809       if (bind)
4810         return bind->GetPicture();
4811       break;
4812     }
4813     default:
4814       break;
4815   }
4816   return WideString();
4817 }
4818 
GetValue(XFA_ValuePicture eValueType)4819 WideString CXFA_Node::GetValue(XFA_ValuePicture eValueType) {
4820   WideString wsValue = JSObject()->GetContent(false);
4821 
4822   if (eValueType == XFA_ValuePicture::kDisplay)
4823     wsValue = GetItemLabel(wsValue.AsStringView());
4824 
4825   WideString wsPicture = GetPictureContent(eValueType);
4826   CXFA_Node* pNode = GetUIChildNode();
4827   if (!pNode)
4828     return wsValue;
4829 
4830   switch (pNode->GetElementType()) {
4831     case XFA_Element::ChoiceList: {
4832       if (eValueType == XFA_ValuePicture::kDisplay) {
4833         int32_t iSelItemIndex = GetSelectedItem(0);
4834         if (iSelItemIndex >= 0) {
4835           wsValue =
4836               GetChoiceListItem(iSelItemIndex, false).value_or(WideString());
4837           wsPicture.clear();
4838         }
4839       }
4840       break;
4841     }
4842     case XFA_Element::NumericEdit:
4843       if (eValueType != XFA_ValuePicture::kRaw && wsPicture.IsEmpty()) {
4844         LocaleIface* pLocale = GetLocale();
4845         if (eValueType == XFA_ValuePicture::kDisplay && pLocale)
4846           wsValue = FormatNumStr(NormalizeNumStr(wsValue), pLocale);
4847       }
4848       break;
4849     default:
4850       break;
4851   }
4852   if (wsPicture.IsEmpty())
4853     return wsValue;
4854 
4855   GCedLocaleIface* pLocale = GetLocale();
4856   if (pLocale) {
4857     CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4858     CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4859     switch (widgetValue.GetType()) {
4860       case CXFA_LocaleValue::ValueType::kDate: {
4861         WideString wsDate, wsTime;
4862         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4863           CXFA_LocaleValue date(CXFA_LocaleValue::ValueType::kDate, wsDate,
4864                                 pLocaleMgr);
4865           if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
4866             return wsValue;
4867         }
4868         break;
4869       }
4870       case CXFA_LocaleValue::ValueType::kTime: {
4871         WideString wsDate, wsTime;
4872         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4873           CXFA_LocaleValue time(CXFA_LocaleValue::ValueType::kTime, wsTime,
4874                                 pLocaleMgr);
4875           if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
4876             return wsValue;
4877         }
4878         break;
4879       }
4880       default:
4881         break;
4882     }
4883     widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
4884   }
4885   return wsValue;
4886 }
4887 
GetNormalizeDataValue(const WideString & wsValue)4888 WideString CXFA_Node::GetNormalizeDataValue(const WideString& wsValue) {
4889   if (wsValue.IsEmpty())
4890     return WideString();
4891 
4892   WideString wsPicture = GetPictureContent(XFA_ValuePicture::kDataBind);
4893   if (wsPicture.IsEmpty())
4894     return wsValue;
4895 
4896   CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4897   GCedLocaleIface* pLocale = GetLocale();
4898   CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
4899   if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
4900     widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsValue, wsPicture,
4901                                    pLocale, pLocaleMgr);
4902     return widgetValue.GetValue();
4903   }
4904   return wsValue;
4905 }
4906 
GetFormatDataValue(const WideString & wsValue)4907 WideString CXFA_Node::GetFormatDataValue(const WideString& wsValue) {
4908   if (wsValue.IsEmpty())
4909     return WideString();
4910 
4911   WideString wsPicture = GetPictureContent(XFA_ValuePicture::kDataBind);
4912   if (wsPicture.IsEmpty())
4913     return wsValue;
4914 
4915   WideString wsFormattedValue = wsValue;
4916   GCedLocaleIface* pLocale = GetLocale();
4917   if (pLocale) {
4918     CXFA_Value* pNodeValue = GetChild<CXFA_Value>(0, XFA_Element::Value, false);
4919     if (!pNodeValue)
4920       return wsValue;
4921 
4922     CXFA_Node* pValueChild = pNodeValue->GetFirstChild();
4923     if (!pValueChild)
4924       return wsValue;
4925 
4926     CXFA_LocaleValue::ValueType iVTType =
4927         XFA_GetLocaleValueType(pValueChild->GetElementType());
4928     CXFA_LocaleMgr* pLocaleMgr = GetDocument()->GetLocaleMgr();
4929     CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocaleMgr);
4930     switch (widgetValue.GetType()) {
4931       case CXFA_LocaleValue::ValueType::kDate: {
4932         WideString wsDate, wsTime;
4933         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4934           CXFA_LocaleValue date(CXFA_LocaleValue::ValueType::kDate, wsDate,
4935                                 pLocaleMgr);
4936           if (date.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
4937                                   XFA_ValuePicture::kDataBind)) {
4938             return wsFormattedValue;
4939           }
4940         }
4941         break;
4942       }
4943       case CXFA_LocaleValue::ValueType::kTime: {
4944         WideString wsDate, wsTime;
4945         if (SplitDateTime(wsValue, wsDate, wsTime)) {
4946           CXFA_LocaleValue time(CXFA_LocaleValue::ValueType::kTime, wsTime,
4947                                 pLocaleMgr);
4948           if (time.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
4949                                   XFA_ValuePicture::kDataBind)) {
4950             return wsFormattedValue;
4951           }
4952         }
4953         break;
4954       }
4955       default:
4956         break;
4957     }
4958     widgetValue.FormatPatterns(wsFormattedValue, wsPicture, pLocale,
4959                                XFA_ValuePicture::kDataBind);
4960   }
4961   return wsFormattedValue;
4962 }
4963 
NormalizeNumStr(const WideString & wsValue)4964 WideString CXFA_Node::NormalizeNumStr(const WideString& wsValue) {
4965   if (wsValue.IsEmpty())
4966     return WideString();
4967 
4968   WideString wsOutput = wsValue;
4969   wsOutput.TrimLeft('0');
4970 
4971   if (!wsOutput.IsEmpty() && wsOutput.Contains('.') && GetFracDigits() != -1) {
4972     wsOutput.TrimRight(L"0");
4973     wsOutput.TrimRight(L".");
4974   }
4975   if (wsOutput.IsEmpty() || wsOutput[0] == '.')
4976     wsOutput.InsertAtFront('0');
4977 
4978   return wsOutput;
4979 }
4980 
InsertListTextItem(CXFA_Node * pItems,const WideString & wsText,int32_t nIndex)4981 void CXFA_Node::InsertListTextItem(CXFA_Node* pItems,
4982                                    const WideString& wsText,
4983                                    int32_t nIndex) {
4984   CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_Element::Text);
4985   pItems->InsertChildAndNotify(nIndex, pText);
4986   pText->JSObject()->SetContent(wsText, wsText, false, false, false);
4987 }
4988 
NumericLimit(const WideString & wsValue)4989 WideString CXFA_Node::NumericLimit(const WideString& wsValue) {
4990   int32_t iLead = GetLeadDigits();
4991   int32_t iTread = GetFracDigits();
4992   if (iLead == -1 && iTread == -1)
4993     return wsValue;
4994 
4995   int32_t iCount = pdfium::base::checked_cast<int32_t>(wsValue.GetLength());
4996   if (iCount == 0)
4997     return wsValue;
4998 
4999   WideString wsRet;
5000   int32_t i = 0;
5001   if (wsValue[i] == L'-') {
5002     wsRet += L'-';
5003     i++;
5004   }
5005 
5006   int32_t iLead2 = 0;
5007   int32_t iTread2 = -1;
5008   for (; i < iCount; i++) {
5009     wchar_t wc = wsValue[i];
5010     if (FXSYS_IsDecimalDigit(wc)) {
5011       if (iLead >= 0) {
5012         iLead2++;
5013         if (iLead2 > iLead)
5014           return L"0";
5015       } else if (iTread2 >= 0) {
5016         iTread2++;
5017         if (iTread2 > iTread) {
5018           if (iTread != -1) {
5019             CFGAS_Decimal wsDeci = CFGAS_Decimal(wsValue.AsStringView());
5020             wsDeci.SetScale(iTread);
5021             wsRet = wsDeci.ToWideString();
5022           }
5023           return wsRet;
5024         }
5025       }
5026     } else if (wc == L'.') {
5027       iTread2 = 0;
5028       iLead = -1;
5029     }
5030     wsRet += wc;
5031   }
5032   return wsRet;
5033 }
5034 
IsTransparent() const5035 bool CXFA_Node::IsTransparent() const {
5036   XFA_Element type = GetElementType();
5037   return type == XFA_Element::SubformSet || type == XFA_Element::Area ||
5038          type == XFA_Element::Proto || (IsUnnamed() && IsContainerNode());
5039 }
5040 
IsProperty() const5041 bool CXFA_Node::IsProperty() const {
5042   CXFA_Node* parent = GetParent();
5043   return parent && parent->HasProperty(GetElementType());
5044 }
5045 
PresenceRequiresSpace() const5046 bool CXFA_Node::PresenceRequiresSpace() const {
5047   auto value = JSObject()->TryEnum(XFA_Attribute::Presence, true);
5048   XFA_AttributeValue ePresence = value.value_or(XFA_AttributeValue::Visible);
5049   return ePresence == XFA_AttributeValue::Visible ||
5050          ePresence == XFA_AttributeValue::Invisible;
5051 }
5052 
SetBindingNode(CXFA_Node * node)5053 void CXFA_Node::SetBindingNode(CXFA_Node* node) {
5054   binding_nodes_.clear();
5055   if (node)
5056     binding_nodes_.emplace_back(node);
5057 }
5058 
SetNodeAndDescendantsUnused()5059 void CXFA_Node::SetNodeAndDescendantsUnused() {
5060   CXFA_NodeIterator sIterator(this);
5061   for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
5062        pNode = sIterator.MoveToNext()) {
5063     pNode->SetFlag(XFA_NodeFlag::kUnusedNode);
5064   }
5065 }
5066 
SetToXML(const WideString & value)5067 void CXFA_Node::SetToXML(const WideString& value) {
5068   auto* pNode = GetXMLMappingNode();
5069   switch (pNode->GetType()) {
5070     case CFX_XMLNode::Type::kElement: {
5071       auto* elem = static_cast<CFX_XMLElement*>(pNode);
5072       if (IsAttributeInXML()) {
5073         elem->SetAttribute(JSObject()->GetCData(XFA_Attribute::QualifiedName),
5074                            value);
5075         return;
5076       }
5077 
5078       bool bDeleteChildren = true;
5079       if (GetPacketType() == XFA_PacketType::Datasets) {
5080         for (CXFA_Node* pChildDataNode = GetFirstChild(); pChildDataNode;
5081              pChildDataNode = pChildDataNode->GetNextSibling()) {
5082           if (pChildDataNode->HasBindItems()) {
5083             bDeleteChildren = false;
5084             break;
5085           }
5086         }
5087       }
5088       if (bDeleteChildren)
5089         elem->RemoveAllChildren();
5090 
5091       auto* text = GetXMLDocument()->CreateNode<CFX_XMLText>(value);
5092       elem->AppendLastChild(text);
5093       break;
5094     }
5095     case CFX_XMLNode::Type::kText:
5096       ToXMLText(GetXMLMappingNode())->SetText(value);
5097       break;
5098     default:
5099       NOTREACHED();
5100   }
5101 }
5102 
GetTransparentParent()5103 CXFA_Node* CXFA_Node::GetTransparentParent() {
5104   CXFA_Node* parent = GetParent();
5105   while (parent) {
5106     XFA_Element type = parent->GetElementType();
5107     if (type == XFA_Element::Variables ||
5108         (type != XFA_Element::SubformSet && !parent->IsUnnamed())) {
5109       return parent;
5110     }
5111     parent = parent->GetParent();
5112   }
5113   return nullptr;
5114 }
5115 
GetXMLDocument() const5116 CFX_XMLDocument* CXFA_Node::GetXMLDocument() const {
5117   return GetDocument()->GetNotify()->GetFFDoc()->GetXMLDocument();
5118 }
5119 
5120 // static
Create(CXFA_Document * doc,XFA_Element element,XFA_PacketType packet)5121 CXFA_Node* CXFA_Node::Create(CXFA_Document* doc,
5122                              XFA_Element element,
5123                              XFA_PacketType packet) {
5124   CXFA_Node* node = nullptr;
5125   switch (element) {
5126     case XFA_Element::Ps:
5127       node = cppgc::MakeGarbageCollected<CXFA_Ps>(
5128           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5129       break;
5130     case XFA_Element::To:
5131       node = cppgc::MakeGarbageCollected<CXFA_To>(
5132           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5133       break;
5134     case XFA_Element::Ui:
5135       node = cppgc::MakeGarbageCollected<CXFA_Ui>(
5136           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5137       break;
5138     case XFA_Element::RecordSet:
5139       node = cppgc::MakeGarbageCollected<CXFA_RecordSet>(
5140           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5141       break;
5142     case XFA_Element::SubsetBelow:
5143       node = cppgc::MakeGarbageCollected<CXFA_SubsetBelow>(
5144           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5145       break;
5146     case XFA_Element::SubformSet:
5147       node = cppgc::MakeGarbageCollected<CXFA_SubformSet>(
5148           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5149       break;
5150     case XFA_Element::AdobeExtensionLevel:
5151       node = cppgc::MakeGarbageCollected<CXFA_AdobeExtensionLevel>(
5152           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5153       break;
5154     case XFA_Element::Typeface:
5155       node = cppgc::MakeGarbageCollected<CXFA_Typeface>(
5156           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5157       break;
5158     case XFA_Element::Break:
5159       node = cppgc::MakeGarbageCollected<CXFA_Break>(
5160           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5161       break;
5162     case XFA_Element::FontInfo:
5163       node = cppgc::MakeGarbageCollected<CXFA_FontInfo>(
5164           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5165       break;
5166     case XFA_Element::NumberPattern:
5167       node = cppgc::MakeGarbageCollected<CXFA_NumberPattern>(
5168           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5169       break;
5170     case XFA_Element::DynamicRender:
5171       node = cppgc::MakeGarbageCollected<CXFA_DynamicRender>(
5172           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5173       break;
5174     case XFA_Element::PrintScaling:
5175       node = cppgc::MakeGarbageCollected<CXFA_PrintScaling>(
5176           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5177       break;
5178     case XFA_Element::CheckButton:
5179       node = cppgc::MakeGarbageCollected<CXFA_CheckButton>(
5180           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5181       break;
5182     case XFA_Element::DatePatterns:
5183       node = cppgc::MakeGarbageCollected<CXFA_DatePatterns>(
5184           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5185       break;
5186     case XFA_Element::SourceSet:
5187       node = cppgc::MakeGarbageCollected<CXFA_SourceSet>(
5188           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5189       break;
5190     case XFA_Element::Amd:
5191       node = cppgc::MakeGarbageCollected<CXFA_Amd>(
5192           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5193       break;
5194     case XFA_Element::Arc:
5195       node = cppgc::MakeGarbageCollected<CXFA_Arc>(
5196           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5197       break;
5198     case XFA_Element::Day:
5199       node = cppgc::MakeGarbageCollected<CXFA_Day>(
5200           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5201       break;
5202     case XFA_Element::Era:
5203       node = cppgc::MakeGarbageCollected<CXFA_Era>(
5204           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5205       break;
5206     case XFA_Element::Jog:
5207       node = cppgc::MakeGarbageCollected<CXFA_Jog>(
5208           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5209       break;
5210     case XFA_Element::Log:
5211       node = cppgc::MakeGarbageCollected<CXFA_Log>(
5212           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5213       break;
5214     case XFA_Element::Map:
5215       node = cppgc::MakeGarbageCollected<CXFA_Map>(
5216           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5217       break;
5218     case XFA_Element::Mdp:
5219       node = cppgc::MakeGarbageCollected<CXFA_Mdp>(
5220           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5221       break;
5222     case XFA_Element::BreakBefore:
5223       node = cppgc::MakeGarbageCollected<CXFA_BreakBefore>(
5224           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5225       break;
5226     case XFA_Element::Oid:
5227       node = cppgc::MakeGarbageCollected<CXFA_Oid>(
5228           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5229       break;
5230     case XFA_Element::Pcl:
5231       node = cppgc::MakeGarbageCollected<CXFA_Pcl>(
5232           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5233       break;
5234     case XFA_Element::Pdf:
5235       node = cppgc::MakeGarbageCollected<CXFA_Pdf>(
5236           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5237       break;
5238     case XFA_Element::Ref:
5239       node = cppgc::MakeGarbageCollected<CXFA_Ref>(
5240           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5241       break;
5242     case XFA_Element::Uri:
5243       node = cppgc::MakeGarbageCollected<CXFA_Uri>(
5244           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5245       break;
5246     case XFA_Element::Xdc:
5247       node = cppgc::MakeGarbageCollected<CXFA_Xdc>(
5248           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5249       break;
5250     case XFA_Element::Xdp:
5251       node = cppgc::MakeGarbageCollected<CXFA_Xdp>(
5252           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5253       break;
5254     case XFA_Element::Xfa:
5255       node = cppgc::MakeGarbageCollected<CXFA_Xfa>(
5256           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5257       break;
5258     case XFA_Element::Xsl:
5259       node = cppgc::MakeGarbageCollected<CXFA_Xsl>(
5260           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5261       break;
5262     case XFA_Element::Zpl:
5263       node = cppgc::MakeGarbageCollected<CXFA_Zpl>(
5264           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5265       break;
5266     case XFA_Element::Cache:
5267       node = cppgc::MakeGarbageCollected<CXFA_Cache>(
5268           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5269       break;
5270     case XFA_Element::Margin:
5271       node = cppgc::MakeGarbageCollected<CXFA_Margin>(
5272           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5273       break;
5274     case XFA_Element::KeyUsage:
5275       node = cppgc::MakeGarbageCollected<CXFA_KeyUsage>(
5276           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5277       break;
5278     case XFA_Element::Exclude:
5279       node = cppgc::MakeGarbageCollected<CXFA_Exclude>(
5280           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5281       break;
5282     case XFA_Element::ChoiceList:
5283       node = cppgc::MakeGarbageCollected<CXFA_ChoiceList>(
5284           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5285       break;
5286     case XFA_Element::Level:
5287       node = cppgc::MakeGarbageCollected<CXFA_Level>(
5288           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5289       break;
5290     case XFA_Element::LabelPrinter:
5291       node = cppgc::MakeGarbageCollected<CXFA_LabelPrinter>(
5292           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5293       break;
5294     case XFA_Element::CalendarSymbols:
5295       node = cppgc::MakeGarbageCollected<CXFA_CalendarSymbols>(
5296           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5297       break;
5298     case XFA_Element::Para:
5299       node = cppgc::MakeGarbageCollected<CXFA_Para>(
5300           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5301       break;
5302     case XFA_Element::Part:
5303       node = cppgc::MakeGarbageCollected<CXFA_Part>(
5304           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5305       break;
5306     case XFA_Element::Pdfa:
5307       node = cppgc::MakeGarbageCollected<CXFA_Pdfa>(
5308           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5309       break;
5310     case XFA_Element::Filter:
5311       node = cppgc::MakeGarbageCollected<CXFA_Filter>(
5312           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5313       break;
5314     case XFA_Element::Present:
5315       node = cppgc::MakeGarbageCollected<CXFA_Present>(
5316           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5317       break;
5318     case XFA_Element::Pagination:
5319       node = cppgc::MakeGarbageCollected<CXFA_Pagination>(
5320           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5321       break;
5322     case XFA_Element::Encoding:
5323       node = cppgc::MakeGarbageCollected<CXFA_Encoding>(
5324           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5325       break;
5326     case XFA_Element::Event:
5327       node = cppgc::MakeGarbageCollected<CXFA_Event>(
5328           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5329       break;
5330     case XFA_Element::Whitespace:
5331       node = cppgc::MakeGarbageCollected<CXFA_Whitespace>(
5332           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5333       break;
5334     case XFA_Element::DefaultUi:
5335       node = cppgc::MakeGarbageCollected<CXFA_DefaultUi>(
5336           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5337       break;
5338     case XFA_Element::DataModel:
5339       node = cppgc::MakeGarbageCollected<CXFA_DataModel>(
5340           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5341       break;
5342     case XFA_Element::Barcode:
5343       node = cppgc::MakeGarbageCollected<CXFA_Barcode>(
5344           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5345       break;
5346     case XFA_Element::TimePattern:
5347       node = cppgc::MakeGarbageCollected<CXFA_TimePattern>(
5348           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5349       break;
5350     case XFA_Element::BatchOutput:
5351       node = cppgc::MakeGarbageCollected<CXFA_BatchOutput>(
5352           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5353       break;
5354     case XFA_Element::Enforce:
5355       node = cppgc::MakeGarbageCollected<CXFA_Enforce>(
5356           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5357       break;
5358     case XFA_Element::CurrencySymbols:
5359       node = cppgc::MakeGarbageCollected<CXFA_CurrencySymbols>(
5360           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5361       break;
5362     case XFA_Element::AddSilentPrint:
5363       node = cppgc::MakeGarbageCollected<CXFA_AddSilentPrint>(
5364           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5365       break;
5366     case XFA_Element::Rename:
5367       node = cppgc::MakeGarbageCollected<CXFA_Rename>(
5368           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5369       break;
5370     case XFA_Element::Operation:
5371       node = cppgc::MakeGarbageCollected<CXFA_Operation>(
5372           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5373       break;
5374     case XFA_Element::Typefaces:
5375       node = cppgc::MakeGarbageCollected<CXFA_Typefaces>(
5376           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5377       break;
5378     case XFA_Element::SubjectDNs:
5379       node = cppgc::MakeGarbageCollected<CXFA_SubjectDNs>(
5380           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5381       break;
5382     case XFA_Element::Issuers:
5383       node = cppgc::MakeGarbageCollected<CXFA_Issuers>(
5384           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5385       break;
5386     case XFA_Element::WsdlConnection:
5387       node = cppgc::MakeGarbageCollected<CXFA_WsdlConnection>(
5388           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5389       break;
5390     case XFA_Element::Debug:
5391       node = cppgc::MakeGarbageCollected<CXFA_Debug>(
5392           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5393       break;
5394     case XFA_Element::Delta:
5395       node = cppgc::MakeGarbageCollected<CXFA_Delta>(
5396           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5397       break;
5398     case XFA_Element::EraNames:
5399       node = cppgc::MakeGarbageCollected<CXFA_EraNames>(
5400           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5401       break;
5402     case XFA_Element::ModifyAnnots:
5403       node = cppgc::MakeGarbageCollected<CXFA_ModifyAnnots>(
5404           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5405       break;
5406     case XFA_Element::StartNode:
5407       node = cppgc::MakeGarbageCollected<CXFA_StartNode>(
5408           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5409       break;
5410     case XFA_Element::Button:
5411       node = cppgc::MakeGarbageCollected<CXFA_Button>(
5412           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5413       break;
5414     case XFA_Element::Format:
5415       node = cppgc::MakeGarbageCollected<CXFA_Format>(
5416           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5417       break;
5418     case XFA_Element::Border:
5419       node = cppgc::MakeGarbageCollected<CXFA_Border>(
5420           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5421       break;
5422     case XFA_Element::Area:
5423       node = cppgc::MakeGarbageCollected<CXFA_Area>(
5424           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5425       break;
5426     case XFA_Element::Hyphenation:
5427       node = cppgc::MakeGarbageCollected<CXFA_Hyphenation>(
5428           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5429       break;
5430     case XFA_Element::Text:
5431       node = cppgc::MakeGarbageCollected<CXFA_Text>(
5432           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5433       break;
5434     case XFA_Element::Time:
5435       node = cppgc::MakeGarbageCollected<CXFA_Time>(
5436           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5437       break;
5438     case XFA_Element::Type:
5439       node = cppgc::MakeGarbageCollected<CXFA_Type>(
5440           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5441       break;
5442     case XFA_Element::Overprint:
5443       node = cppgc::MakeGarbageCollected<CXFA_Overprint>(
5444           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5445       break;
5446     case XFA_Element::Certificates:
5447       node = cppgc::MakeGarbageCollected<CXFA_Certificates>(
5448           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5449       break;
5450     case XFA_Element::EncryptionMethods:
5451       node = cppgc::MakeGarbageCollected<CXFA_EncryptionMethods>(
5452           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5453       break;
5454     case XFA_Element::SetProperty:
5455       node = cppgc::MakeGarbageCollected<CXFA_SetProperty>(
5456           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5457       break;
5458     case XFA_Element::PrinterName:
5459       node = cppgc::MakeGarbageCollected<CXFA_PrinterName>(
5460           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5461       break;
5462     case XFA_Element::StartPage:
5463       node = cppgc::MakeGarbageCollected<CXFA_StartPage>(
5464           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5465       break;
5466     case XFA_Element::PageOffset:
5467       node = cppgc::MakeGarbageCollected<CXFA_PageOffset>(
5468           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5469       break;
5470     case XFA_Element::DateTime:
5471       node = cppgc::MakeGarbageCollected<CXFA_DateTime>(
5472           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5473       break;
5474     case XFA_Element::Comb:
5475       node = cppgc::MakeGarbageCollected<CXFA_Comb>(
5476           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5477       break;
5478     case XFA_Element::Pattern:
5479       node = cppgc::MakeGarbageCollected<CXFA_Pattern>(
5480           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5481       break;
5482     case XFA_Element::IfEmpty:
5483       node = cppgc::MakeGarbageCollected<CXFA_IfEmpty>(
5484           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5485       break;
5486     case XFA_Element::SuppressBanner:
5487       node = cppgc::MakeGarbageCollected<CXFA_SuppressBanner>(
5488           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5489       break;
5490     case XFA_Element::OutputBin:
5491       node = cppgc::MakeGarbageCollected<CXFA_OutputBin>(
5492           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5493       break;
5494     case XFA_Element::Field:
5495       node = cppgc::MakeGarbageCollected<CXFA_Field>(
5496           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5497       break;
5498     case XFA_Element::Agent:
5499       node = cppgc::MakeGarbageCollected<CXFA_Agent>(
5500           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5501       break;
5502     case XFA_Element::OutputXSL:
5503       node = cppgc::MakeGarbageCollected<CXFA_OutputXSL>(
5504           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5505       break;
5506     case XFA_Element::AdjustData:
5507       node = cppgc::MakeGarbageCollected<CXFA_AdjustData>(
5508           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5509       break;
5510     case XFA_Element::AutoSave:
5511       node = cppgc::MakeGarbageCollected<CXFA_AutoSave>(
5512           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5513       break;
5514     case XFA_Element::ContentArea:
5515       node = cppgc::MakeGarbageCollected<CXFA_ContentArea>(
5516           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5517       break;
5518     case XFA_Element::WsdlAddress:
5519       node = cppgc::MakeGarbageCollected<CXFA_WsdlAddress>(
5520           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5521       break;
5522     case XFA_Element::Solid:
5523       node = cppgc::MakeGarbageCollected<CXFA_Solid>(
5524           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5525       break;
5526     case XFA_Element::DateTimeSymbols:
5527       node = cppgc::MakeGarbageCollected<CXFA_DateTimeSymbols>(
5528           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5529       break;
5530     case XFA_Element::EncryptionLevel:
5531       node = cppgc::MakeGarbageCollected<CXFA_EncryptionLevel>(
5532           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5533       break;
5534     case XFA_Element::Edge:
5535       node = cppgc::MakeGarbageCollected<CXFA_Edge>(
5536           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5537       break;
5538     case XFA_Element::Stipple:
5539       node = cppgc::MakeGarbageCollected<CXFA_Stipple>(
5540           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5541       break;
5542     case XFA_Element::Attributes:
5543       node = cppgc::MakeGarbageCollected<CXFA_Attributes>(
5544           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5545       break;
5546     case XFA_Element::VersionControl:
5547       node = cppgc::MakeGarbageCollected<CXFA_VersionControl>(
5548           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5549       break;
5550     case XFA_Element::Meridiem:
5551       node = cppgc::MakeGarbageCollected<CXFA_Meridiem>(
5552           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5553       break;
5554     case XFA_Element::ExclGroup:
5555       node = cppgc::MakeGarbageCollected<CXFA_ExclGroup>(
5556           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5557       break;
5558     case XFA_Element::ToolTip:
5559       node = cppgc::MakeGarbageCollected<CXFA_ToolTip>(
5560           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5561       break;
5562     case XFA_Element::Compress:
5563       node = cppgc::MakeGarbageCollected<CXFA_Compress>(
5564           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5565       break;
5566     case XFA_Element::Reason:
5567       node = cppgc::MakeGarbageCollected<CXFA_Reason>(
5568           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5569       break;
5570     case XFA_Element::Execute:
5571       node = cppgc::MakeGarbageCollected<CXFA_Execute>(
5572           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5573       break;
5574     case XFA_Element::ContentCopy:
5575       node = cppgc::MakeGarbageCollected<CXFA_ContentCopy>(
5576           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5577       break;
5578     case XFA_Element::DateTimeEdit:
5579       node = cppgc::MakeGarbageCollected<CXFA_DateTimeEdit>(
5580           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5581       break;
5582     case XFA_Element::Config:
5583       node = cppgc::MakeGarbageCollected<CXFA_Config>(
5584           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5585       break;
5586     case XFA_Element::Image:
5587       node = cppgc::MakeGarbageCollected<CXFA_Image>(
5588           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5589       break;
5590     case XFA_Element::SharpxHTML:
5591       node = cppgc::MakeGarbageCollected<CXFA_SharpxHTML>(
5592           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5593       break;
5594     case XFA_Element::NumberOfCopies:
5595       node = cppgc::MakeGarbageCollected<CXFA_NumberOfCopies>(
5596           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5597       break;
5598     case XFA_Element::BehaviorOverride:
5599       node = cppgc::MakeGarbageCollected<CXFA_BehaviorOverride>(
5600           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5601       break;
5602     case XFA_Element::TimeStamp:
5603       node = cppgc::MakeGarbageCollected<CXFA_TimeStamp>(
5604           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5605       break;
5606     case XFA_Element::Month:
5607       node = cppgc::MakeGarbageCollected<CXFA_Month>(
5608           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5609       break;
5610     case XFA_Element::ViewerPreferences:
5611       node = cppgc::MakeGarbageCollected<CXFA_ViewerPreferences>(
5612           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5613       break;
5614     case XFA_Element::ScriptModel:
5615       node = cppgc::MakeGarbageCollected<CXFA_ScriptModel>(
5616           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5617       break;
5618     case XFA_Element::Decimal:
5619       node = cppgc::MakeGarbageCollected<CXFA_Decimal>(
5620           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5621       break;
5622     case XFA_Element::Subform:
5623       node = cppgc::MakeGarbageCollected<CXFA_Subform>(
5624           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5625       break;
5626     case XFA_Element::Select:
5627       node = cppgc::MakeGarbageCollected<CXFA_Select>(
5628           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5629       break;
5630     case XFA_Element::Window:
5631       node = cppgc::MakeGarbageCollected<CXFA_Window>(
5632           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5633       break;
5634     case XFA_Element::LocaleSet:
5635       node = cppgc::MakeGarbageCollected<CXFA_LocaleSet>(
5636           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5637       break;
5638     case XFA_Element::Handler:
5639       node = cppgc::MakeGarbageCollected<CXFA_Handler>(
5640           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5641       break;
5642     case XFA_Element::Presence:
5643       node = cppgc::MakeGarbageCollected<CXFA_Presence>(
5644           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5645       break;
5646     case XFA_Element::Record:
5647       node = cppgc::MakeGarbageCollected<CXFA_Record>(
5648           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5649       break;
5650     case XFA_Element::Embed:
5651       node = cppgc::MakeGarbageCollected<CXFA_Embed>(
5652           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5653       break;
5654     case XFA_Element::Version:
5655       node = cppgc::MakeGarbageCollected<CXFA_Version>(
5656           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5657       break;
5658     case XFA_Element::Command:
5659       node = cppgc::MakeGarbageCollected<CXFA_Command>(
5660           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5661       break;
5662     case XFA_Element::Copies:
5663       node = cppgc::MakeGarbageCollected<CXFA_Copies>(
5664           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5665       break;
5666     case XFA_Element::Staple:
5667       node = cppgc::MakeGarbageCollected<CXFA_Staple>(
5668           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5669       break;
5670     case XFA_Element::SubmitFormat:
5671       node = cppgc::MakeGarbageCollected<CXFA_SubmitFormat>(
5672           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5673       break;
5674     case XFA_Element::Boolean:
5675       node = cppgc::MakeGarbageCollected<CXFA_Boolean>(
5676           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5677       break;
5678     case XFA_Element::Message:
5679       node = cppgc::MakeGarbageCollected<CXFA_Message>(
5680           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5681       break;
5682     case XFA_Element::Output:
5683       node = cppgc::MakeGarbageCollected<CXFA_Output>(
5684           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5685       break;
5686     case XFA_Element::PsMap:
5687       node = cppgc::MakeGarbageCollected<CXFA_PsMap>(
5688           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5689       break;
5690     case XFA_Element::ExcludeNS:
5691       node = cppgc::MakeGarbageCollected<CXFA_ExcludeNS>(
5692           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5693       break;
5694     case XFA_Element::Assist:
5695       node = cppgc::MakeGarbageCollected<CXFA_Assist>(
5696           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5697       break;
5698     case XFA_Element::Picture:
5699       node = cppgc::MakeGarbageCollected<CXFA_Picture>(
5700           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5701       break;
5702     case XFA_Element::Traversal:
5703       node = cppgc::MakeGarbageCollected<CXFA_Traversal>(
5704           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5705       break;
5706     case XFA_Element::SilentPrint:
5707       node = cppgc::MakeGarbageCollected<CXFA_SilentPrint>(
5708           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5709       break;
5710     case XFA_Element::WebClient:
5711       node = cppgc::MakeGarbageCollected<CXFA_WebClient>(
5712           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5713       break;
5714     case XFA_Element::Producer:
5715       node = cppgc::MakeGarbageCollected<CXFA_Producer>(
5716           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5717       break;
5718     case XFA_Element::Corner:
5719       node = cppgc::MakeGarbageCollected<CXFA_Corner>(
5720           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5721       break;
5722     case XFA_Element::MsgId:
5723       node = cppgc::MakeGarbageCollected<CXFA_MsgId>(
5724           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5725       break;
5726     case XFA_Element::Color:
5727       node = cppgc::MakeGarbageCollected<CXFA_Color>(
5728           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5729       break;
5730     case XFA_Element::Keep:
5731       node = cppgc::MakeGarbageCollected<CXFA_Keep>(
5732           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5733       break;
5734     case XFA_Element::Query:
5735       node = cppgc::MakeGarbageCollected<CXFA_Query>(
5736           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5737       break;
5738     case XFA_Element::Insert:
5739       node = cppgc::MakeGarbageCollected<CXFA_Insert>(
5740           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5741       break;
5742     case XFA_Element::ImageEdit:
5743       node = cppgc::MakeGarbageCollected<CXFA_ImageEdit>(
5744           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5745       break;
5746     case XFA_Element::Validate:
5747       node = cppgc::MakeGarbageCollected<CXFA_Validate>(
5748           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5749       break;
5750     case XFA_Element::DigestMethods:
5751       node = cppgc::MakeGarbageCollected<CXFA_DigestMethods>(
5752           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5753       break;
5754     case XFA_Element::NumberPatterns:
5755       node = cppgc::MakeGarbageCollected<CXFA_NumberPatterns>(
5756           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5757       break;
5758     case XFA_Element::PageSet:
5759       node = cppgc::MakeGarbageCollected<CXFA_PageSet>(
5760           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5761       break;
5762     case XFA_Element::Integer:
5763       node = cppgc::MakeGarbageCollected<CXFA_Integer>(
5764           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5765       break;
5766     case XFA_Element::SoapAddress:
5767       node = cppgc::MakeGarbageCollected<CXFA_SoapAddress>(
5768           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5769       break;
5770     case XFA_Element::Equate:
5771       node = cppgc::MakeGarbageCollected<CXFA_Equate>(
5772           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5773       break;
5774     case XFA_Element::FormFieldFilling:
5775       node = cppgc::MakeGarbageCollected<CXFA_FormFieldFilling>(
5776           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5777       break;
5778     case XFA_Element::PageRange:
5779       node = cppgc::MakeGarbageCollected<CXFA_PageRange>(
5780           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5781       break;
5782     case XFA_Element::Update:
5783       node = cppgc::MakeGarbageCollected<CXFA_Update>(
5784           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5785       break;
5786     case XFA_Element::ConnectString:
5787       node = cppgc::MakeGarbageCollected<CXFA_ConnectString>(
5788           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5789       break;
5790     case XFA_Element::Mode:
5791       node = cppgc::MakeGarbageCollected<CXFA_Mode>(
5792           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5793       break;
5794     case XFA_Element::Layout:
5795       node = cppgc::MakeGarbageCollected<CXFA_Layout>(
5796           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5797       break;
5798     case XFA_Element::Sharpxml:
5799       node = cppgc::MakeGarbageCollected<CXFA_Sharpxml>(
5800           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5801       break;
5802     case XFA_Element::XsdConnection:
5803       node = cppgc::MakeGarbageCollected<CXFA_XsdConnection>(
5804           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5805       break;
5806     case XFA_Element::Traverse:
5807       node = cppgc::MakeGarbageCollected<CXFA_Traverse>(
5808           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5809       break;
5810     case XFA_Element::Encodings:
5811       node = cppgc::MakeGarbageCollected<CXFA_Encodings>(
5812           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5813       break;
5814     case XFA_Element::Template:
5815       node = cppgc::MakeGarbageCollected<CXFA_Template>(
5816           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5817       break;
5818     case XFA_Element::Acrobat:
5819       node = cppgc::MakeGarbageCollected<CXFA_Acrobat>(
5820           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5821       break;
5822     case XFA_Element::ValidationMessaging:
5823       node = cppgc::MakeGarbageCollected<CXFA_ValidationMessaging>(
5824           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5825       break;
5826     case XFA_Element::Signing:
5827       node = cppgc::MakeGarbageCollected<CXFA_Signing>(
5828           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5829       break;
5830     case XFA_Element::Script:
5831       node = cppgc::MakeGarbageCollected<CXFA_Script>(
5832           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5833       break;
5834     case XFA_Element::AddViewerPreferences:
5835       node = cppgc::MakeGarbageCollected<CXFA_AddViewerPreferences>(
5836           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5837       break;
5838     case XFA_Element::AlwaysEmbed:
5839       node = cppgc::MakeGarbageCollected<CXFA_AlwaysEmbed>(
5840           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5841       break;
5842     case XFA_Element::PasswordEdit:
5843       node = cppgc::MakeGarbageCollected<CXFA_PasswordEdit>(
5844           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5845       break;
5846     case XFA_Element::NumericEdit:
5847       node = cppgc::MakeGarbageCollected<CXFA_NumericEdit>(
5848           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5849       break;
5850     case XFA_Element::EncryptionMethod:
5851       node = cppgc::MakeGarbageCollected<CXFA_EncryptionMethod>(
5852           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5853       break;
5854     case XFA_Element::Change:
5855       node = cppgc::MakeGarbageCollected<CXFA_Change>(
5856           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5857       break;
5858     case XFA_Element::PageArea:
5859       node = cppgc::MakeGarbageCollected<CXFA_PageArea>(
5860           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5861       break;
5862     case XFA_Element::SubmitUrl:
5863       node = cppgc::MakeGarbageCollected<CXFA_SubmitUrl>(
5864           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5865       break;
5866     case XFA_Element::Oids:
5867       node = cppgc::MakeGarbageCollected<CXFA_Oids>(
5868           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5869       break;
5870     case XFA_Element::Signature:
5871       node = cppgc::MakeGarbageCollected<CXFA_Signature>(
5872           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5873       break;
5874     case XFA_Element::ADBE_JSConsole:
5875       node = cppgc::MakeGarbageCollected<CXFA_ADBE_JSConsole>(
5876           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5877       break;
5878     case XFA_Element::Caption:
5879       node = cppgc::MakeGarbageCollected<CXFA_Caption>(
5880           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5881       break;
5882     case XFA_Element::Relevant:
5883       node = cppgc::MakeGarbageCollected<CXFA_Relevant>(
5884           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5885       break;
5886     case XFA_Element::FlipLabel:
5887       node = cppgc::MakeGarbageCollected<CXFA_FlipLabel>(
5888           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5889       break;
5890     case XFA_Element::ExData:
5891       node = cppgc::MakeGarbageCollected<CXFA_ExData>(
5892           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5893       break;
5894     case XFA_Element::DayNames:
5895       node = cppgc::MakeGarbageCollected<CXFA_DayNames>(
5896           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5897       break;
5898     case XFA_Element::SoapAction:
5899       node = cppgc::MakeGarbageCollected<CXFA_SoapAction>(
5900           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5901       break;
5902     case XFA_Element::DefaultTypeface:
5903       node = cppgc::MakeGarbageCollected<CXFA_DefaultTypeface>(
5904           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5905       break;
5906     case XFA_Element::Manifest:
5907       node = cppgc::MakeGarbageCollected<CXFA_Manifest>(
5908           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5909       break;
5910     case XFA_Element::Overflow:
5911       node = cppgc::MakeGarbageCollected<CXFA_Overflow>(
5912           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5913       break;
5914     case XFA_Element::Linear:
5915       node = cppgc::MakeGarbageCollected<CXFA_Linear>(
5916           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5917       break;
5918     case XFA_Element::CurrencySymbol:
5919       node = cppgc::MakeGarbageCollected<CXFA_CurrencySymbol>(
5920           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5921       break;
5922     case XFA_Element::Delete:
5923       node = cppgc::MakeGarbageCollected<CXFA_Delete>(
5924           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5925       break;
5926     case XFA_Element::DigestMethod:
5927       node = cppgc::MakeGarbageCollected<CXFA_DigestMethod>(
5928           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5929       break;
5930     case XFA_Element::InstanceManager:
5931       node = cppgc::MakeGarbageCollected<CXFA_InstanceManager>(
5932           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5933       break;
5934     case XFA_Element::EquateRange:
5935       node = cppgc::MakeGarbageCollected<CXFA_EquateRange>(
5936           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5937       break;
5938     case XFA_Element::Medium:
5939       node = cppgc::MakeGarbageCollected<CXFA_Medium>(
5940           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5941       break;
5942     case XFA_Element::TextEdit:
5943       node = cppgc::MakeGarbageCollected<CXFA_TextEdit>(
5944           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5945       break;
5946     case XFA_Element::TemplateCache:
5947       node = cppgc::MakeGarbageCollected<CXFA_TemplateCache>(
5948           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5949       break;
5950     case XFA_Element::CompressObjectStream:
5951       node = cppgc::MakeGarbageCollected<CXFA_CompressObjectStream>(
5952           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5953       break;
5954     case XFA_Element::DataValue:
5955       node = cppgc::MakeGarbageCollected<CXFA_DataValue>(
5956           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5957       break;
5958     case XFA_Element::AccessibleContent:
5959       node = cppgc::MakeGarbageCollected<CXFA_AccessibleContent>(
5960           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5961       break;
5962     case XFA_Element::IncludeXDPContent:
5963       node = cppgc::MakeGarbageCollected<CXFA_IncludeXDPContent>(
5964           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5965       break;
5966     case XFA_Element::XmlConnection:
5967       node = cppgc::MakeGarbageCollected<CXFA_XmlConnection>(
5968           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5969       break;
5970     case XFA_Element::ValidateApprovalSignatures:
5971       node = cppgc::MakeGarbageCollected<CXFA_ValidateApprovalSignatures>(
5972           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5973       break;
5974     case XFA_Element::SignData:
5975       node = cppgc::MakeGarbageCollected<CXFA_SignData>(
5976           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5977       break;
5978     case XFA_Element::Packets:
5979       node = cppgc::MakeGarbageCollected<CXFA_Packets>(
5980           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5981       break;
5982     case XFA_Element::DatePattern:
5983       node = cppgc::MakeGarbageCollected<CXFA_DatePattern>(
5984           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5985       break;
5986     case XFA_Element::DuplexOption:
5987       node = cppgc::MakeGarbageCollected<CXFA_DuplexOption>(
5988           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5989       break;
5990     case XFA_Element::Base:
5991       node = cppgc::MakeGarbageCollected<CXFA_Base>(
5992           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5993       break;
5994     case XFA_Element::Bind:
5995       node = cppgc::MakeGarbageCollected<CXFA_Bind>(
5996           doc->GetHeap()->GetAllocationHandle(), doc, packet);
5997       break;
5998     case XFA_Element::Compression:
5999       node = cppgc::MakeGarbageCollected<CXFA_Compression>(
6000           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6001       break;
6002     case XFA_Element::User:
6003       node = cppgc::MakeGarbageCollected<CXFA_User>(
6004           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6005       break;
6006     case XFA_Element::Rectangle:
6007       node = cppgc::MakeGarbageCollected<CXFA_Rectangle>(
6008           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6009       break;
6010     case XFA_Element::EffectiveOutputPolicy:
6011       node = cppgc::MakeGarbageCollected<CXFA_EffectiveOutputPolicy>(
6012           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6013       break;
6014     case XFA_Element::ADBE_JSDebugger:
6015       node = cppgc::MakeGarbageCollected<CXFA_ADBE_JSDebugger>(
6016           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6017       break;
6018     case XFA_Element::Acrobat7:
6019       node = cppgc::MakeGarbageCollected<CXFA_Acrobat7>(
6020           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6021       break;
6022     case XFA_Element::Interactive:
6023       node = cppgc::MakeGarbageCollected<CXFA_Interactive>(
6024           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6025       break;
6026     case XFA_Element::Locale:
6027       node = cppgc::MakeGarbageCollected<CXFA_Locale>(
6028           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6029       break;
6030     case XFA_Element::CurrentPage:
6031       node = cppgc::MakeGarbageCollected<CXFA_CurrentPage>(
6032           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6033       break;
6034     case XFA_Element::Data:
6035       node = cppgc::MakeGarbageCollected<CXFA_Data>(
6036           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6037       break;
6038     case XFA_Element::Date:
6039       node = cppgc::MakeGarbageCollected<CXFA_Date>(
6040           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6041       break;
6042     case XFA_Element::Desc:
6043       node = cppgc::MakeGarbageCollected<CXFA_Desc>(
6044           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6045       break;
6046     case XFA_Element::Encrypt:
6047       node = cppgc::MakeGarbageCollected<CXFA_Encrypt>(
6048           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6049       break;
6050     case XFA_Element::Draw:
6051       node = cppgc::MakeGarbageCollected<CXFA_Draw>(
6052           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6053       break;
6054     case XFA_Element::Encryption:
6055       node = cppgc::MakeGarbageCollected<CXFA_Encryption>(
6056           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6057       break;
6058     case XFA_Element::MeridiemNames:
6059       node = cppgc::MakeGarbageCollected<CXFA_MeridiemNames>(
6060           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6061       break;
6062     case XFA_Element::Messaging:
6063       node = cppgc::MakeGarbageCollected<CXFA_Messaging>(
6064           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6065       break;
6066     case XFA_Element::Speak:
6067       node = cppgc::MakeGarbageCollected<CXFA_Speak>(
6068           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6069       break;
6070     case XFA_Element::DataGroup:
6071       node = cppgc::MakeGarbageCollected<CXFA_DataGroup>(
6072           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6073       break;
6074     case XFA_Element::Common:
6075       node = cppgc::MakeGarbageCollected<CXFA_Common>(
6076           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6077       break;
6078     case XFA_Element::Sharptext:
6079       node = cppgc::MakeGarbageCollected<CXFA_Sharptext>(
6080           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6081       break;
6082     case XFA_Element::PaginationOverride:
6083       node = cppgc::MakeGarbageCollected<CXFA_PaginationOverride>(
6084           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6085       break;
6086     case XFA_Element::Reasons:
6087       node = cppgc::MakeGarbageCollected<CXFA_Reasons>(
6088           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6089       break;
6090     case XFA_Element::SignatureProperties:
6091       node = cppgc::MakeGarbageCollected<CXFA_SignatureProperties>(
6092           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6093       break;
6094     case XFA_Element::Threshold:
6095       node = cppgc::MakeGarbageCollected<CXFA_Threshold>(
6096           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6097       break;
6098     case XFA_Element::AppearanceFilter:
6099       node = cppgc::MakeGarbageCollected<CXFA_AppearanceFilter>(
6100           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6101       break;
6102     case XFA_Element::Fill:
6103       node = cppgc::MakeGarbageCollected<CXFA_Fill>(
6104           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6105       break;
6106     case XFA_Element::Font:
6107       node = cppgc::MakeGarbageCollected<CXFA_Font>(
6108           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6109       break;
6110     case XFA_Element::Form:
6111       node = cppgc::MakeGarbageCollected<CXFA_Form>(
6112           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6113       break;
6114     case XFA_Element::MediumInfo:
6115       node = cppgc::MakeGarbageCollected<CXFA_MediumInfo>(
6116           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6117       break;
6118     case XFA_Element::Certificate:
6119       node = cppgc::MakeGarbageCollected<CXFA_Certificate>(
6120           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6121       break;
6122     case XFA_Element::Password:
6123       node = cppgc::MakeGarbageCollected<CXFA_Password>(
6124           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6125       break;
6126     case XFA_Element::RunScripts:
6127       node = cppgc::MakeGarbageCollected<CXFA_RunScripts>(
6128           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6129       break;
6130     case XFA_Element::Trace:
6131       node = cppgc::MakeGarbageCollected<CXFA_Trace>(
6132           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6133       break;
6134     case XFA_Element::Float:
6135       node = cppgc::MakeGarbageCollected<CXFA_Float>(
6136           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6137       break;
6138     case XFA_Element::RenderPolicy:
6139       node = cppgc::MakeGarbageCollected<CXFA_RenderPolicy>(
6140           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6141       break;
6142     case XFA_Element::Destination:
6143       node = cppgc::MakeGarbageCollected<CXFA_Destination>(
6144           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6145       break;
6146     case XFA_Element::Value:
6147       node = cppgc::MakeGarbageCollected<CXFA_Value>(
6148           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6149       break;
6150     case XFA_Element::Bookend:
6151       node = cppgc::MakeGarbageCollected<CXFA_Bookend>(
6152           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6153       break;
6154     case XFA_Element::ExObject:
6155       node = cppgc::MakeGarbageCollected<CXFA_ExObject>(
6156           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6157       break;
6158     case XFA_Element::OpenAction:
6159       node = cppgc::MakeGarbageCollected<CXFA_OpenAction>(
6160           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6161       break;
6162     case XFA_Element::NeverEmbed:
6163       node = cppgc::MakeGarbageCollected<CXFA_NeverEmbed>(
6164           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6165       break;
6166     case XFA_Element::BindItems:
6167       node = cppgc::MakeGarbageCollected<CXFA_BindItems>(
6168           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6169       break;
6170     case XFA_Element::Calculate:
6171       node = cppgc::MakeGarbageCollected<CXFA_Calculate>(
6172           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6173       break;
6174     case XFA_Element::Print:
6175       node = cppgc::MakeGarbageCollected<CXFA_Print>(
6176           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6177       break;
6178     case XFA_Element::Extras:
6179       node = cppgc::MakeGarbageCollected<CXFA_Extras>(
6180           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6181       break;
6182     case XFA_Element::Proto:
6183       node = cppgc::MakeGarbageCollected<CXFA_Proto>(
6184           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6185       break;
6186     case XFA_Element::DSigData:
6187       node = cppgc::MakeGarbageCollected<CXFA_DSigData>(
6188           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6189       break;
6190     case XFA_Element::Creator:
6191       node = cppgc::MakeGarbageCollected<CXFA_Creator>(
6192           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6193       break;
6194     case XFA_Element::Connect:
6195       node = cppgc::MakeGarbageCollected<CXFA_Connect>(
6196           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6197       break;
6198     case XFA_Element::Permissions:
6199       node = cppgc::MakeGarbageCollected<CXFA_Permissions>(
6200           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6201       break;
6202     case XFA_Element::ConnectionSet:
6203       node = cppgc::MakeGarbageCollected<CXFA_ConnectionSet>(
6204           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6205       break;
6206     case XFA_Element::Submit:
6207       node = cppgc::MakeGarbageCollected<CXFA_Submit>(
6208           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6209       break;
6210     case XFA_Element::Range:
6211       node = cppgc::MakeGarbageCollected<CXFA_Range>(
6212           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6213       break;
6214     case XFA_Element::Linearized:
6215       node = cppgc::MakeGarbageCollected<CXFA_Linearized>(
6216           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6217       break;
6218     case XFA_Element::Packet:
6219       node = cppgc::MakeGarbageCollected<CXFA_Packet>(
6220           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6221       break;
6222     case XFA_Element::RootElement:
6223       node = cppgc::MakeGarbageCollected<CXFA_RootElement>(
6224           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6225       break;
6226     case XFA_Element::PlaintextMetadata:
6227       node = cppgc::MakeGarbageCollected<CXFA_PlaintextMetadata>(
6228           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6229       break;
6230     case XFA_Element::NumberSymbols:
6231       node = cppgc::MakeGarbageCollected<CXFA_NumberSymbols>(
6232           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6233       break;
6234     case XFA_Element::PrintHighQuality:
6235       node = cppgc::MakeGarbageCollected<CXFA_PrintHighQuality>(
6236           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6237       break;
6238     case XFA_Element::Driver:
6239       node = cppgc::MakeGarbageCollected<CXFA_Driver>(
6240           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6241       break;
6242     case XFA_Element::IncrementalLoad:
6243       node = cppgc::MakeGarbageCollected<CXFA_IncrementalLoad>(
6244           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6245       break;
6246     case XFA_Element::SubjectDN:
6247       node = cppgc::MakeGarbageCollected<CXFA_SubjectDN>(
6248           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6249       break;
6250     case XFA_Element::CompressLogicalStructure:
6251       node = cppgc::MakeGarbageCollected<CXFA_CompressLogicalStructure>(
6252           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6253       break;
6254     case XFA_Element::IncrementalMerge:
6255       node = cppgc::MakeGarbageCollected<CXFA_IncrementalMerge>(
6256           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6257       break;
6258     case XFA_Element::Radial:
6259       node = cppgc::MakeGarbageCollected<CXFA_Radial>(
6260           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6261       break;
6262     case XFA_Element::Variables:
6263       node = cppgc::MakeGarbageCollected<CXFA_Variables>(
6264           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6265       break;
6266     case XFA_Element::TimePatterns:
6267       node = cppgc::MakeGarbageCollected<CXFA_TimePatterns>(
6268           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6269       break;
6270     case XFA_Element::EffectiveInputPolicy:
6271       node = cppgc::MakeGarbageCollected<CXFA_EffectiveInputPolicy>(
6272           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6273       break;
6274     case XFA_Element::NameAttr:
6275       node = cppgc::MakeGarbageCollected<CXFA_NameAttr>(
6276           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6277       break;
6278     case XFA_Element::Conformance:
6279       node = cppgc::MakeGarbageCollected<CXFA_Conformance>(
6280           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6281       break;
6282     case XFA_Element::Transform:
6283       node = cppgc::MakeGarbageCollected<CXFA_Transform>(
6284           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6285       break;
6286     case XFA_Element::LockDocument:
6287       node = cppgc::MakeGarbageCollected<CXFA_LockDocument>(
6288           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6289       break;
6290     case XFA_Element::BreakAfter:
6291       node = cppgc::MakeGarbageCollected<CXFA_BreakAfter>(
6292           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6293       break;
6294     case XFA_Element::Line:
6295       node = cppgc::MakeGarbageCollected<CXFA_Line>(
6296           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6297       break;
6298     case XFA_Element::Source:
6299       node = cppgc::MakeGarbageCollected<CXFA_Source>(
6300           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6301       break;
6302     case XFA_Element::Occur:
6303       node = cppgc::MakeGarbageCollected<CXFA_Occur>(
6304           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6305       break;
6306     case XFA_Element::PickTrayByPDFSize:
6307       node = cppgc::MakeGarbageCollected<CXFA_PickTrayByPDFSize>(
6308           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6309       break;
6310     case XFA_Element::MonthNames:
6311       node = cppgc::MakeGarbageCollected<CXFA_MonthNames>(
6312           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6313       break;
6314     case XFA_Element::Severity:
6315       node = cppgc::MakeGarbageCollected<CXFA_Severity>(
6316           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6317       break;
6318     case XFA_Element::GroupParent:
6319       node = cppgc::MakeGarbageCollected<CXFA_GroupParent>(
6320           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6321       break;
6322     case XFA_Element::DocumentAssembly:
6323       node = cppgc::MakeGarbageCollected<CXFA_DocumentAssembly>(
6324           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6325       break;
6326     case XFA_Element::NumberSymbol:
6327       node = cppgc::MakeGarbageCollected<CXFA_NumberSymbol>(
6328           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6329       break;
6330     case XFA_Element::Tagged:
6331       node = cppgc::MakeGarbageCollected<CXFA_Tagged>(
6332           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6333       break;
6334     case XFA_Element::Items:
6335       node = cppgc::MakeGarbageCollected<CXFA_Items>(
6336           doc->GetHeap()->GetAllocationHandle(), doc, packet);
6337       break;
6338     case XFA_Element::DataWindow:
6339     case XFA_Element::Deltas:
6340     case XFA_Element::EventPseudoModel:
6341     case XFA_Element::HostPseudoModel:
6342     case XFA_Element::LayoutPseudoModel:
6343     case XFA_Element::List:
6344     case XFA_Element::ListDuplicate:
6345     case XFA_Element::LogPseudoModel:
6346     case XFA_Element::Model:
6347     case XFA_Element::Node:
6348     case XFA_Element::NodeWithDesc:
6349     case XFA_Element::NodeWithUse:
6350     case XFA_Element::NodeWithValue:
6351     case XFA_Element::Object:
6352     case XFA_Element::SignaturePseudoModel:
6353     case XFA_Element::Tree:
6354     case XFA_Element::TreeList:
6355     case XFA_Element::Unknown:
6356       // These defined elements can not be made from an XML parse. Some are
6357       // not CXFA_Node sub-classes, some are only used as intermediate classes,
6358       // and so forth.
6359       return nullptr;
6360   }
6361   if (!node || !node->IsValidInPacket(packet))
6362     return nullptr;
6363   return node;
6364 }
6365