Skip to content

Commit

Permalink
Handle submit inputs and buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
liZe committed Jul 21, 2024
1 parent 1245d33 commit 2289170
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
4 changes: 2 additions & 2 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,10 +538,10 @@ def test_pdf_no_srgb():
('<input type="radio">',
['/Btn', '/V /Off', '/AS /Off', '/Ff 49152']),
('<input checked type="radio" name="foo" value="value">',
['/Btn', '/T (1)', '/V /dmFsdWU=', '/AS /dmFsdWU=']),
['/Btn', '/T (foo)', '/V /0', '/AS /0']),
('<form><input type="radio" name="foo" value="v0"></form>'
'<form><input checked type="radio" name="foo" value="v1"></form>',
['/Btn', '/AS /djE=', '/V /djE=', '/AS /Off', '/V /Off']),
['/Btn', '/AS /0', '/V /0', '/AS /Off', '/V /Off']),
('<textarea></textarea>', ['/Tx', '/V ()']),
('<select><option value="a">A</option></select>', ['/Ch', '/Opt']),
('<select>'
Expand Down
35 changes: 33 additions & 2 deletions weasyprint/pdf/anchors.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def add_forms(forms, matrix, pdf, page, resources, stream, font_map,
for element, style, rectangle in inputs
]
radio_groups = collections.defaultdict(dict)
forms = collections.defaultdict(dict)
for i, (form, element, style, rectangle) in enumerate(inputs_with_forms):
rectangle = (
*matrix.transform_point(*rectangle[:2]),
Expand All @@ -136,9 +137,10 @@ def add_forms(forms, matrix, pdf, page, resources, stream, font_map,
radio_groups[form][input_name] = group = pydyf.Dictionary({
'FT': '/Btn',
'Ff': (1 << (15 - 1)) + (1 << (16 - 1)), # NoToggle & Radio
'T': pydyf.String(f'{len(radio_groups)}'),
'T': pydyf.String(input_name),
'V': '/Off',
'Kids': pydyf.Array(),
'Opt': pydyf.Array(),
})
pdf.add_object(group)
pdf.catalog['AcroForm']['Fields'].append(group.reference)
Expand Down Expand Up @@ -172,7 +174,7 @@ def add_forms(forms, matrix, pdf, page, resources, stream, font_map,

checked = 'checked' in element.attrib
field_stream.set_font_size('ZaDb', font_size)
key = b64encode(input_value.encode(), altchars=b"+-").decode()
key = len(group['Kids']) if input_type == 'radio' else 'on'
field = pydyf.Dictionary({
'Type': '/Annot',
'Subtype': '/Widget',
Expand All @@ -192,6 +194,7 @@ def add_forms(forms, matrix, pdf, page, resources, stream, font_map,
if checked:
group['V'] = f'/{key}'
group['Kids'].append(field.reference)
group['Opt'].append(pydyf.String(input_value))
else:
field['T'] = pydyf.String(input_name)
field['V'] = field['AS']
Expand Down Expand Up @@ -233,6 +236,31 @@ def add_forms(forms, matrix, pdf, page, resources, stream, font_map,
selected_values[-1] if selected_values
else pydyf.String(''))
pdf.add_object(field)
elif input_type == 'submit' or element.tag == 'button':
flags = 1 << (3 - 1) # HTML form format
if form.attrib.get('method', '').lower() != 'post':
flags += 1 << (4 - 1) # GET method
field = pydyf.Dictionary({
'Type': '/Annot',
'Subtype': '/Widget',
'Rect': pydyf.Array(rectangle),
'FT': '/Btn',
'T': pydyf.String(input_name),
'F': 1 << (3 - 1), # Print flag
'Ff': 1 << (17 - 1), # Push-button
'P': page.reference,
'DA': pydyf.String(b' '.join(field_stream.stream)),
'V': pydyf.String(form.attrib.get('value', '')),
'A': pydyf.Dictionary({
'Type': '/Action',
'S': '/SubmitForm',
'F': pydyf.String(form.attrib.get('action')),
'Fields': pydyf.Array((
field.reference for field in forms[form].values())),
'Flags': flags,
}),
})
pdf.add_object(field)
else:
# Text, password, textarea, files, and unknown
font_description = get_font_description(style)
Expand Down Expand Up @@ -270,6 +298,9 @@ def add_forms(forms, matrix, pdf, page, resources, stream, font_map,

page['Annots'].append(field.reference)
pdf.catalog['AcroForm']['Fields'].append(field.reference)
if input_name not in forms:
forms[form][input_name] = field



def add_annotations(links, matrix, document, pdf, page, annot_files, compress):
Expand Down

0 comments on commit 2289170

Please sign in to comment.