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