@eeacms/volto-eea-website-theme 1.26.1 → 1.27.0

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,22 @@ 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
+ ### [1.27.0](https://github.com/eea/volto-eea-website-theme/compare/1.26.2...1.27.0) - 17 January 2024
8
+
9
+ #### :rocket: New Features
10
+
11
+ - feat: Put cloneData function for slate block, in order to change the uuids of fragments - refs #261770 [dobri1408 - [`069bffc`](https://github.com/eea/volto-eea-website-theme/commit/069bffcf114a886690408bbc2c2909c298b5e1aa)]
12
+
13
+ #### :bug: Bug Fixes
14
+
15
+ - fix: noreferrer on links - refs #263008 [ichim-david - [`d8f81e0`](https://github.com/eea/volto-eea-website-theme/commit/d8f81e01d9d2666e834ac92b2f34976f25156ea2)]
16
+ - fix: History diff page overlap - refs #262216 [dobri1408 - [`f580b16`](https://github.com/eea/volto-eea-website-theme/commit/f580b16f24faacb9318402699a1b616814840d63)]
17
+
18
+ #### :hammer_and_wrench: Others
19
+
20
+ - Release 1.27.0 [Alin Voinea - [`e7acf6d`](https://github.com/eea/volto-eea-website-theme/commit/e7acf6dd3332c090f75a6b1f63fc772912406ec0)]
21
+ ### [1.26.2](https://github.com/eea/volto-eea-website-theme/compare/1.26.1...1.26.2) - 4 January 2024
22
+
7
23
  ### [1.26.1](https://github.com/eea/volto-eea-website-theme/compare/1.26.0...1.26.1) - 14 December 2023
8
24
 
9
25
  #### :rocket: New Features
@@ -74,11 +90,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
74
90
  - test: Add real image to cypress test [Alin Voinea - [`4ff591a`](https://github.com/eea/volto-eea-website-theme/commit/4ff591ae3318c9588b4e2114582c0fa6cfdf31ae)]
75
91
  - test: Add cypress tests for Image block styling position and align [Alin Voinea - [`7341ef7`](https://github.com/eea/volto-eea-website-theme/commit/7341ef7b92714fc0cc3ab0c31c39033e7b3e19e7)]
76
92
  - Revert "change(tests): commented out rss test since title block config is missing" [Alin Voinea - [`fb61191`](https://github.com/eea/volto-eea-website-theme/commit/fb611918d6ca380b89b594f283dcf9f685a4b294)]
77
- - test: [JENKINS] Use java17 for sonarqube scanner [valentinab25 - [`6a3be30`](https://github.com/eea/volto-eea-website-theme/commit/6a3be3092589411af7808a235f76de5222fd3868)]
78
- - test: [JENKINS] Run cypress in started frontend container [valentinab25 - [`c3978f2`](https://github.com/eea/volto-eea-website-theme/commit/c3978f23375ef066e9fd6f6c2e34ba6c1c058f69)]
79
- - test: [JENKINS] Add cpu limit on cypress docker [valentinab25 - [`f672779`](https://github.com/eea/volto-eea-website-theme/commit/f672779e845bec9240ccc901e9f53ec80c5a1819)]
80
- - test: [JENKINS] Increase shm-size to cypress docker [valentinab25 - [`ae5d8e3`](https://github.com/eea/volto-eea-website-theme/commit/ae5d8e3f4e04dc2808d47ce2ee886e1b23b528da)]
81
- - test: [JENKINS] Improve cypress time [valentinab25 - [`170ff0c`](https://github.com/eea/volto-eea-website-theme/commit/170ff0c8e3b30e69479bdf1117e811fea94f1027)]
82
93
  ### [1.23.0](https://github.com/eea/volto-eea-website-theme/compare/1.22.1...1.23.0) - 2 November 2023
83
94
 
84
95
  #### :rocket: New Features
@@ -91,7 +102,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
91
102
 
92
103
  #### :house: Internal changes
93
104
 
94
- - chore: [JENKINS] Refactor automated testing [valentinab25 - [`f28fce3`](https://github.com/eea/volto-eea-website-theme/commit/f28fce3d1eb815f95fb9aa40de42b10b7e8e30c5)]
95
105
  - chore: husky, lint-staged use fixed versions [valentinab25 - [`6d15088`](https://github.com/eea/volto-eea-website-theme/commit/6d150886c5aeb2ca0b569270486e60f7cc274e2c)]
96
106
  - chore:volto 16 in tests, update docs, fix stylelint overrides [valentinab25 - [`20c0323`](https://github.com/eea/volto-eea-website-theme/commit/20c032380b33c0077c869a05136f93e2fb68e5d4)]
97
107
 
@@ -277,7 +287,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
277
287
 
278
288
  #### :house: Internal changes
279
289
 
280
- - chore: [JENKINS] Deprecate circularity website [valentinab25 - [`370dcbf`](https://github.com/eea/volto-eea-website-theme/commit/370dcbfbf1a8135ce7b1b3b271b004552a631837)]
281
290
 
282
291
  #### :hammer_and_wrench: Others
283
292
 
@@ -433,7 +442,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
433
442
 
434
443
  #### :hammer_and_wrench: Others
435
444
 
436
- - Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`6c5e2f8`](https://github.com/eea/volto-eea-website-theme/commit/6c5e2f80456e2061d9e9c15fd0a0b91b9ac70568)]
437
445
  ### [1.9.1](https://github.com/eea/volto-eea-website-theme/compare/1.9.0...1.9.1) - 28 February 2023
438
446
 
439
447
  #### :bug: Bug Fixes
@@ -580,7 +588,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
580
588
 
581
589
  - For some reasons types is a string [Alin Voinea - [`3769a09`](https://github.com/eea/volto-eea-website-theme/commit/3769a0981181d5b633f3498daebbe96be8b4b833)]
582
590
  - Fix(redirect): o.filter - refs #157627 [Alin Voinea - [`deb23da`](https://github.com/eea/volto-eea-website-theme/commit/deb23da846444cc96539697fd798429ae0abe89e)]
583
- - Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`f1fffc5`](https://github.com/eea/volto-eea-website-theme/commit/f1fffc5db96725440863d545580b4e76cce4b796)]
584
591
  ### [1.5.0](https://github.com/eea/volto-eea-website-theme/compare/1.4.2...1.5.0) - 9 January 2023
585
592
 
586
593
  #### :hammer_and_wrench: Others
@@ -614,7 +621,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
614
621
 
615
622
  - Release 1.4.0 [Alin Voinea - [`bd42a0d`](https://github.com/eea/volto-eea-website-theme/commit/bd42a0d26e928cac5d99933194755da3db06b341)]
616
623
  - bump version to use as volto-eea-design-system [David Ichim - [`f4be047`](https://github.com/eea/volto-eea-website-theme/commit/f4be047328b46399b03b612d378b18aaf82e7dc1)]
617
- - Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`9b7cfef`](https://github.com/eea/volto-eea-website-theme/commit/9b7cfefb4d34fc1c948015e491feb370f9795bd8)]
618
624
  - test(Jenkins): Run tests and cypress with latest canary @plone/volto [Alin Voinea - [`df252a9`](https://github.com/eea/volto-eea-website-theme/commit/df252a9bfed0bb86cadf53c59dd1603b1e2cd822)]
619
625
  ### [1.3.2](https://github.com/eea/volto-eea-website-theme/compare/1.3.1...1.3.2) - 16 December 2022
620
626
 
@@ -624,7 +630,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
624
630
 
625
631
  #### :hammer_and_wrench: Others
626
632
 
627
- - Add Sonarqube tag using cca-frontend addons list [EEA Jenkins - [`a43c658`](https://github.com/eea/volto-eea-website-theme/commit/a43c658a7920c8df95e763b9a637f38ce77eba2c)]
628
633
  - Better razzle.config [Tiberiu Ichim - [`81dbf48`](https://github.com/eea/volto-eea-website-theme/commit/81dbf48815fb27facb4f82c9b764540fdf188b2e)]
629
634
  - Better razzle.config [Tiberiu Ichim - [`7bc9da2`](https://github.com/eea/volto-eea-website-theme/commit/7bc9da2cd837ab62a95cd29979cdd9b0055b7d67)]
630
635
  ### [1.3.1](https://github.com/eea/volto-eea-website-theme/compare/1.3.0...1.3.1) - 28 November 2022
@@ -635,7 +640,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
635
640
 
636
641
  #### :hammer_and_wrench: Others
637
642
 
638
- - yarn 3 [Alin Voinea - [`ea7a709`](https://github.com/eea/volto-eea-website-theme/commit/ea7a7094945312776e9b6f44e371178603e92139)]
639
643
  ### [1.3.0](https://github.com/eea/volto-eea-website-theme/compare/1.2.0...1.3.0) - 22 November 2022
640
644
 
641
645
  #### :rocket: New Features
@@ -676,7 +680,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
676
680
  - Add subsite class to body [Tiberiu Ichim - [`74d700f`](https://github.com/eea/volto-eea-website-theme/commit/74d700fbfd6249a8604762a7e4e49cce857db0f3)]
677
681
  - Add subsite info to header [Tiberiu Ichim - [`47daf8b`](https://github.com/eea/volto-eea-website-theme/commit/47daf8bb6374a1222040626b19d4154df7ba1b83)]
678
682
  - fix eslint [Miu Razvan - [`eb8d0a7`](https://github.com/eea/volto-eea-website-theme/commit/eb8d0a790bc70c0aae256c6ff35f63c4885f338e)]
679
- - Add Sonarqube tag using circularity-frontend addons list [EEA Jenkins - [`cc578a4`](https://github.com/eea/volto-eea-website-theme/commit/cc578a413b205a8e61e091fab3a88f94cedefc89)]
680
683
  ### [1.1.0](https://github.com/eea/volto-eea-website-theme/compare/1.0.0...1.1.0) - 28 October 2022
681
684
 
682
685
  #### :nail_care: Enhancements
@@ -724,7 +727,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
724
727
 
725
728
  #### :hammer_and_wrench: Others
726
729
 
727
- - Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`33b56ac`](https://github.com/eea/volto-eea-website-theme/commit/33b56acb13fbaf0c5b79e8fc6e13c4b699c79c90)]
728
730
  ### [0.7.3](https://github.com/eea/volto-eea-website-theme/compare/0.7.2...0.7.3) - 22 September 2022
729
731
 
730
732
  #### :hammer_and_wrench: Others
@@ -992,7 +994,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
992
994
  - Header refactor, add custom logo #5 [ichim-david - [`4950235`](https://github.com/eea/volto-eea-website-theme/commit/49502358105437cfeac3b144e6d301cb59aa2346)]
993
995
  - Update footer.config with new publication card component [ichim-david - [`2e38e9a`](https://github.com/eea/volto-eea-website-theme/commit/2e38e9a417f835009d60c80d4eb4b30229f55e45)]
994
996
  - feature(breadcrumbs): implement eea-design-system breadcrumb as Volto component #32 #7 [ichim-david - [`181af41`](https://github.com/eea/volto-eea-website-theme/commit/181af4125ce2b9ddac56dab4723cb11c26633221)]
995
- - Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`da8ceb6`](https://github.com/eea/volto-eea-website-theme/commit/da8ceb68ea68bfbc9504e48ccd4d68277f11ab9a)]
996
997
  - use breadcrumbs from eea-design-system [nileshgulia1 - [`db2f9e9`](https://github.com/eea/volto-eea-website-theme/commit/db2f9e9a4327420a3cce9a9903cd88549b129eab)]
997
998
  - Update theme.config [ichim-david - [`8eca4f4`](https://github.com/eea/volto-eea-website-theme/commit/8eca4f40397a4aeca6d39029c92db78968d37064)]
998
999
  - Added keyContent component to theme.config [ichim-david - [`d86f202`](https://github.com/eea/volto-eea-website-theme/commit/d86f202d0274d839487a88b51cae9a0e899beb23)]
@@ -1034,5 +1035,4 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
1034
1035
 
1035
1036
  #### :hammer_and_wrench: Others
1036
1037
 
1037
- - yarn bootstrap [Alin Voinea - [`6995e9e`](https://github.com/eea/volto-eea-website-theme/commit/6995e9e091f21fdbbdffa8a44fc0e2c626f6d46a)]
1038
1038
  - Initial commit [Alin Voinea - [`6a9c03a`](https://github.com/eea/volto-eea-website-theme/commit/6a9c03a7cebe71ca87e82cf58c42904063e9d8d3)]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-eea-website-theme",
3
- "version": "1.26.1",
3
+ "version": "1.27.0",
4
4
  "description": "@eeacms/volto-eea-website-theme: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -6,6 +6,6 @@ export default function BaseTag(props) {
6
6
  const baseHref = contentId ? flattenToAppURL(contentId) : null;
7
7
 
8
8
  return baseHref !== null ? (
9
- <Helmet base={{ target: '_blank', href: `${baseHref}/` }} />
9
+ <Helmet base={{ target: '_self', href: `${baseHref}/` }} />
10
10
  ) : null;
11
11
  }
@@ -0,0 +1,351 @@
1
+ /**
2
+ * Diff field component.
3
+ * @module components/manage/Diff/DiffField
4
+ */
5
+
6
+ import React from 'react';
7
+ // import { diffWords as dWords } from 'diff';
8
+ import { join, map } from 'lodash';
9
+ import PropTypes from 'prop-types';
10
+ import { Grid } from 'semantic-ui-react';
11
+ import ReactDOMServer from 'react-dom/server';
12
+ import { Provider } from 'react-intl-redux';
13
+ import { createBrowserHistory } from 'history';
14
+ import { ConnectedRouter } from 'connected-react-router';
15
+ import { useSelector } from 'react-redux';
16
+
17
+ import { Api } from '@plone/volto/helpers';
18
+ import configureStore from '@plone/volto/store';
19
+ import { DefaultView } from '@plone/volto/components/';
20
+ import { serializeNodes } from '@plone/volto-slate/editor/render';
21
+
22
+ import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
23
+
24
+ /**
25
+ * Enhanced diff words utility
26
+ * @function diffWords
27
+ * @param oneStr Field one
28
+ * @param twoStr Field two
29
+ */
30
+
31
+ /**
32
+ * Diff field component.
33
+ * @function DiffField
34
+ * @param {*} one Field one
35
+ * @param {*} two Field two
36
+ * @param {Object} schema Field schema
37
+ * @returns {string} Markup of the component.
38
+ */
39
+ const DiffField = ({
40
+ one,
41
+ two,
42
+ contentOne,
43
+ contentTwo,
44
+ view,
45
+ schema,
46
+ diffLib,
47
+ }) => {
48
+ const language = useSelector((state) => state.intl.locale);
49
+ const readable_date_format = {
50
+ dateStyle: 'full',
51
+ timeStyle: 'short',
52
+ };
53
+ const splitWords = (str) => {
54
+ if (!str) return [];
55
+ const splitedArray = [];
56
+ let elementCurent = '';
57
+ let insideTag = false;
58
+ for (let i = 0; i < str.length; i++)
59
+ if (str[i] === '<') {
60
+ if (elementCurent) splitedArray.push(elementCurent);
61
+ elementCurent = '<';
62
+ insideTag = true;
63
+ } else if (str[i] === '>') {
64
+ elementCurent += '>';
65
+ splitedArray.push(elementCurent);
66
+ elementCurent = '';
67
+ insideTag = false;
68
+ } else if (str[i] === ' ' && insideTag === false) {
69
+ elementCurent += ' ';
70
+ splitedArray.push(elementCurent);
71
+ elementCurent = '';
72
+ } else elementCurent += str[i];
73
+ if (elementCurent) splitedArray.push(elementCurent);
74
+ return splitedArray;
75
+ };
76
+
77
+ const diffWords = (oneStr, twoStr) => {
78
+ return diffLib.diffArrays(splitWords(oneStr), splitWords(twoStr));
79
+ };
80
+
81
+ let parts, oneArray, twoArray;
82
+ if (schema.widget && schema.title !== 'Data sources and providers') {
83
+ switch (schema.widget) {
84
+ case 'richtext':
85
+ parts = diffWords(one?.data, two?.data);
86
+ break;
87
+ case 'datetime':
88
+ parts = diffWords(
89
+ new Intl.DateTimeFormat(language, readable_date_format)
90
+ .format(new Date(one))
91
+ .replace('\u202F', ' '),
92
+ new Intl.DateTimeFormat(language, readable_date_format)
93
+ .format(new Date(two))
94
+ .replace('\u202F', ' '),
95
+ );
96
+ break;
97
+ case 'json': {
98
+ const api = new Api();
99
+ const history = createBrowserHistory();
100
+ const store = configureStore(window.__data, history, api);
101
+ parts = diffWords(
102
+ ReactDOMServer.renderToStaticMarkup(
103
+ <Provider store={store}>
104
+ <ConnectedRouter history={history}>
105
+ <DefaultView content={contentOne} />
106
+ </ConnectedRouter>
107
+ </Provider>,
108
+ ),
109
+ ReactDOMServer.renderToStaticMarkup(
110
+ <Provider store={store}>
111
+ <ConnectedRouter history={history}>
112
+ <DefaultView content={contentTwo} />
113
+ </ConnectedRouter>
114
+ </Provider>,
115
+ ),
116
+ );
117
+ break;
118
+ }
119
+ case 'slate': {
120
+ const api = new Api();
121
+ const history = createBrowserHistory();
122
+ const store = configureStore(window.__data, history, api);
123
+ parts = diffWords(
124
+ ReactDOMServer.renderToStaticMarkup(
125
+ <Provider store={store}>
126
+ <ConnectedRouter history={history}>
127
+ {serializeNodes(one)}
128
+ </ConnectedRouter>
129
+ </Provider>,
130
+ ),
131
+ ReactDOMServer.renderToStaticMarkup(
132
+ <Provider store={store}>
133
+ <ConnectedRouter history={history}>
134
+ {serializeNodes(two)}
135
+ </ConnectedRouter>
136
+ </Provider>,
137
+ ),
138
+ );
139
+ break;
140
+ }
141
+ case 'temporal': {
142
+ if (one?.temporal?.length > 0 && two.temporal?.length > 0) {
143
+ let firstString = one.temporal.reduce((acc, cur) => {
144
+ return acc + cur?.label + ', ';
145
+ }, '');
146
+ firstString = firstString.substring(0, firstString.length - 2);
147
+ let secondString = two.temporal.reduce((acc, cur) => {
148
+ return acc + cur?.label + ', ';
149
+ }, '');
150
+ secondString = secondString.substring(0, secondString.length - 2);
151
+ parts = diffWords(firstString, secondString);
152
+ }
153
+ break;
154
+ }
155
+ case 'geolocation': {
156
+ if (one?.geolocation?.length > 0 && two.geolocation?.length > 0) {
157
+ let firstString = one.geolocation.reduce((acc, cur) => {
158
+ return acc + cur?.label + ', ';
159
+ }, '');
160
+ firstString = firstString.substring(0, firstString.length - 2);
161
+ let secondString = two.geolocation.reduce((acc, cur) => {
162
+ return acc + cur?.label + ', ';
163
+ }, '');
164
+ secondString = secondString.substring(0, secondString.length - 2);
165
+ parts = diffWords(firstString, secondString);
166
+ }
167
+ break;
168
+ }
169
+ case 'textarea':
170
+ default:
171
+ parts = diffWords(one, two);
172
+ break;
173
+ }
174
+ } else if (schema.title === 'Data sources and providers') {
175
+ if (one?.data?.length > 0 && two.data?.length > 0) {
176
+ let firstString = one.data.reduce((acc, cur) => {
177
+ return acc + cur?.title + ', ' + cur?.organisation + '<br/>';
178
+ }, '');
179
+ firstString = firstString.substring(0, firstString.length - 2);
180
+ let secondString = two.data.reduce((acc, cur) => {
181
+ return acc + cur?.title + ', ' + cur?.organisation + '<br/>';
182
+ }, '');
183
+ secondString = secondString.substring(0, secondString.length - 2);
184
+ parts = diffWords(firstString, secondString);
185
+ }
186
+ } else if (schema.type === 'object') {
187
+ parts = diffWords(one?.filename || one, two?.filename || two);
188
+ } else if (schema.type === 'array') {
189
+ oneArray = (one || []).map((i) => i?.title || i);
190
+ twoArray = (two || []).map((j) => j?.title || j);
191
+ parts = diffWords(oneArray, twoArray);
192
+ } else {
193
+ parts = diffWords(one?.title || one, two?.title || two);
194
+ }
195
+
196
+ return (
197
+ <Grid data-testid="DiffField">
198
+ <Grid.Row>
199
+ <Grid.Column width={12}>{schema.title}</Grid.Column>
200
+ </Grid.Row>
201
+
202
+ {view === 'split' && (
203
+ <Grid.Row>
204
+ <Grid.Column width={6} verticalAlign="top">
205
+ <span
206
+ dangerouslySetInnerHTML={{
207
+ __html: join(
208
+ map(parts, (part) => {
209
+ let combined = (part.value || []).reduce((acc, value) => {
210
+ if (
211
+ part.removed &&
212
+ !value.includes('<') &&
213
+ !value.includes('>') &&
214
+ !value.includes('>') &&
215
+ !value.includes('</') &&
216
+ !value.includes('"') &&
217
+ !value.includes('src') &&
218
+ !value.includes('href') &&
219
+ !value.includes('=')
220
+ )
221
+ return acc + `<span class="deletion">${value}</span>`;
222
+ if (
223
+ part.added &&
224
+ !value.includes('<') &&
225
+ !value.includes('>') &&
226
+ !value.includes('>') &&
227
+ !value.includes('</') &&
228
+ !value.includes('"') &&
229
+ !value.includes('src') &&
230
+ !value.includes('href') &&
231
+ !value.includes('=')
232
+ )
233
+ return acc;
234
+ return acc + value;
235
+ }, '');
236
+ return combined;
237
+ }),
238
+ '',
239
+ ),
240
+ }}
241
+ />
242
+ </Grid.Column>
243
+ <Grid.Column width={6} verticalAlign="top">
244
+ <span
245
+ dangerouslySetInnerHTML={{
246
+ __html: join(
247
+ map(parts, (part) => {
248
+ let combined = (part.value || []).reduce((acc, value) => {
249
+ if (
250
+ part.added &&
251
+ !value.includes('<') &&
252
+ !value.includes('>') &&
253
+ !value.includes('>') &&
254
+ !value.includes('</') &&
255
+ !value.includes('"') &&
256
+ !value.includes('src') &&
257
+ !value.includes('href') &&
258
+ !value.includes('=')
259
+ )
260
+ return acc + `<span class="addition">${value}</span>`;
261
+ if (
262
+ part.removed &&
263
+ !value.includes('<') &&
264
+ !value.includes('>') &&
265
+ !value.includes('>') &&
266
+ !value.includes('</') &&
267
+ !value.includes('"') &&
268
+ !value.includes('src') &&
269
+ !value.includes('href') &&
270
+ !value.includes('=')
271
+ )
272
+ return acc;
273
+ return acc + value;
274
+ }, '');
275
+ return combined;
276
+ }),
277
+ '',
278
+ ),
279
+ }}
280
+ />
281
+ </Grid.Column>
282
+ </Grid.Row>
283
+ )}
284
+ {view === 'unified' && (
285
+ <Grid.Row>
286
+ <Grid.Column width={16} verticalAlign="top">
287
+ <span
288
+ dangerouslySetInnerHTML={{
289
+ __html: join(
290
+ map(parts, (part) => {
291
+ let combined = (part.value || []).reduce((acc, value) => {
292
+ if (
293
+ part.removed &&
294
+ !value.includes('<') &&
295
+ !value.includes('>') &&
296
+ !value.includes('>') &&
297
+ !value.includes('</') &&
298
+ !value.includes('"') &&
299
+ !value.includes('src') &&
300
+ !value.includes('href') &&
301
+ !value.includes('=')
302
+ )
303
+ return acc + `<span class="deletion">${value}</span>`;
304
+
305
+ if (
306
+ part.added &&
307
+ !value.includes('<') &&
308
+ !value.includes('>') &&
309
+ !value.includes('>') &&
310
+ !value.includes('</') &&
311
+ !value.includes('"') &&
312
+ !value.includes('src') &&
313
+ !value.includes('href') &&
314
+ !value.includes('=')
315
+ )
316
+ return acc + `<span class="addition">${value}</span>`;
317
+
318
+ return acc + value;
319
+ }, '');
320
+ return combined;
321
+ }),
322
+ '',
323
+ ),
324
+ }}
325
+ />
326
+ </Grid.Column>
327
+ </Grid.Row>
328
+ )}
329
+ </Grid>
330
+ );
331
+ };
332
+
333
+ /**
334
+ * Property types.
335
+ * @property {Object} propTypes Property types.
336
+ * @static
337
+ */
338
+ DiffField.propTypes = {
339
+ one: PropTypes.any.isRequired,
340
+ two: PropTypes.any.isRequired,
341
+ contentOne: PropTypes.any,
342
+ contentTwo: PropTypes.any,
343
+ view: PropTypes.string.isRequired,
344
+ schema: PropTypes.shape({
345
+ widget: PropTypes.string,
346
+ type: PropTypes.string,
347
+ title: PropTypes.string,
348
+ }).isRequired,
349
+ };
350
+
351
+ export default injectLazyLibs('diffLib')(DiffField);
@@ -0,0 +1,154 @@
1
+ /*
2
+ * UniversalLink
3
+ * @module components/UniversalLink
4
+ * Removed noreferrer from rel attribute
5
+ */
6
+
7
+ import React from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { HashLink as Link } from 'react-router-hash-link';
10
+ import { useSelector } from 'react-redux';
11
+ import {
12
+ flattenToAppURL,
13
+ isInternalURL,
14
+ URLUtils,
15
+ } from '@plone/volto/helpers/Url/Url';
16
+
17
+ import config from '@plone/volto/registry';
18
+
19
+ const UniversalLink = ({
20
+ href,
21
+ item = null,
22
+ openLinkInNewTab,
23
+ download = false,
24
+ children,
25
+ className = null,
26
+ title = null,
27
+ ...props
28
+ }) => {
29
+ const token = useSelector((state) => state.userSession?.token);
30
+
31
+ let url = href;
32
+ if (!href && item) {
33
+ if (!item['@id']) {
34
+ // eslint-disable-next-line no-console
35
+ console.error(
36
+ 'Invalid item passed to UniversalLink',
37
+ item,
38
+ props,
39
+ children,
40
+ );
41
+ url = '#';
42
+ } else {
43
+ //case: generic item
44
+ url = flattenToAppURL(item['@id']);
45
+
46
+ //case: item like a Link
47
+ let remoteUrl = item.remoteUrl || item.getRemoteUrl;
48
+ if (!token && remoteUrl) {
49
+ url = remoteUrl;
50
+ }
51
+
52
+ //case: item of type 'File'
53
+ if (
54
+ !token &&
55
+ config.settings.downloadableObjects.includes(item['@type'])
56
+ ) {
57
+ url = `${url}/@@download/file`;
58
+ }
59
+
60
+ if (
61
+ !token &&
62
+ config.settings.viewableInBrowserObjects.includes(item['@type'])
63
+ ) {
64
+ url = `${url}/@@display-file/file`;
65
+ }
66
+ }
67
+ }
68
+
69
+ const isExternal = !isInternalURL(url);
70
+
71
+ const isDownload = (!isExternal && url.includes('@@download')) || download;
72
+ const isDisplayFile =
73
+ (!isExternal && url.includes('@@display-file')) || false;
74
+
75
+ const checkedURL = URLUtils.checkAndNormalizeUrl(url);
76
+
77
+ url = checkedURL.url;
78
+ let tag = (
79
+ <Link
80
+ to={flattenToAppURL(url)}
81
+ target={openLinkInNewTab ?? false ? '_blank' : null}
82
+ title={title}
83
+ className={className}
84
+ smooth={config.settings.hashLinkSmoothScroll}
85
+ {...props}
86
+ >
87
+ {children}
88
+ </Link>
89
+ );
90
+
91
+ if (isExternal) {
92
+ tag = (
93
+ <a
94
+ href={url}
95
+ title={title}
96
+ target={
97
+ !checkedURL.isMail &&
98
+ !checkedURL.isTelephone &&
99
+ !(openLinkInNewTab === false)
100
+ ? '_blank'
101
+ : null
102
+ }
103
+ rel="noopener"
104
+ className={className}
105
+ {...props}
106
+ >
107
+ {children}
108
+ </a>
109
+ );
110
+ } else if (isDownload) {
111
+ tag = (
112
+ <a
113
+ href={flattenToAppURL(url)}
114
+ download
115
+ title={title}
116
+ className={className}
117
+ {...props}
118
+ >
119
+ {children}
120
+ </a>
121
+ );
122
+ } else if (isDisplayFile) {
123
+ tag = (
124
+ <a
125
+ href={flattenToAppURL(url)}
126
+ title={title}
127
+ rel="noopener"
128
+ className={className}
129
+ {...props}
130
+ >
131
+ {children}
132
+ </a>
133
+ );
134
+ }
135
+ return tag;
136
+ };
137
+
138
+ UniversalLink.propTypes = {
139
+ href: PropTypes.string,
140
+ openLinkInNewTab: PropTypes.bool,
141
+ download: PropTypes.bool,
142
+ className: PropTypes.string,
143
+ title: PropTypes.string,
144
+ item: PropTypes.shape({
145
+ '@id': PropTypes.string.isRequired,
146
+ remoteUrl: PropTypes.string, //of plone @type 'Link'
147
+ }),
148
+ children: PropTypes.oneOfType([
149
+ PropTypes.arrayOf(PropTypes.node),
150
+ PropTypes.node,
151
+ ]),
152
+ };
153
+
154
+ export default UniversalLink;
@@ -0,0 +1,27 @@
1
+ //this should be deleted when upgraded to a volto version that supports App Extras exceptions
2
+ import React from 'react';
3
+ import { matchPath } from 'react-router';
4
+ import config from '@plone/volto/registry';
5
+
6
+ const AppExtras = (props) => {
7
+ const { settings } = config;
8
+ const { appExtras = [] } = settings;
9
+ const { pathname } = props;
10
+ const active = appExtras
11
+ .map((reg) => {
12
+ const excluded = matchPath(pathname, reg.exclude);
13
+ if (excluded) return null;
14
+ const match = matchPath(pathname, reg.match);
15
+ return match ? { reg, match } : null;
16
+ })
17
+ .filter((reg) => reg);
18
+
19
+ return active.map(({ reg: { component, props: extraProps }, match }, i) => {
20
+ const Insert = component;
21
+ return (
22
+ <Insert key={`appextra-${i}`} match={match} {...props} {...extraProps} />
23
+ );
24
+ });
25
+ };
26
+
27
+ export default AppExtras;
package/src/index.js CHANGED
@@ -29,6 +29,9 @@ import installSlate from './slate';
29
29
  import installReducers from './reducers';
30
30
  import installMiddlewares from './middleware';
31
31
 
32
+ import { nanoid } from '@plone/volto-slate/utils';
33
+ import { v4 as uuid } from 'uuid';
34
+
32
35
  import * as eea from './config';
33
36
  import React from 'react';
34
37
 
@@ -98,6 +101,7 @@ function tabVariationCustomization(tabs_block_variations, config) {
98
101
  };
99
102
  return schema;
100
103
  };
104
+
101
105
  const oldDefaultSchemaEnhancer = defaultVariation.schemaEnhancer;
102
106
  defaultVariation.schemaEnhancer = (props) => {
103
107
  const newSchema = oldDefaultSchemaEnhancer(props);
@@ -110,7 +114,6 @@ function tabVariationCustomization(tabs_block_variations, config) {
110
114
  ];
111
115
  return newSchema;
112
116
  };
113
-
114
117
  const oldHorizontalSchemaEnhancer = horizontalVariation.schemaEnhancer;
115
118
  horizontalVariation.schemaEnhancer = (props) => {
116
119
  const newSchema = oldHorizontalSchemaEnhancer(props);
@@ -139,6 +142,40 @@ const applyConfig = (config) => {
139
142
  if (config.settings?.serverConfig?.extractScripts) {
140
143
  config.settings.serverConfig.extractScripts.errorPages = true;
141
144
  }
145
+ // Set cloneData function for slate block, in order to change the uuids of fragments in the copy process
146
+ if (config.blocks?.blocksConfig?.slate) {
147
+ config.blocks.blocksConfig.slate.cloneData = (data) => {
148
+ const replaceAllUidsWithNewOnes = (value) => {
149
+ if (value?.children?.length > 0) {
150
+ const newChildren = value.children.map((childrenData) => {
151
+ if (childrenData?.data?.uid) {
152
+ return {
153
+ ...childrenData,
154
+ data: { ...childrenData.data, uid: nanoid(5) },
155
+ };
156
+ }
157
+ return childrenData;
158
+ });
159
+ return {
160
+ ...value,
161
+ children: newChildren,
162
+ };
163
+ }
164
+ return value;
165
+ };
166
+ return [
167
+ uuid(),
168
+ {
169
+ ...data,
170
+ value: [
171
+ ...(data?.value || []).map((value) =>
172
+ replaceAllUidsWithNewOnes(value),
173
+ ),
174
+ ],
175
+ },
176
+ ];
177
+ };
178
+ }
142
179
 
143
180
  // Disable tags on View
144
181
  config.settings.showTags = false;
package/src/index.test.js CHANGED
@@ -144,7 +144,7 @@ describe('applyConfig', () => {
144
144
  { match: '', component: 'MockedDraftBackground' },
145
145
  { match: '', component: 'MockedSubsiteClass' },
146
146
  { match: '', component: BaseTag },
147
- { match: '*', component: 'MockedRemoveSchema' },
147
+ { match: '*', exclude: '/**/diff', component: 'MockedRemoveSchema' },
148
148
  ]);
149
149
  expect(config.settings.available_colors).toEqual(eea.colors);
150
150
  expect(config.settings.hasLanguageDropdown).toBe(false);
@@ -303,7 +303,7 @@ describe('applyConfig', () => {
303
303
  { match: '', component: 'MockedDraftBackground' },
304
304
  { match: '', component: 'MockedSubsiteClass' },
305
305
  { match: '', component: BaseTag },
306
- { match: '*', component: 'MockedRemoveSchema' },
306
+ { match: '*', exclude: '/**/diff', component: 'MockedRemoveSchema' },
307
307
  ]);
308
308
  expect(config.settings.available_colors).toEqual(eea.colors);
309
309
  expect(config.settings.hasLanguageDropdown).toBe(false);
@@ -9,6 +9,7 @@ export default function applyConfig(config) {
9
9
  ...(config.settings.appExtras || []),
10
10
  {
11
11
  match: '*',
12
+ exclude: '/**/diff',
12
13
  component: RemoveSchema,
13
14
  },
14
15
  ];