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