diff --git a/packages/app-cli/tests/support/plugins/dialog/src/index.ts b/packages/app-cli/tests/support/plugins/dialog/src/index.ts
index 6ee5b1db5..b1e6ed4a2 100644
--- a/packages/app-cli/tests/support/plugins/dialog/src/index.ts
+++ b/packages/app-cli/tests/support/plugins/dialog/src/index.ts
@@ -7,7 +7,7 @@ joplin.plugins.register({
const handle = await dialogs.create();
await dialogs.setHtml(handle, '
Testing dialog with default buttons
Second line
Third line
');
const result = await dialogs.open(handle);
- alert('This button was clicked: ' + result);
+ alert('Got result: ' + JSON.stringify(result));
const handle2 = await dialogs.create();
await dialogs.setHtml(handle2, 'Testing dialog with custom buttons
Second line
Third line
');
@@ -25,7 +25,20 @@ joplin.plugins.register({
]);
const result2 = await dialogs.open(handle2);
- alert('This button was clicked: ' + result2);
+ alert('Got result: ' + JSON.stringify(result2));
+ const handle3 = await dialogs.create();
+ await dialogs.setHtml(handle3, `
+ Testing dialog with form elements
+
+ `);
+
+ const result3 = await dialogs.open(handle3);
+ alert('Got result: ' + JSON.stringify(result3));
},
+
});
diff --git a/packages/app-desktop/services/plugins/UserWebview.tsx b/packages/app-desktop/services/plugins/UserWebview.tsx
index 6e23c518a..7f0c22891 100644
--- a/packages/app-desktop/services/plugins/UserWebview.tsx
+++ b/packages/app-desktop/services/plugins/UserWebview.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { useRef, useEffect, useState } from 'react';
+import { useRef, useEffect, useState, useImperativeHandle, forwardRef } from 'react';
import useViewIsReady from './hooks/useViewIsReady';
import useThemeCss from './hooks/useThemeCss';
const styled = require('styled-components').default;
@@ -32,7 +32,29 @@ const StyledFrame = styled.iframe`
border-bottom: ${(props: Props) => props.borderBottom ? `1px solid ${props.theme.dividerColor}` : 'none'};
`;
-export default function UserWebview(props: Props) {
+function serializeForm(form: any) {
+ const output: any = {};
+ const formData = new FormData(form);
+ for (const key of formData.keys()) {
+ output[key] = formData.get(key);
+ }
+ return output;
+}
+
+function serializeForms(document: any) {
+ const forms = document.getElementsByTagName('form');
+ const output: any = {};
+ let untitledIndex = 0;
+
+ for (const form of forms) {
+ const name = `${form.getAttribute('name')}` || (`form${untitledIndex++}`);
+ output[name] = serializeForm(form);
+ }
+
+ return output;
+}
+
+function UserWebview(props: Props, ref: any) {
const minWidth = props.minWidth ? props.minWidth : 200;
const minHeight = props.minHeight ? props.minHeight : 20;
@@ -41,6 +63,18 @@ export default function UserWebview(props: Props) {
const cssFilePath = useThemeCss({ pluginId: props.pluginId, themeId: props.themeId });
const [contentSize, setContentSize] = useState({ width: minWidth, height: minHeight });
+ useImperativeHandle(ref, () => {
+ return {
+ formData: function() {
+ if (viewRef.current) {
+ return serializeForms(viewRef.current.contentWindow.document);
+ } else {
+ return null;
+ }
+ },
+ };
+ });
+
function frameWindow() {
if (!viewRef.current) return null;
return viewRef.current.contentWindow;
@@ -143,3 +177,5 @@ export default function UserWebview(props: Props) {
borderBottom={props.borderBottom}
>;
}
+
+export default forwardRef(UserWebview);
diff --git a/packages/app-desktop/services/plugins/UserWebviewDialog.tsx b/packages/app-desktop/services/plugins/UserWebviewDialog.tsx
index c6882e6c3..00a07d44c 100644
--- a/packages/app-desktop/services/plugins/UserWebviewDialog.tsx
+++ b/packages/app-desktop/services/plugins/UserWebviewDialog.tsx
@@ -1,7 +1,8 @@
-import { ButtonSpec } from '@joplin/lib/services/plugins/api/types';
+import { ButtonSpec, DialogResult } from '@joplin/lib/services/plugins/api/types';
import PluginService from '@joplin/lib/services/plugins/PluginService';
import WebviewController from '@joplin/lib/services/plugins/WebviewController';
import * as React from 'react';
+import { useRef } from 'react';
import UserWebview, { Props as UserWebviewProps } from './UserWebview';
import UserWebviewDialogButtonBar from './UserWebviewDialogButtonBar';
const styled = require('styled-components').default;
@@ -49,6 +50,8 @@ function defaultButtons(): ButtonSpec[] {
}
export default function UserWebviewDialog(props: Props) {
+ const webviewRef = useRef(null);
+
function viewController(): WebviewController {
return PluginService.instance().pluginById(props.pluginId).viewController(props.viewId) as WebviewController;
}
@@ -57,7 +60,10 @@ export default function UserWebviewDialog(props: Props) {
return {
...b,
onClick: () => {
- viewController().closeWithResponse(b.id);
+ const response: DialogResult = { id: b.id };
+ const formData = webviewRef.current.formData();
+ if (formData && Object.keys(formData).length) response.formData = formData;
+ viewController().closeWithResponse(response);
},
};
});
@@ -67,6 +73,7 @@ export default function UserWebviewDialog(props: Props) {