Fix: Create form in parent document to POST to Collabora iframe
- Data URL iframe form submission was blocked by CORS - New approach: create iframe in viewport, form in document body - Form targets iframe by name, submits WOPISrc to loleaflet.html via POST - Form submission happens in parent document context, not sandboxed iframe - This avoids CORS issues and ensures form actually submits
This commit is contained in:
@@ -449,14 +449,18 @@ class _DocumentViewerModalState extends State<DocumentViewerModal> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCollaboraIframe(String wopisrc) {
|
Widget _buildCollaboraIframe(String wopisrc) {
|
||||||
// For Collabora Online, we need to POST the WOPISrc, not GET it
|
// For Collabora Online, POST the WOPISrc to loleaflet.html
|
||||||
// Create an HTML page with auto-submitting form and set as iframe src
|
// We'll create an iframe and submit a form to it from the page level
|
||||||
final String viewType =
|
final String viewType =
|
||||||
'collabora-form-${DateTime.now().millisecondsSinceEpoch}';
|
'collabora-viewer-${DateTime.now().millisecondsSinceEpoch}';
|
||||||
|
|
||||||
ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) {
|
ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) {
|
||||||
// Create the iframe
|
// Create a unique iframe name
|
||||||
|
final iframeName = 'collabora-$viewId';
|
||||||
|
|
||||||
|
// Create the iframe that will receive the form submission
|
||||||
final iframe = html.IFrameElement()
|
final iframe = html.IFrameElement()
|
||||||
|
..name = iframeName
|
||||||
..style.border = 'none'
|
..style.border = 'none'
|
||||||
..style.width = '100%'
|
..style.width = '100%'
|
||||||
..style.height = '100%'
|
..style.height = '100%'
|
||||||
@@ -468,34 +472,10 @@ class _DocumentViewerModalState extends State<DocumentViewerModal> {
|
|||||||
)
|
)
|
||||||
..setAttribute(
|
..setAttribute(
|
||||||
'sandbox',
|
'sandbox',
|
||||||
'allow-same-origin allow-scripts allow-popups allow-forms',
|
'allow-same-origin allow-scripts allow-popups allow-forms allow-pointer-lock allow-presentation allow-modals allow-downloads',
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create an HTML page with an auto-submitting form
|
// Create container
|
||||||
final htmlContent =
|
|
||||||
'''
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Loading...</title>
|
|
||||||
</head>
|
|
||||||
<body style="margin: 0; padding: 0;">
|
|
||||||
<form method="POST" action="https://of.b0esche.cloud/loleaflet/dist/loleaflet.html" style="display: none;">
|
|
||||||
<input type="hidden" name="WOPISrc" value="$wopisrc">
|
|
||||||
</form>
|
|
||||||
<script>
|
|
||||||
document.forms[0].submit();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
''';
|
|
||||||
|
|
||||||
// Set iframe src to a data URL with the form
|
|
||||||
final dataUrl =
|
|
||||||
'data:text/html;charset=utf-8,${Uri.encodeComponent(htmlContent)}';
|
|
||||||
iframe.src = dataUrl;
|
|
||||||
|
|
||||||
// Create a container
|
|
||||||
final container = html.DivElement()
|
final container = html.DivElement()
|
||||||
..style.width = '100%'
|
..style.width = '100%'
|
||||||
..style.height = '100%'
|
..style.height = '100%'
|
||||||
@@ -504,6 +484,46 @@ 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
|
||||||
|
// 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');
|
||||||
|
|
||||||
|
if (html.document.querySelector('#collabora-forms') == null) {
|
||||||
|
html.document.body!.append(formContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user