You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-06 09:19:22 +02:00
Plugins: Allow retrieving form values from dialogs
This commit is contained in:
@@ -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<Size>({ 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}
|
||||
></StyledFrame>;
|
||||
}
|
||||
|
||||
export default forwardRef(UserWebview);
|
||||
|
||||
@@ -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) {
|
||||
<Dialog>
|
||||
<UserWebViewWrapper>
|
||||
<UserWebview
|
||||
ref={webviewRef}
|
||||
html={props.html}
|
||||
scripts={props.scripts}
|
||||
onMessage={props.onMessage}
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
# This is a convenient way to build and test a plugin demo.
|
||||
# It could be used to develop plugins too.
|
||||
|
||||
PLUGIN_PATH=/home/laurent/source/joplin/packages/app-cli/tests/support/plugins/content_script
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
PLUGIN_PATH="$SCRIPT_DIR/../app-cli/tests/support/plugins/dialog"
|
||||
npm i --prefix="$PLUGIN_PATH" && npm start -- --dev-plugins "$PLUGIN_PATH"
|
||||
Reference in New Issue
Block a user