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 ∝
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