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