Fix: Use JavaScript in head to submit form for Collabora POST

- Inject script element into head that creates and submits form
- Script executes immediately when loaded, doesn't rely on Future callbacks
- Form targets iframe by name, WOPISrc in body not query params
- This ensures form submission happens reliably before any async operations
This commit is contained in:
Leon Bösche
2026-01-12 15:58:08 +01:00
parent 2fa5f0441a
commit 2daa9e9855

View File

@@ -450,14 +450,12 @@ class _DocumentViewerModalState extends State<DocumentViewerModal> {
Widget _buildCollaboraIframe(String wopisrc) { Widget _buildCollaboraIframe(String wopisrc) {
// For Collabora Online, POST the WOPISrc to loleaflet.html // For Collabora Online, POST the WOPISrc to loleaflet.html
// We'll create an iframe and submit a form to it from the page level // Use JavaScript to submit the form reliably
final String viewType = final String viewType =
'collabora-viewer-${DateTime.now().millisecondsSinceEpoch}'; 'collabora-viewer-${DateTime.now().millisecondsSinceEpoch}';
final String iframeName = 'collabora-iframe-$viewType';
ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) { ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) {
// Create a unique iframe name
final iframeName = 'collabora-$viewId';
// Create the iframe that will receive the form submission // Create the iframe that will receive the form submission
final iframe = html.IFrameElement() final iframe = html.IFrameElement()
..name = iframeName ..name = iframeName
@@ -484,45 +482,32 @@ class _DocumentViewerModalState extends State<DocumentViewerModal> {
..style.overflow = 'hidden' ..style.overflow = 'hidden'
..append(iframe); ..append(iframe);
// Create form in the parent document that targets this iframe // Create JavaScript to submit the form
// We need to do this after the view is registered but before it's displayed final jsCode = '''
// So we use a setTimeout to ensure the DOM is ready (function() {
Future.delayed(Duration.zero, () { var form = document.createElement('form');
// Get or create a hidden form container in the document body form.method = 'POST';
final formContainer = html.document.querySelector('#collabora-forms') ?? form.action = 'https://of.b0esche.cloud/loleaflet/dist/loleaflet.html';
(html.DivElement() form.target = '$iframeName';
..id = 'collabora-forms' form.style.display = 'none';
..style.display = 'none'
..style.position = 'absolute'
..style.width = '0'
..style.height = '0'
..style.overflow = 'hidden');
if (html.document.querySelector('#collabora-forms') == null) { var input = document.createElement('input');
html.document.body!.append(formContainer); input.type = 'hidden';
} input.name = 'WOPISrc';
input.value = '$wopisrc';
// Create the form form.appendChild(input);
final form = html.FormElement() document.body.appendChild(form);
..id = 'form-$iframeName'
..method = 'POST'
..action = 'https://of.b0esche.cloud/loleaflet/dist/loleaflet.html'
..target = iframeName;
// Add WOPISrc input
final input = html.InputElement()
..type = 'hidden'
..name = 'WOPISrc'
..value = wopisrc;
form.append(input);
formContainer.append(form);
// Submit the form after a short delay to ensure everything is connected
Future.delayed(Duration(milliseconds: 100), () {
form.submit(); form.submit();
}); })();
}); ''';
// Create and execute script
final script = html.ScriptElement()
..type = 'text/javascript'
..text = jsCode;
html.document.head!.append(script);
return container; return container;
}); });