@eeacms/volto-cca-policy 0.1.13 → 0.1.15

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,19 @@ 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.15](https://github.com/eea/volto-cca-policy/compare/0.1.14...0.1.15) - 27 March 2023
8
+
9
+ #### :hammer_and_wrench: Others
10
+
11
+ - Retry build [Ghiță Bizău - [`d878ed0`](https://github.com/eea/volto-cca-policy/commit/d878ed0c91c7441f0f65a1caf6336de5272c9907)]
12
+ ### [0.1.14](https://github.com/eea/volto-cca-policy/compare/0.1.13...0.1.14) - 24 March 2023
13
+
14
+ #### :hammer_and_wrench: Others
15
+
16
+ - Update url for privacy in footer [Ghiță Bizău - [`18f2c9b`](https://github.com/eea/volto-cca-policy/commit/18f2c9b9e0f912d4851c5fcc9fbaf89a07476ce9)]
17
+ - Update links [kreafox - [`1cc68f2`](https://github.com/eea/volto-cca-policy/commit/1cc68f2093e0c8308afd8461f3fa6cbfe9e0aa36)]
18
+ - Refs #250307 - Add Privacy link in footer. [GhitaB - [`e2338c9`](https://github.com/eea/volto-cca-policy/commit/e2338c9289a9205f50fbfc626f2ccad79180d11b)]
19
+ - Add volto-slate customization [kreafox - [`d267f35`](https://github.com/eea/volto-cca-policy/commit/d267f351b8d76dca09748851ba9eb22d882efb69)]
7
20
  ### [0.1.13](https://github.com/eea/volto-cca-policy/compare/0.1.12...0.1.13) - 23 March 2023
8
21
 
9
22
  #### :hammer_and_wrench: Others
package/README.md CHANGED
@@ -83,3 +83,4 @@ don-template/blob/master/LICENSE.md) for details.
83
83
  ## Funding
84
84
 
85
85
  [European Environment Agency (EU)](http://eea.europa.eu)
86
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-cca-policy",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "@eeacms/volto-cca-policy: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -0,0 +1 @@
1
+ Customizations from this PR: https://github.com/plone/volto/pull/4583
@@ -0,0 +1,115 @@
1
+ import { v4 as uuid } from 'uuid';
2
+ import { Editor, Transforms } from 'slate';
3
+ import {
4
+ TABLE,
5
+ THEAD,
6
+ TBODY,
7
+ TFOOT,
8
+ TD,
9
+ TH,
10
+ TR,
11
+ } from '@plone/volto-slate/constants';
12
+
13
+ /**
14
+ * @param {Array} rows The array of rows that almost completely defines a
15
+ * `table`-typed block.
16
+ * @returns {Array} A tuple `[id, block]` where `id` is the new block's ID and
17
+ * the `block` is all the block's data.
18
+ */
19
+ export function syncCreateTableBlock(rows) {
20
+ const id = uuid();
21
+ const block = {
22
+ '@type': 'slateTable',
23
+ table: {
24
+ rows,
25
+ },
26
+ };
27
+ return [id, block];
28
+ }
29
+
30
+ /**
31
+ * @param {Editor} editor The Slate Editor from which to extract tables.
32
+ * @param {PathRef} pathRef Has the current value a `Path` so that the search is
33
+ * done just inside nodes in that `Path`.
34
+ * @returns Extracts tables from a Slate `Editor` into an array of detached
35
+ * `table` blocks.
36
+ */
37
+ export const extractTables = (editor, pathRef) => {
38
+ const tableNodes = Array.from(
39
+ Editor.nodes(editor, {
40
+ at: pathRef.current,
41
+ match: (node) => node.type === TABLE,
42
+ }),
43
+ );
44
+ const tables = tableNodes.map(([node]) => extractVoltoTable(node));
45
+
46
+ Transforms.removeNodes(editor, {
47
+ at: pathRef.current,
48
+ match: (node) => node.type === TABLE,
49
+ });
50
+
51
+ return tables.map((el) => syncCreateTableBlock(el));
52
+ };
53
+
54
+ extractTables.id = 'extractTables';
55
+
56
+ /**
57
+ * @param {Node[]} fragment A Slate document fragment.
58
+ * @returns {Array} An array of rows in the format requested by `table`
59
+ * blocks.
60
+ */
61
+ function collectRowsFrom(fragment) {
62
+ let rows = [];
63
+ fragment.children.forEach((y) => {
64
+ if (y.type === TR) {
65
+ let row = { key: uuid(), cells: [] };
66
+
67
+ y.children.forEach((z) => {
68
+ let val = JSON.parse(JSON.stringify(z.children));
69
+ if (z.type === TD) {
70
+ row.cells.push({
71
+ key: uuid(),
72
+ type: 'data',
73
+ value: val,
74
+ });
75
+ } else if (z.type === TH) {
76
+ row.cells.push({
77
+ key: uuid(),
78
+ type: 'header',
79
+ value: val,
80
+ });
81
+ }
82
+ });
83
+
84
+ rows.push(row);
85
+ }
86
+ });
87
+ return rows;
88
+ }
89
+
90
+ /**
91
+ * @param {HTMLElement} el The <table> element from which to extract rows.
92
+ * @returns {Array} A rows array that contains rows in the format required by
93
+ * `table` blocks.
94
+ */
95
+ function extractVoltoTable(el) {
96
+ let thead = [],
97
+ tfoot = [],
98
+ tbody = [];
99
+
100
+ el.children.forEach((fragment) => {
101
+ if (fragment.type === THEAD) {
102
+ // not supported by View fully, so prepend this to tbody below
103
+ thead = collectRowsFrom(fragment);
104
+ } else if (fragment.type === TBODY) {
105
+ tbody = collectRowsFrom(fragment);
106
+ } else if (fragment.type === TFOOT) {
107
+ // not supported by View fully, so append this to tbody below
108
+ tfoot = collectRowsFrom(fragment);
109
+ }
110
+ });
111
+
112
+ const rows = [...thead, ...tbody, ...tfoot];
113
+
114
+ return rows;
115
+ }
@@ -0,0 +1,69 @@
1
+ import TableBlockEdit from '@plone/volto-slate/blocks/Table/TableBlockEdit';
2
+ import TableBlockView from '@plone/volto-slate/blocks/Table/TableBlockView';
3
+ import { extractTables } from './deconstruct';
4
+ import { normalizeTable } from '@plone/volto-slate/blocks/Table/extensions/normalizeTable';
5
+ import { normalizeExternalData } from '@plone/volto-slate/blocks/Text/extensions';
6
+
7
+ import tableSVG from '@plone/volto/icons/table.svg';
8
+
9
+ /**
10
+ * @summary Called from Volto to configure new or existing Volto block types.
11
+ * @param {object} config The object received from Volto containing the
12
+ * configuration for all the blocks.
13
+ */
14
+ export default function install(config) {
15
+ config.settings.slate = {
16
+ ...config.settings.slate,
17
+ tableblockExtensions: [
18
+ // First here gets executed last
19
+ // withLists,
20
+ // withSplitBlocksOnBreak,
21
+ // withDeleteSelectionOnEnter,
22
+ // withDeserializers,
23
+ // breakList,
24
+ normalizeTable,
25
+ normalizeExternalData,
26
+ ],
27
+ };
28
+
29
+ const tableBlockConfig = {
30
+ id: 'table',
31
+ title: 'Table',
32
+ icon: tableSVG,
33
+ group: 'common',
34
+ view: TableBlockView,
35
+ edit: TableBlockEdit,
36
+ restricted: false,
37
+ mostUsed: false,
38
+ blockHasOwnFocusManagement: true,
39
+ sidebarTab: 1,
40
+ security: {
41
+ addPermission: [],
42
+ view: [],
43
+ },
44
+ // blockHasValue: (data) => {
45
+ // return true;
46
+ // },
47
+ };
48
+
49
+ config.blocks.blocksConfig.table.restricted = true;
50
+ config.blocks.blocksConfig.slateTable = {
51
+ ...tableBlockConfig,
52
+ id: 'slateTable',
53
+ };
54
+
55
+ const { voltoBlockEmiters = [] } = config.settings.slate;
56
+ const imageExtractor = voltoBlockEmiters.find(
57
+ (e) => e.id === 'extractImages',
58
+ );
59
+
60
+ // we want to extract the tables before the images, so that the images that
61
+ // that are inserted in the tables are not extracted as Volto image blocks
62
+ config.settings.slate.voltoBlockEmiters = [
63
+ ...voltoBlockEmiters.filter((e) => e.id !== 'extractImages'),
64
+ extractTables,
65
+ ...(imageExtractor ? [imageExtractor] : []),
66
+ ];
67
+
68
+ return config;
69
+ }
@@ -0,0 +1,164 @@
1
+ import React from 'react';
2
+ import redraft from 'redraft';
3
+ import TextBlockView from '@plone/volto-slate/blocks/Text/TextBlockView';
4
+ import TextBlockEdit from '@plone/volto-slate/blocks/Text/TextBlockEdit';
5
+ import TextBlockSchema from '@plone/volto-slate/blocks/Text/TextBlockSchema';
6
+
7
+ import {
8
+ goDown,
9
+ goUp,
10
+ backspaceInList,
11
+ indentListItems,
12
+ joinWithNextBlock,
13
+ joinWithPreviousBlock,
14
+ softBreak,
15
+ moveListItemDown,
16
+ moveListItemUp,
17
+ traverseBlocks,
18
+ unwrapEmptyString,
19
+ slashMenu,
20
+ cancelEsc,
21
+ } from '@plone/volto-slate/blocks/Text/keyboard';
22
+ import { withDeleteSelectionOnEnter } from '@plone/volto-slate/editor/extensions';
23
+ import {
24
+ breakList,
25
+ withDeserializers,
26
+ withLists,
27
+ withSplitBlocksOnBreak,
28
+ withIsSelected,
29
+ normalizeExternalData,
30
+ } from '@plone/volto-slate/blocks/Text/extensions';
31
+
32
+ import textSVG from '@plone/volto/icons/subtext.svg';
33
+
34
+ export { TextBlockView, TextBlockEdit, TextBlockSchema };
35
+
36
+ export default function installTextBlock(config) {
37
+ config.settings.slate = {
38
+ // TODO: should we inverse order? First here gets executed last
39
+ textblockExtensions: [
40
+ withLists,
41
+ withSplitBlocksOnBreak, // TODO: do we still need this one?
42
+ withDeleteSelectionOnEnter,
43
+ withDeserializers,
44
+ withIsSelected,
45
+ breakList,
46
+ normalizeExternalData,
47
+ ],
48
+
49
+ // Pluggable handlers for the onKeyDown event of <Editable />
50
+ // Order matters here. A handler can return `true` to stop executing any
51
+ // following handler
52
+ textblockKeyboardHandlers: {
53
+ Backspace: [
54
+ unwrapEmptyString,
55
+ backspaceInList, // Backspace in list item lifts node and breaks Volto blocks
56
+ joinWithPreviousBlock, // Backspace at beginning of block joins with previous block
57
+ ],
58
+ Delete: [
59
+ unwrapEmptyString,
60
+ joinWithNextBlock, // Delete at end of block joins with next block
61
+ ],
62
+ Enter: [
63
+ slashMenu,
64
+ unwrapEmptyString,
65
+ softBreak, // Handles shift+Enter as a newline (<br/>)
66
+ ],
67
+ ArrowUp: [
68
+ slashMenu,
69
+ moveListItemUp, // Move up a list with with Ctrl+up
70
+ goUp, // Select previous block
71
+ ],
72
+ ArrowDown: [
73
+ slashMenu,
74
+ moveListItemDown, // Move down a list item with Ctrl+down
75
+ goDown, // Select next block
76
+ ],
77
+ Tab: [
78
+ indentListItems, // <tab> and <c-tab> behaviour for list items
79
+ traverseBlocks,
80
+ ],
81
+ Escape: [cancelEsc],
82
+ },
83
+ textblockDetachedKeyboardHandlers: {
84
+ Enter: [
85
+ softBreak, // Handles shift+Enter as a newline (<br/>)
86
+ ],
87
+ },
88
+ // Used by deconstructToVoltoBlocks to transform tags such as <img> to a Volto image block
89
+ // These emiters receive (editor, pathRef), emit [blockid, blockoptions] and
90
+ // are allowed to change the editor contents (for the given path)
91
+ // voltoBlockEmiters: [
92
+ // ...(config.settings.slate.voltoBlockEmiters || []),
93
+ // ],
94
+
95
+ // These elements will get an id, to make them targets in TOC
96
+ topLevelTargetElements: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
97
+
98
+ ...config.settings.slate, // TODO: is this correct for volto-slate addons?
99
+ };
100
+
101
+ config.settings.integratesBlockStyles = [
102
+ ...(config.settings.integratesBlockStyles || []),
103
+ 'slate',
104
+ ];
105
+
106
+ const slateBlockConfig = {
107
+ id: 'slate',
108
+ title: 'Text',
109
+ icon: textSVG,
110
+ group: 'text',
111
+ view: TextBlockView,
112
+ edit: TextBlockEdit,
113
+ schema: TextBlockSchema,
114
+ restricted: false,
115
+ mostUsed: false,
116
+ blockHasOwnFocusManagement: true,
117
+ sidebarTab: 0,
118
+ security: {
119
+ addPermission: [],
120
+ view: [],
121
+ },
122
+ blockHasValue: (data) => {
123
+ // TODO: this should be handled better
124
+ return data && !!data.plaintext?.trim();
125
+ },
126
+ tocEntry: (block = {}) => {
127
+ const { value, override_toc, entry_text, level, plaintext } = block;
128
+ const type = value?.[0]?.type;
129
+ return override_toc && level
130
+ ? [parseInt(level.slice(1)), entry_text]
131
+ : config.settings.slate.topLevelTargetElements.includes(type)
132
+ ? [parseInt(type.slice(1)), plaintext]
133
+ : null;
134
+ },
135
+ };
136
+
137
+ // Make draft js compatible with ToC
138
+ config.blocks.blocksConfig.text = {
139
+ ...config.blocks.blocksConfig.text,
140
+ restricted: true,
141
+ tocEntry: (block = {}) => {
142
+ const draft = redraft(
143
+ block.text,
144
+ config.settings.richtextViewSettings.ToHTMLRenderers,
145
+ config.settings.richtextViewSettings.ToHTMLOptions,
146
+ );
147
+ const type = draft?.[0]?.[0]?.type;
148
+
149
+ return config.settings.slate.topLevelTargetElements.includes(type)
150
+ ? [parseInt(type.slice(1)), block.text.blocks[0].text]
151
+ : null;
152
+ },
153
+ };
154
+
155
+ config.blocks.blocksConfig.slate = slateBlockConfig;
156
+ config.blocks.blocksConfig.detachedSlate = {
157
+ ...config.blocks.blocksConfig.slate,
158
+ id: 'detachedSlate',
159
+ title: 'Detached Slate',
160
+ edit: (props) => <TextBlockEdit {...props} detached />,
161
+ restricted: true,
162
+ };
163
+ return config;
164
+ }