Fix: Use JavaScript form submission for Collabora POST request

- Collabora expects POST to loleaflet.html with WOPISrc in body, not GET
- Previous Dart form.submit() wasn't executing reliably
- Use ScriptElement to inject and execute form submission JavaScript
- This bypasses Dart's HTML layer limitations and ensures form POSTs properly
- Unique viewType names with timestamp to avoid registration conflicts
This commit is contained in:
Leon Bösche
2026-01-12 15:22:40 +01:00
parent ef60983534
commit 89f55471ce

View File

@@ -459,8 +459,8 @@ class _DocumentViewerModalState extends State<DocumentViewerModal> {
Widget _buildCollaboraIframe(String collaboraUrl) { Widget _buildCollaboraIframe(String collaboraUrl) {
// For Collabora Online, we need to POST the WOPISrc, not GET it // For Collabora Online, we need to POST the WOPISrc, not GET it
// Create an iframe and submit a form to load the document // Use JavaScript to create and submit the form properly
const String viewType = 'collabora-form'; final String viewType = 'collabora-form-${DateTime.now().millisecondsSinceEpoch}';
ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) { ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) {
// Extract the WOPISrc from the URL // Extract the WOPISrc from the URL
@@ -477,7 +477,7 @@ class _DocumentViewerModalState extends State<DocumentViewerModal> {
// Create the iframe first // Create the iframe first
final iframe = html.IFrameElement() final iframe = html.IFrameElement()
..name = 'collabora-iframe' ..name = 'collabora-iframe-$viewId'
..style.border = 'none' ..style.border = 'none'
..style.width = '100%' ..style.width = '100%'
..style.height = '100%' ..style.height = '100%'
@@ -494,26 +494,36 @@ class _DocumentViewerModalState extends State<DocumentViewerModal> {
container.append(iframe); container.append(iframe);
// Create a hidden form that will POST to Collabora // Use JavaScript to create and submit the form
final form = html.FormElement() // This is more reliable than Dart's form.submit()
..method = 'POST' final jsCode = '''
..action = 'https://of.b0esche.cloud/loleaflet/dist/loleaflet.html' (function() {
..target = 'collabora-iframe' var form = document.createElement('form');
..style.display = 'none'; form.method = 'POST';
form.action = 'https://of.b0esche.cloud/loleaflet/dist/loleaflet.html';
form.target = 'collabora-iframe-$viewId';
form.style.display = 'none';
// Add WOPISrc as a hidden input var input = document.createElement('input');
final wopisrcInput = html.InputElement() input.type = 'hidden';
..type = 'hidden' input.name = 'WOPISrc';
..name = 'WOPISrc' input.value = '$wopisrc';
..value = wopisrc;
form.append(wopisrcInput); form.appendChild(input);
container.append(form); document.body.appendChild(form);
// Use a timer to submit the form after the iframe is fully loaded // Submit the form
Future.delayed(const Duration(milliseconds: 100), () { setTimeout(function() {
form.submit(); form.submit();
}); }, 50);
})();
''';
final script = html.ScriptElement()
..type = 'text/javascript'
..text = jsCode;
html.document.body!.append(script);
return container; return container;
}); });