From 2daa9e98550b59795e8f74c6e42f4c7c5a623359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20B=C3=B6sche?= Date: Mon, 12 Jan 2026 15:58:08 +0100 Subject: [PATCH] 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 --- b0esche_cloud/lib/pages/document_viewer.dart | 67 ++++++++------------ 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/b0esche_cloud/lib/pages/document_viewer.dart b/b0esche_cloud/lib/pages/document_viewer.dart index 9059996..73616bd 100644 --- a/b0esche_cloud/lib/pages/document_viewer.dart +++ b/b0esche_cloud/lib/pages/document_viewer.dart @@ -450,14 +450,12 @@ class _DocumentViewerModalState extends State { Widget _buildCollaboraIframe(String wopisrc) { // 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 = 'collabora-viewer-${DateTime.now().millisecondsSinceEpoch}'; + final String iframeName = 'collabora-iframe-$viewType'; ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) { - // Create a unique iframe name - final iframeName = 'collabora-$viewId'; - // Create the iframe that will receive the form submission final iframe = html.IFrameElement() ..name = iframeName @@ -484,45 +482,32 @@ class _DocumentViewerModalState extends State { ..style.overflow = 'hidden' ..append(iframe); - // Create form in the parent document that targets this iframe - // We need to do this after the view is registered but before it's displayed - // So we use a setTimeout to ensure the DOM is ready - Future.delayed(Duration.zero, () { - // Get or create a hidden form container in the document body - final formContainer = html.document.querySelector('#collabora-forms') ?? - (html.DivElement() - ..id = 'collabora-forms' - ..style.display = 'none' - ..style.position = 'absolute' - ..style.width = '0' - ..style.height = '0' - ..style.overflow = 'hidden'); + // Create JavaScript to submit the form + final jsCode = ''' +(function() { + var form = document.createElement('form'); + form.method = 'POST'; + form.action = 'https://of.b0esche.cloud/loleaflet/dist/loleaflet.html'; + form.target = '$iframeName'; + form.style.display = 'none'; + + var input = document.createElement('input'); + input.type = 'hidden'; + input.name = 'WOPISrc'; + input.value = '$wopisrc'; + + form.appendChild(input); + document.body.appendChild(form); + form.submit(); +})(); + '''; - if (html.document.querySelector('#collabora-forms') == null) { - html.document.body!.append(formContainer); - } + // Create and execute script + final script = html.ScriptElement() + ..type = 'text/javascript' + ..text = jsCode; - // Create the form - final form = html.FormElement() - ..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(); - }); - }); + html.document.head!.append(script); return container; });