@eeacms/volto-cca-policy 0.1.54 → 0.1.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
### [0.1.55](https://github.com/eea/volto-cca-policy/compare/0.1.54...0.1.55) - 21 December 2023
|
|
8
|
+
|
|
7
9
|
### [0.1.54](https://github.com/eea/volto-cca-policy/compare/0.1.53...0.1.54) - 20 December 2023
|
|
8
10
|
|
|
9
11
|
#### :rocket: New Features
|
package/package.json
CHANGED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HtmlSlateWidget, a slate widget variant that saves its data as HTML
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import ReactDOMServer from 'react-dom/server';
|
|
7
|
+
import configureStore from 'redux-mock-store';
|
|
8
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
9
|
+
import { Provider, useSelector } from 'react-redux';
|
|
10
|
+
import { defineMessages, injectIntl } from 'react-intl';
|
|
11
|
+
|
|
12
|
+
import { FormFieldWrapper } from '@plone/volto/components';
|
|
13
|
+
import SlateEditor from '@plone/volto-slate/editor/SlateEditor';
|
|
14
|
+
import { serializeNodes } from '@plone/volto-slate/editor/render';
|
|
15
|
+
import { makeEditor } from '@plone/volto-slate/utils';
|
|
16
|
+
import deserialize from '@plone/volto-slate/editor/deserialize';
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
createEmptyParagraph,
|
|
20
|
+
normalizeExternalData,
|
|
21
|
+
} from '@plone/volto-slate/utils';
|
|
22
|
+
import { ErrorBoundary } from '@plone/volto-slate/widgets/ErrorBoundary';
|
|
23
|
+
|
|
24
|
+
import '@plone/volto-slate/widgets/style.css';
|
|
25
|
+
|
|
26
|
+
const messages = defineMessages({
|
|
27
|
+
error: {
|
|
28
|
+
id:
|
|
29
|
+
'An error has occurred while editing "{name}" field. We have been notified and we are looking into it. Please save your work and retry. If the issue persists please contact the site administrator.',
|
|
30
|
+
defaultMessage:
|
|
31
|
+
'An error has occurred while editing "{name}" field. We have been notified and we are looking into it. Please save your work and retry. If the issue persists please contact the site administrator.',
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const HtmlSlateWidget = (props) => {
|
|
36
|
+
const {
|
|
37
|
+
id,
|
|
38
|
+
onChange,
|
|
39
|
+
value,
|
|
40
|
+
focus,
|
|
41
|
+
className,
|
|
42
|
+
block,
|
|
43
|
+
placeholder,
|
|
44
|
+
properties,
|
|
45
|
+
intl,
|
|
46
|
+
} = props;
|
|
47
|
+
|
|
48
|
+
const [selected, setSelected] = React.useState(focus);
|
|
49
|
+
|
|
50
|
+
const editor = React.useMemo(() => makeEditor(), []);
|
|
51
|
+
|
|
52
|
+
const token = useSelector((state) => state.userSession.token);
|
|
53
|
+
|
|
54
|
+
const toHtml = React.useCallback(
|
|
55
|
+
(value) => {
|
|
56
|
+
const mockStore = configureStore();
|
|
57
|
+
const html = ReactDOMServer.renderToStaticMarkup(
|
|
58
|
+
<Provider store={mockStore({ userSession: { token } })}>
|
|
59
|
+
<MemoryRouter>{serializeNodes(value || [])}</MemoryRouter>
|
|
60
|
+
</Provider>,
|
|
61
|
+
);
|
|
62
|
+
// console.log('toHtml value', JSON.stringify(value));
|
|
63
|
+
// console.log('toHtml html', html);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
'content-type': value ? value['content-type'] : 'text/html',
|
|
67
|
+
encoding: value ? value.encoding : 'utf8',
|
|
68
|
+
data: html,
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
[token],
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const fromHtml = React.useCallback(
|
|
75
|
+
(value) => {
|
|
76
|
+
const html = value?.data || '';
|
|
77
|
+
|
|
78
|
+
const parsed = new DOMParser().parseFromString(html, 'text/html');
|
|
79
|
+
const body =
|
|
80
|
+
parsed.getElementsByTagName('google-sheets-html-origin').length > 0
|
|
81
|
+
? parsed.querySelector('google-sheets-html-origin > table')
|
|
82
|
+
: parsed.body;
|
|
83
|
+
let data = deserialize(editor, body, { collapseWhitespace: false });
|
|
84
|
+
if (data.length) {
|
|
85
|
+
data = normalizeExternalData(editor, data);
|
|
86
|
+
} else {
|
|
87
|
+
return [createEmptyParagraph()];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// editor.children = data;
|
|
91
|
+
// Editor.normalize(editor);
|
|
92
|
+
// TODO: need to add {text: ""} placeholders between elements
|
|
93
|
+
const res = data.length ? data : [createEmptyParagraph()];
|
|
94
|
+
// console.log('from html', { html: value?.data, res });
|
|
95
|
+
return res;
|
|
96
|
+
},
|
|
97
|
+
[editor],
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const valueFromHtml = React.useMemo(() => {
|
|
101
|
+
return fromHtml(value);
|
|
102
|
+
}, [value, fromHtml]);
|
|
103
|
+
|
|
104
|
+
const handleChange = React.useCallback(
|
|
105
|
+
(newValue) => {
|
|
106
|
+
onChange(id, toHtml(newValue));
|
|
107
|
+
},
|
|
108
|
+
[onChange, toHtml, id],
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
const handleClick = React.useCallback(() => {
|
|
112
|
+
setSelected(true);
|
|
113
|
+
}, []);
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<FormFieldWrapper {...props} draggable={false} className="slate_wysiwyg">
|
|
117
|
+
<div
|
|
118
|
+
className="slate_wysiwyg_box"
|
|
119
|
+
role="textbox"
|
|
120
|
+
tabIndex="-1"
|
|
121
|
+
style={{ boxSizing: 'initial' }}
|
|
122
|
+
onClick={handleClick}
|
|
123
|
+
onKeyDown={() => {}}
|
|
124
|
+
>
|
|
125
|
+
<ErrorBoundary name={intl.formatMessage(messages.error, { name: id })}>
|
|
126
|
+
<SlateEditor
|
|
127
|
+
className={className}
|
|
128
|
+
id={id}
|
|
129
|
+
name={id}
|
|
130
|
+
value={valueFromHtml}
|
|
131
|
+
onChange={handleChange}
|
|
132
|
+
block={block}
|
|
133
|
+
selected={selected}
|
|
134
|
+
properties={properties}
|
|
135
|
+
placeholder={placeholder}
|
|
136
|
+
/>
|
|
137
|
+
</ErrorBoundary>
|
|
138
|
+
</div>
|
|
139
|
+
</FormFieldWrapper>
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export default injectIntl(HtmlSlateWidget);
|