@eeacms/volto-slate-footnote 7.2.0 → 7.2.2
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 +45 -0
- package/locales/de/LC_MESSAGES/volto.po +43 -8
- package/locales/en/LC_MESSAGES/volto.po +39 -4
- package/locales/it/LC_MESSAGES/volto.po +39 -4
- package/locales/ro/LC_MESSAGES/volto.po +39 -4
- package/locales/volto.pot +41 -6
- package/package.json +1 -1
- package/src/Blocks/Footnote/FootnotesBlockEdit.jsx +4 -2
- package/src/Blocks/Footnote/FootnotesBlockView.jsx +3 -45
- package/src/Blocks/Footnote/FootnotesBlockView.test.jsx +84 -0
- package/src/Blocks/Footnote/schema.js +37 -8
- package/src/editor/render.jsx +39 -48
- package/src/editor/utils.js +75 -1
- package/src/editor/utils.test.js +69 -0
- package/src/index.js +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@ 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
|
+
### [7.2.2](https://github.com/eea/volto-slate-footnote/compare/7.2.1...7.2.2) - 31 January 2025
|
|
8
|
+
|
|
9
|
+
#### :bug: Bug Fixes
|
|
10
|
+
|
|
11
|
+
- fix: Update render.jsx to fix zotero in Edit mode - refs #282898 [dobri1408 - [`e84f0e3`](https://github.com/eea/volto-slate-footnote/commit/e84f0e3f79213b3e1cad2a887545bf5a64c9b4ab)]
|
|
12
|
+
|
|
13
|
+
### [7.2.1](https://github.com/eea/volto-slate-footnote/compare/7.2.0...7.2.1) - 30 January 2025
|
|
14
|
+
|
|
15
|
+
#### :bug: Bug Fixes
|
|
16
|
+
|
|
17
|
+
- fix: Improve the algorithm of link detection and html insertion to remove bugs - refs 282898 [dobri1408 - [`4e03b60`](https://github.com/eea/volto-slate-footnote/commit/4e03b6003df6e1fae89343bade9fc35425fb7de9)]
|
|
18
|
+
|
|
19
|
+
#### :hammer_and_wrench: Others
|
|
20
|
+
|
|
21
|
+
- i18n: Add german translations [Valentin Dumitru - [`aedee6f`](https://github.com/eea/volto-slate-footnote/commit/aedee6fab827de485137e703854f98d8a29b45e9)]
|
|
7
22
|
### [7.2.0](https://github.com/eea/volto-slate-footnote/compare/7.1.1...7.2.0) - 28 November 2024
|
|
8
23
|
|
|
9
24
|
### [7.1.1](https://github.com/eea/volto-slate-footnote/compare/7.1.0...7.1.1) - 16 September 2024
|
|
@@ -31,6 +46,8 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
31
46
|
|
|
32
47
|
#### :hammer_and_wrench: Others
|
|
33
48
|
|
|
49
|
+
- Add Sonarqube tag using insitu-frontend addons list [EEA Jenkins - [`1258c37`](https://github.com/eea/volto-slate-footnote/commit/1258c370d2ce42ddff78d6b749ab8c45897991d3)]
|
|
50
|
+
- Add Sonarqube tag using freshwater-frontend addons list [EEA Jenkins - [`e1031b1`](https://github.com/eea/volto-slate-footnote/commit/e1031b1db0a34679e0bb312e8f0db9433bf08498)]
|
|
34
51
|
### [6.3.0](https://github.com/eea/volto-slate-footnote/compare/6.2.3...6.3.0) - 28 March 2024
|
|
35
52
|
|
|
36
53
|
#### :hammer_and_wrench: Others
|
|
@@ -50,6 +67,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
50
67
|
|
|
51
68
|
#### :hammer_and_wrench: Others
|
|
52
69
|
|
|
70
|
+
- Add Sonarqube tag using insitu-frontend addons list [EEA Jenkins - [`aa335f9`](https://github.com/eea/volto-slate-footnote/commit/aa335f9eedd9d994b6fbceb57102d848dbdbae15)]
|
|
53
71
|
### [6.2.2](https://github.com/eea/volto-slate-footnote/compare/6.2.1...6.2.2) - 20 January 2024
|
|
54
72
|
|
|
55
73
|
#### :hammer_and_wrench: Others
|
|
@@ -74,9 +92,15 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
74
92
|
|
|
75
93
|
#### :house: Internal changes
|
|
76
94
|
|
|
95
|
+
- chore: [JENKINS] Refactor automated testing [valentinab25 - [`5a5e1ad`](https://github.com/eea/volto-slate-footnote/commit/5a5e1adf997af84e93a4015dc66b7299abba0874)]
|
|
77
96
|
|
|
78
97
|
#### :hammer_and_wrench: Others
|
|
79
98
|
|
|
99
|
+
- test: [JENKINS] Use java17 for sonarqube scanner [valentinab25 - [`af6d78f`](https://github.com/eea/volto-slate-footnote/commit/af6d78f60dd040fe61ebb225f4a689ac21ffb55c)]
|
|
100
|
+
- test: [JENKINS] Run cypress in started frontend container [valentinab25 - [`7f4c07f`](https://github.com/eea/volto-slate-footnote/commit/7f4c07f1fc2e9893d1f925152a473855a7e0f064)]
|
|
101
|
+
- test: [JENKINS] Add cpu limit on cypress docker [valentinab25 - [`0670217`](https://github.com/eea/volto-slate-footnote/commit/0670217cca01571e8a3bd64ee3d85bb53ce447be)]
|
|
102
|
+
- test: [JENKINS] Increase shm-size to cypress docker [valentinab25 - [`ec08749`](https://github.com/eea/volto-slate-footnote/commit/ec08749f9547d2c133b2174ab8d60cf2bdb1b23a)]
|
|
103
|
+
- test: [JENKINS] Improve cypress time [valentinab25 - [`237e6a3`](https://github.com/eea/volto-slate-footnote/commit/237e6a331e3608aa35d1c93a03c435daf330c2bd)]
|
|
80
104
|
### [6.1.8](https://github.com/eea/volto-slate-footnote/compare/6.1.7...6.1.8) - 22 October 2023
|
|
81
105
|
|
|
82
106
|
#### :house: Internal changes
|
|
@@ -146,17 +170,25 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
146
170
|
|
|
147
171
|
#### :house: Internal changes
|
|
148
172
|
|
|
173
|
+
- chore: [JENKINS] Deprecate circularity website [valentinab25 - [`ded882a`](https://github.com/eea/volto-slate-footnote/commit/ded882a1ca1183c2ba74ff4246111123ee36e6cb)]
|
|
149
174
|
|
|
150
175
|
#### :hammer_and_wrench: Others
|
|
151
176
|
|
|
152
177
|
- test: jest should look for addons in node_modules Refs #253277 [valentinab25 - [`3e0749c`](https://github.com/eea/volto-slate-footnote/commit/3e0749cc5bd7f5810ac6fd7a3feee4df0435ee0a)]
|
|
153
178
|
- test: Add unit tests for utils - refs #253277 [ana-oprea - [`a709895`](https://github.com/eea/volto-slate-footnote/commit/a709895d9953742ef6d39f8d9673c06b2efe6a64)]
|
|
154
179
|
- test: Fix test config, coverage Refs #253277 [valentinab25 - [`dc4d6dc`](https://github.com/eea/volto-slate-footnote/commit/dc4d6dc9b39bfe2c892156f32c764153d1366486)]
|
|
180
|
+
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`4f0ecee`](https://github.com/eea/volto-slate-footnote/commit/4f0ecee224d5d6604dfbb562556e45437edbb8ec)]
|
|
155
181
|
### [6.1.0](https://github.com/eea/volto-slate-footnote/compare/6.0.2...6.1.0) - 27 March 2023
|
|
156
182
|
|
|
157
183
|
#### :hammer_and_wrench: Others
|
|
158
184
|
|
|
185
|
+
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`23959ee`](https://github.com/eea/volto-slate-footnote/commit/23959ee43d45ec5eaa483590415a75fc58faae03)]
|
|
186
|
+
- Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`7aa6f34`](https://github.com/eea/volto-slate-footnote/commit/7aa6f3439953cc3d8f28875eff9fbcc24084cbc7)]
|
|
187
|
+
- Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`b117d15`](https://github.com/eea/volto-slate-footnote/commit/b117d15e51b3cf10717b9dd9dfef8304d46ad556)]
|
|
159
188
|
- test(Jenkins): Run tests and cypress with latest canary @plone/volto [Alin Voinea - [`97ed8fb`](https://github.com/eea/volto-slate-footnote/commit/97ed8fbd92f76c2b3128b62cdc1a77611e79410a)]
|
|
189
|
+
- Add Sonarqube tag using cca-frontend addons list [EEA Jenkins - [`cb22f5e`](https://github.com/eea/volto-slate-footnote/commit/cb22f5e8e9d3aed0a3b4374b6d4d80c8c2bb66e1)]
|
|
190
|
+
- yarn 3 [Alin Voinea - [`f5bb904`](https://github.com/eea/volto-slate-footnote/commit/f5bb904eecf740ffd57dbccf9a597c99ea2dfc0c)]
|
|
191
|
+
- Add Sonarqube tag using demo-kitkat-frontend addons list [EEA Jenkins - [`59cf6d3`](https://github.com/eea/volto-slate-footnote/commit/59cf6d334a460e373dda3e2e28754fcdd9fb0281)]
|
|
160
192
|
### [6.0.2](https://github.com/eea/volto-slate-footnote/compare/6.0.1...6.0.2) - 16 November 2022
|
|
161
193
|
|
|
162
194
|
#### :hammer_and_wrench: Others
|
|
@@ -172,27 +204,37 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
172
204
|
|
|
173
205
|
#### :hammer_and_wrench: Others
|
|
174
206
|
|
|
207
|
+
- Add Sonarqube tag using marine-frontend addons list [EEA Jenkins - [`dc3c7de`](https://github.com/eea/volto-slate-footnote/commit/dc3c7deaa8c692689ea0cec66cf019f05f9c4e22)]
|
|
208
|
+
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`133969a`](https://github.com/eea/volto-slate-footnote/commit/133969a37a6153a19af121d2f6031a70bc67cc9d)]
|
|
175
209
|
### [5.0.1](https://github.com/eea/volto-slate-footnote/compare/5.0.0...5.0.1) - 30 June 2022
|
|
176
210
|
|
|
177
211
|
#### :hammer_and_wrench: Others
|
|
178
212
|
|
|
213
|
+
- Add Sonarqube tag using circularity-frontend addons list [EEA Jenkins - [`4d5af13`](https://github.com/eea/volto-slate-footnote/commit/4d5af1345aad9071c031f7f00efd6bc5da04541f)]
|
|
179
214
|
## [5.0.0](https://github.com/eea/volto-slate-footnote/compare/4.0.5...5.0.0) - 19 May 2022
|
|
180
215
|
|
|
181
216
|
### [4.0.5](https://github.com/eea/volto-slate-footnote/compare/4.0.4...4.0.5) - 17 May 2022
|
|
182
217
|
|
|
183
218
|
#### :hammer_and_wrench: Others
|
|
184
219
|
|
|
220
|
+
- Add Sonarqube tag using clms-frontend addons list [EEA Jenkins - [`85a16ee`](https://github.com/eea/volto-slate-footnote/commit/85a16ee73d21d696282dc24933169d3c31383027)]
|
|
221
|
+
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`418349c`](https://github.com/eea/volto-slate-footnote/commit/418349ce22d98bf5dee58130d6f1cb9f45bbaa46)]
|
|
185
222
|
### [4.0.4](https://github.com/eea/volto-slate-footnote/compare/4.0.3...4.0.4) - 3 January 2022
|
|
186
223
|
|
|
187
224
|
### [4.0.3](https://github.com/eea/volto-slate-footnote/compare/4.0.2...4.0.3) - 18 December 2021
|
|
188
225
|
|
|
189
226
|
#### :hammer_and_wrench: Others
|
|
190
227
|
|
|
228
|
+
- Add Sonarqube tag using freshwater-frontend addons list [EEA Jenkins - [`ad06940`](https://github.com/eea/volto-slate-footnote/commit/ad0694074a06eb56ec1891256b262e9854c0303d)]
|
|
191
229
|
- Refs #142010 - Optimize Volto-addons gitflow pipelines [valentinab25 - [`1081079`](https://github.com/eea/volto-slate-footnote/commit/1081079444f5ac806e9d56765c4ccf0b9e415a73)]
|
|
230
|
+
- Add Sonarqube tag using industry-frontend addons list [EEA Jenkins - [`307687b`](https://github.com/eea/volto-slate-footnote/commit/307687b93d966e0df5c4a3f813dbb19442d2e169)]
|
|
231
|
+
- Add Sonarqube tag using clms-frontend addons list [EEA Jenkins - [`0460e2a`](https://github.com/eea/volto-slate-footnote/commit/0460e2a73a4c8ede00b0c1fc3f05624eaa345a33)]
|
|
232
|
+
- Add Sonarqube tag using forests-frontend addons list [EEA Jenkins - [`8aecee9`](https://github.com/eea/volto-slate-footnote/commit/8aecee99f11387e4ce31825209798772d7fee060)]
|
|
192
233
|
### [4.0.2](https://github.com/eea/volto-slate-footnote/compare/4.0.1...4.0.2) - 30 September 2021
|
|
193
234
|
|
|
194
235
|
#### :hammer_and_wrench: Others
|
|
195
236
|
|
|
237
|
+
- Add Sonarqube tag using sustainability-frontend addons list [EEA Jenkins - [`cf33efe`](https://github.com/eea/volto-slate-footnote/commit/cf33efec91b4b8d13562b8c8f660e7a78191d9e0)]
|
|
196
238
|
- Remove :asDefault dependency from volto-slate [Alin Voinea - [`13dad5e`](https://github.com/eea/volto-slate-footnote/commit/13dad5ed23043fa7a24682e1ac6addc86632bfe0)]
|
|
197
239
|
### [4.0.1](https://github.com/eea/volto-slate-footnote/compare/4.0.0...4.0.1) - 29 September 2021
|
|
198
240
|
|
|
@@ -200,6 +242,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
200
242
|
|
|
201
243
|
#### :hammer_and_wrench: Others
|
|
202
244
|
|
|
245
|
+
- Add Sonarqube tag using climate-energy-frontend addons list [EEA Jenkins - [`80a159b`](https://github.com/eea/volto-slate-footnote/commit/80a159bb67698cddedadc494e7ae2da32a96faea)]
|
|
203
246
|
### [3.2.0](https://github.com/eea/volto-slate-footnote/compare/3.1.1...3.2.0) - 13 September 2021
|
|
204
247
|
|
|
205
248
|
#### :hammer_and_wrench: Others
|
|
@@ -212,6 +255,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
212
255
|
- Remove console.log [Alin Voinea - [`b5d83e7`](https://github.com/eea/volto-slate-footnote/commit/b5d83e7c13240151f602d122ecf09ba9b8e335f3)]
|
|
213
256
|
- Fix slate json field default value in DX layout [Alin Voinea - [`f2805bb`](https://github.com/eea/volto-slate-footnote/commit/f2805bbc15c51ebd914ee5f4eb9dd34ef32e095b)]
|
|
214
257
|
- Fix cypress api_url [Alin Voinea - [`6a4966a`](https://github.com/eea/volto-slate-footnote/commit/6a4966a2f92e932e1d0df35351989cda535f15c8)]
|
|
258
|
+
- Add Sonarqube tag using ims-frontend addons list [EEA Jenkins - [`aed3984`](https://github.com/eea/volto-slate-footnote/commit/aed39840ecd467689eaf0adb352bd00ce95bdbbe)]
|
|
215
259
|
### [3.1.0](https://github.com/eea/volto-slate-footnote/compare/3.0.0...3.1.0) - 9 September 2021
|
|
216
260
|
|
|
217
261
|
#### :hammer_and_wrench: Others
|
|
@@ -232,6 +276,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
232
276
|
- Bump version to 2.4.0 [Alin Voinea - [`bef0d34`](https://github.com/eea/volto-slate-footnote/commit/bef0d34c2b9c20915578ffaefb4fd30cbf42f0a1)]
|
|
233
277
|
- Fix Slate point from DOM crash [Alin Voinea - [`c852f79`](https://github.com/eea/volto-slate-footnote/commit/c852f7987ffe8db433235b70792002d40ade690f)]
|
|
234
278
|
- Fix crash on copy&paste beforeInsert condition [Alin Voinea - [`85172cf`](https://github.com/eea/volto-slate-footnote/commit/85172cff3e2ea95a86d4b4fb452f3c0287b80e8f)]
|
|
279
|
+
- Add Sonarqube tag using frontend addons list [EEA Jenkins - [`b471c41`](https://github.com/eea/volto-slate-footnote/commit/b471c418d198b1bde95acfe0b256f642bacc6865)]
|
|
235
280
|
### [2.3.1](https://github.com/eea/volto-slate-footnote/compare/2.3.0...2.3.1) - 25 June 2021
|
|
236
281
|
|
|
237
282
|
### [2.3.0](https://github.com/eea/volto-slate-footnote/compare/2.2.2...2.3.0) - 12 June 2021
|
|
@@ -11,22 +11,57 @@ msgstr ""
|
|
|
11
11
|
"Content-Transfer-Encoding: \n"
|
|
12
12
|
"Plural-Forms: \n"
|
|
13
13
|
|
|
14
|
+
#. Default: "Edit footnote"
|
|
14
15
|
#: editor/index
|
|
15
|
-
# defaultMessage: Edit footnote
|
|
16
16
|
msgid "Edit footnote"
|
|
17
|
-
msgstr ""
|
|
17
|
+
msgstr "Fußnote bearbeiten"
|
|
18
|
+
|
|
19
|
+
#. Default: "Footnotes"
|
|
20
|
+
#: index
|
|
21
|
+
msgid "Footnotes"
|
|
22
|
+
msgstr "Fußnoten"
|
|
18
23
|
|
|
24
|
+
#. Default: "No options"
|
|
19
25
|
#: editor/MultiSelectSearchWidget
|
|
20
|
-
# defaultMessage: No options
|
|
21
26
|
msgid "No options"
|
|
22
|
-
msgstr ""
|
|
27
|
+
msgstr "Keine Optionen"
|
|
23
28
|
|
|
29
|
+
#. Default: "Remove footnote"
|
|
24
30
|
#: editor/index
|
|
25
|
-
# defaultMessage: Remove footnote
|
|
26
31
|
msgid "Remove footnote"
|
|
27
|
-
msgstr ""
|
|
32
|
+
msgstr "Fußnote entfernen"
|
|
28
33
|
|
|
34
|
+
#. Default: "Select…"
|
|
29
35
|
#: editor/MultiSelectSearchWidget
|
|
30
|
-
# defaultMessage: Select…
|
|
31
36
|
msgid "Select…"
|
|
32
|
-
msgstr ""
|
|
37
|
+
msgstr "Auswählen..."
|
|
38
|
+
|
|
39
|
+
#. Default: "Block title"
|
|
40
|
+
#: Blocks/Footnote/schema
|
|
41
|
+
msgid "blockTitle"
|
|
42
|
+
msgstr "Blocktitel"
|
|
43
|
+
|
|
44
|
+
#. Default: "Friendly name to be displayed as block title"
|
|
45
|
+
#: Blocks/Footnote/schema
|
|
46
|
+
msgid "blockTitleDescription"
|
|
47
|
+
msgstr "Name, der als Blocktitel angezeigt werden soll"
|
|
48
|
+
|
|
49
|
+
#. Default: "Default"
|
|
50
|
+
#: Blocks/Footnote/schema
|
|
51
|
+
msgid "default"
|
|
52
|
+
msgstr "Standard"
|
|
53
|
+
|
|
54
|
+
#. Default: "Entire document"
|
|
55
|
+
#: Blocks/Footnote/schema
|
|
56
|
+
msgid "entireDocument"
|
|
57
|
+
msgstr "Ganzes Dokument"
|
|
58
|
+
|
|
59
|
+
#. Default: "Lookup citation references on the entire document"
|
|
60
|
+
#: Blocks/Footnote/schema
|
|
61
|
+
msgid "entireDocumentDescription"
|
|
62
|
+
msgstr "Nachschlagen von Zitierangaben im gesamten Dokument"
|
|
63
|
+
|
|
64
|
+
#. Default: "Footnote block"
|
|
65
|
+
#: Blocks/Footnote/schema
|
|
66
|
+
msgid "footnoteBlock"
|
|
67
|
+
msgstr "Fußnoten-Block"
|
|
@@ -11,22 +11,57 @@ msgstr ""
|
|
|
11
11
|
"Content-Transfer-Encoding: \n"
|
|
12
12
|
"Plural-Forms: \n"
|
|
13
13
|
|
|
14
|
+
#. Default: "Edit footnote"
|
|
14
15
|
#: editor/index
|
|
15
|
-
# defaultMessage: Edit footnote
|
|
16
16
|
msgid "Edit footnote"
|
|
17
17
|
msgstr ""
|
|
18
18
|
|
|
19
|
+
#. Default: "Footnotes"
|
|
20
|
+
#: index
|
|
21
|
+
msgid "Footnotes"
|
|
22
|
+
msgstr ""
|
|
23
|
+
|
|
24
|
+
#. Default: "No options"
|
|
19
25
|
#: editor/MultiSelectSearchWidget
|
|
20
|
-
# defaultMessage: No options
|
|
21
26
|
msgid "No options"
|
|
22
27
|
msgstr ""
|
|
23
28
|
|
|
29
|
+
#. Default: "Remove footnote"
|
|
24
30
|
#: editor/index
|
|
25
|
-
# defaultMessage: Remove footnote
|
|
26
31
|
msgid "Remove footnote"
|
|
27
32
|
msgstr ""
|
|
28
33
|
|
|
34
|
+
#. Default: "Select…"
|
|
29
35
|
#: editor/MultiSelectSearchWidget
|
|
30
|
-
# defaultMessage: Select…
|
|
31
36
|
msgid "Select…"
|
|
32
37
|
msgstr ""
|
|
38
|
+
|
|
39
|
+
#. Default: "Block title"
|
|
40
|
+
#: Blocks/Footnote/schema
|
|
41
|
+
msgid "blockTitle"
|
|
42
|
+
msgstr ""
|
|
43
|
+
|
|
44
|
+
#. Default: "Friendly name to be displayed as block title"
|
|
45
|
+
#: Blocks/Footnote/schema
|
|
46
|
+
msgid "blockTitleDescription"
|
|
47
|
+
msgstr ""
|
|
48
|
+
|
|
49
|
+
#. Default: "Default"
|
|
50
|
+
#: Blocks/Footnote/schema
|
|
51
|
+
msgid "default"
|
|
52
|
+
msgstr ""
|
|
53
|
+
|
|
54
|
+
#. Default: "Entire document"
|
|
55
|
+
#: Blocks/Footnote/schema
|
|
56
|
+
msgid "entireDocument"
|
|
57
|
+
msgstr ""
|
|
58
|
+
|
|
59
|
+
#. Default: "Lookup citation references on the entire document"
|
|
60
|
+
#: Blocks/Footnote/schema
|
|
61
|
+
msgid "entireDocumentDescription"
|
|
62
|
+
msgstr ""
|
|
63
|
+
|
|
64
|
+
#. Default: "Footnote block"
|
|
65
|
+
#: Blocks/Footnote/schema
|
|
66
|
+
msgid "footnoteBlock"
|
|
67
|
+
msgstr ""
|
|
@@ -11,22 +11,57 @@ msgstr ""
|
|
|
11
11
|
"Content-Transfer-Encoding: \n"
|
|
12
12
|
"Plural-Forms: \n"
|
|
13
13
|
|
|
14
|
+
#. Default: "Edit footnote"
|
|
14
15
|
#: editor/index
|
|
15
|
-
# defaultMessage: Edit footnote
|
|
16
16
|
msgid "Edit footnote"
|
|
17
17
|
msgstr ""
|
|
18
18
|
|
|
19
|
+
#. Default: "Footnotes"
|
|
20
|
+
#: index
|
|
21
|
+
msgid "Footnotes"
|
|
22
|
+
msgstr ""
|
|
23
|
+
|
|
24
|
+
#. Default: "No options"
|
|
19
25
|
#: editor/MultiSelectSearchWidget
|
|
20
|
-
# defaultMessage: No options
|
|
21
26
|
msgid "No options"
|
|
22
27
|
msgstr ""
|
|
23
28
|
|
|
29
|
+
#. Default: "Remove footnote"
|
|
24
30
|
#: editor/index
|
|
25
|
-
# defaultMessage: Remove footnote
|
|
26
31
|
msgid "Remove footnote"
|
|
27
32
|
msgstr ""
|
|
28
33
|
|
|
34
|
+
#. Default: "Select…"
|
|
29
35
|
#: editor/MultiSelectSearchWidget
|
|
30
|
-
# defaultMessage: Select…
|
|
31
36
|
msgid "Select…"
|
|
32
37
|
msgstr ""
|
|
38
|
+
|
|
39
|
+
#. Default: "Block title"
|
|
40
|
+
#: Blocks/Footnote/schema
|
|
41
|
+
msgid "blockTitle"
|
|
42
|
+
msgstr ""
|
|
43
|
+
|
|
44
|
+
#. Default: "Friendly name to be displayed as block title"
|
|
45
|
+
#: Blocks/Footnote/schema
|
|
46
|
+
msgid "blockTitleDescription"
|
|
47
|
+
msgstr ""
|
|
48
|
+
|
|
49
|
+
#. Default: "Default"
|
|
50
|
+
#: Blocks/Footnote/schema
|
|
51
|
+
msgid "default"
|
|
52
|
+
msgstr ""
|
|
53
|
+
|
|
54
|
+
#. Default: "Entire document"
|
|
55
|
+
#: Blocks/Footnote/schema
|
|
56
|
+
msgid "entireDocument"
|
|
57
|
+
msgstr ""
|
|
58
|
+
|
|
59
|
+
#. Default: "Lookup citation references on the entire document"
|
|
60
|
+
#: Blocks/Footnote/schema
|
|
61
|
+
msgid "entireDocumentDescription"
|
|
62
|
+
msgstr ""
|
|
63
|
+
|
|
64
|
+
#. Default: "Footnote block"
|
|
65
|
+
#: Blocks/Footnote/schema
|
|
66
|
+
msgid "footnoteBlock"
|
|
67
|
+
msgstr ""
|
|
@@ -11,22 +11,57 @@ msgstr ""
|
|
|
11
11
|
"Content-Transfer-Encoding: \n"
|
|
12
12
|
"Plural-Forms: \n"
|
|
13
13
|
|
|
14
|
+
#. Default: "Edit footnote"
|
|
14
15
|
#: editor/index
|
|
15
|
-
# defaultMessage: Edit footnote
|
|
16
16
|
msgid "Edit footnote"
|
|
17
17
|
msgstr ""
|
|
18
18
|
|
|
19
|
+
#. Default: "Footnotes"
|
|
20
|
+
#: index
|
|
21
|
+
msgid "Footnotes"
|
|
22
|
+
msgstr ""
|
|
23
|
+
|
|
24
|
+
#. Default: "No options"
|
|
19
25
|
#: editor/MultiSelectSearchWidget
|
|
20
|
-
# defaultMessage: No options
|
|
21
26
|
msgid "No options"
|
|
22
27
|
msgstr ""
|
|
23
28
|
|
|
29
|
+
#. Default: "Remove footnote"
|
|
24
30
|
#: editor/index
|
|
25
|
-
# defaultMessage: Remove footnote
|
|
26
31
|
msgid "Remove footnote"
|
|
27
32
|
msgstr ""
|
|
28
33
|
|
|
34
|
+
#. Default: "Select…"
|
|
29
35
|
#: editor/MultiSelectSearchWidget
|
|
30
|
-
# defaultMessage: Select…
|
|
31
36
|
msgid "Select…"
|
|
32
37
|
msgstr ""
|
|
38
|
+
|
|
39
|
+
#. Default: "Block title"
|
|
40
|
+
#: Blocks/Footnote/schema
|
|
41
|
+
msgid "blockTitle"
|
|
42
|
+
msgstr ""
|
|
43
|
+
|
|
44
|
+
#. Default: "Friendly name to be displayed as block title"
|
|
45
|
+
#: Blocks/Footnote/schema
|
|
46
|
+
msgid "blockTitleDescription"
|
|
47
|
+
msgstr ""
|
|
48
|
+
|
|
49
|
+
#. Default: "Default"
|
|
50
|
+
#: Blocks/Footnote/schema
|
|
51
|
+
msgid "default"
|
|
52
|
+
msgstr ""
|
|
53
|
+
|
|
54
|
+
#. Default: "Entire document"
|
|
55
|
+
#: Blocks/Footnote/schema
|
|
56
|
+
msgid "entireDocument"
|
|
57
|
+
msgstr ""
|
|
58
|
+
|
|
59
|
+
#. Default: "Lookup citation references on the entire document"
|
|
60
|
+
#: Blocks/Footnote/schema
|
|
61
|
+
msgid "entireDocumentDescription"
|
|
62
|
+
msgstr ""
|
|
63
|
+
|
|
64
|
+
#. Default: "Footnote block"
|
|
65
|
+
#: Blocks/Footnote/schema
|
|
66
|
+
msgid "footnoteBlock"
|
|
67
|
+
msgstr ""
|
package/locales/volto.pot
CHANGED
|
@@ -1,34 +1,69 @@
|
|
|
1
1
|
msgid ""
|
|
2
2
|
msgstr ""
|
|
3
3
|
"Project-Id-Version: Plone\n"
|
|
4
|
-
"POT-Creation-Date:
|
|
4
|
+
"POT-Creation-Date: 2025-01-14T11:22:56.136Z\n"
|
|
5
5
|
"Last-Translator: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
|
|
6
6
|
"Language-Team: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
|
|
7
|
-
"MIME-Version: 1.0\n"
|
|
8
7
|
"Content-Type: text/plain; charset=utf-8\n"
|
|
9
8
|
"Content-Transfer-Encoding: 8bit\n"
|
|
10
9
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
10
|
+
"MIME-Version: 1.0\n"
|
|
11
11
|
"Language-Code: en\n"
|
|
12
12
|
"Language-Name: English\n"
|
|
13
13
|
"Preferred-Encodings: utf-8\n"
|
|
14
14
|
"Domain: volto\n"
|
|
15
15
|
|
|
16
|
+
#. Default: "Edit footnote"
|
|
16
17
|
#: editor/index
|
|
17
|
-
# defaultMessage: Edit footnote
|
|
18
18
|
msgid "Edit footnote"
|
|
19
19
|
msgstr ""
|
|
20
20
|
|
|
21
|
+
#. Default: "Footnotes"
|
|
22
|
+
#: index
|
|
23
|
+
msgid "Footnotes"
|
|
24
|
+
msgstr ""
|
|
25
|
+
|
|
26
|
+
#. Default: "No options"
|
|
21
27
|
#: editor/MultiSelectSearchWidget
|
|
22
|
-
# defaultMessage: No options
|
|
23
28
|
msgid "No options"
|
|
24
29
|
msgstr ""
|
|
25
30
|
|
|
31
|
+
#. Default: "Remove footnote"
|
|
26
32
|
#: editor/index
|
|
27
|
-
# defaultMessage: Remove footnote
|
|
28
33
|
msgid "Remove footnote"
|
|
29
34
|
msgstr ""
|
|
30
35
|
|
|
36
|
+
#. Default: "Select…"
|
|
31
37
|
#: editor/MultiSelectSearchWidget
|
|
32
|
-
# defaultMessage: Select…
|
|
33
38
|
msgid "Select…"
|
|
34
39
|
msgstr ""
|
|
40
|
+
|
|
41
|
+
#. Default: "Block title"
|
|
42
|
+
#: Blocks/Footnote/schema
|
|
43
|
+
msgid "blockTitle"
|
|
44
|
+
msgstr ""
|
|
45
|
+
|
|
46
|
+
#. Default: "Friendly name to be displayed as block title"
|
|
47
|
+
#: Blocks/Footnote/schema
|
|
48
|
+
msgid "blockTitleDescription"
|
|
49
|
+
msgstr ""
|
|
50
|
+
|
|
51
|
+
#. Default: "Default"
|
|
52
|
+
#: Blocks/Footnote/schema
|
|
53
|
+
msgid "default"
|
|
54
|
+
msgstr ""
|
|
55
|
+
|
|
56
|
+
#. Default: "Entire document"
|
|
57
|
+
#: Blocks/Footnote/schema
|
|
58
|
+
msgid "entireDocument"
|
|
59
|
+
msgstr ""
|
|
60
|
+
|
|
61
|
+
#. Default: "Lookup citation references on the entire document"
|
|
62
|
+
#: Blocks/Footnote/schema
|
|
63
|
+
msgid "entireDocumentDescription"
|
|
64
|
+
msgstr ""
|
|
65
|
+
|
|
66
|
+
#. Default: "Footnote block"
|
|
67
|
+
#: Blocks/Footnote/schema
|
|
68
|
+
msgid "footnoteBlock"
|
|
69
|
+
msgstr ""
|
package/package.json
CHANGED
|
@@ -18,6 +18,8 @@ const FootnotesBlockEdit = (props) => {
|
|
|
18
18
|
instructions = props.formDescription;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
const blockSchema = schema(props.intl);
|
|
22
|
+
|
|
21
23
|
return (
|
|
22
24
|
<>
|
|
23
25
|
<FootnotesBlockView {...props} properties={properties} />
|
|
@@ -29,8 +31,8 @@ const FootnotesBlockEdit = (props) => {
|
|
|
29
31
|
)}
|
|
30
32
|
{!data?.readOnlySettings && (
|
|
31
33
|
<InlineForm
|
|
32
|
-
schema={
|
|
33
|
-
title={
|
|
34
|
+
schema={blockSchema}
|
|
35
|
+
title={blockSchema.title}
|
|
34
36
|
onChangeField={(id, value) => {
|
|
35
37
|
onChangeBlock(block, {
|
|
36
38
|
...data,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import {
|
|
4
4
|
openAccordionOrTabIfContainsFootnoteReference,
|
|
5
5
|
getAllBlocksAndSlateFields,
|
|
@@ -8,10 +8,9 @@ import {
|
|
|
8
8
|
import './less/public.less';
|
|
9
9
|
|
|
10
10
|
import { UniversalLink } from '@plone/volto/components';
|
|
11
|
+
import { renderTextWithLinks } from '../../editor/utils';
|
|
11
12
|
|
|
12
13
|
const alphabet = 'abcdefghijklmnopqrstuvwxyz';
|
|
13
|
-
const urlRegex =
|
|
14
|
-
/\b((http|https|ftp):\/\/)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(:\d+)?(\/[^\s]*)?\b/g;
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* @summary The React component that displays the list of footnotes inserted
|
|
@@ -78,47 +77,6 @@ const FootnotesBlockView = (props) => {
|
|
|
78
77
|
startList = citationIndice;
|
|
79
78
|
}
|
|
80
79
|
|
|
81
|
-
const renderTextWithLinks = (text) => {
|
|
82
|
-
if (!text) return null;
|
|
83
|
-
const links = text.match(urlRegex);
|
|
84
|
-
if (!links) {
|
|
85
|
-
return (
|
|
86
|
-
<div
|
|
87
|
-
dangerouslySetInnerHTML={{
|
|
88
|
-
__html: text,
|
|
89
|
-
}}
|
|
90
|
-
/>
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
let result = [];
|
|
94
|
-
const parts = text.split(
|
|
95
|
-
new RegExp(`(${links.map((link) => escapeRegExp(link)).join('|')})`),
|
|
96
|
-
);
|
|
97
|
-
parts.forEach((part, index) => {
|
|
98
|
-
if (links.includes(part)) {
|
|
99
|
-
result.push(
|
|
100
|
-
<UniversalLink
|
|
101
|
-
key={`link-${index}`}
|
|
102
|
-
href={part}
|
|
103
|
-
openLinkInNewTab={false}
|
|
104
|
-
>
|
|
105
|
-
{part}
|
|
106
|
-
</UniversalLink>,
|
|
107
|
-
);
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
result.push(
|
|
112
|
-
<span
|
|
113
|
-
dangerouslySetInnerHTML={{
|
|
114
|
-
__html: part,
|
|
115
|
-
}}
|
|
116
|
-
/>,
|
|
117
|
-
);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
return <div>{result}</div>;
|
|
121
|
-
};
|
|
122
80
|
return (
|
|
123
81
|
<div className="footnotes-listing-block">
|
|
124
82
|
<h3 title={placeholder}>{title}</h3>
|
|
@@ -141,7 +99,7 @@ const FootnotesBlockView = (props) => {
|
|
|
141
99
|
key={`footnote-${zoteroId || uid}`}
|
|
142
100
|
id={`footnote-${zoteroId || uid}`}
|
|
143
101
|
>
|
|
144
|
-
<div>{renderTextWithLinks(footnoteText)}</div>
|
|
102
|
+
<div>{renderTextWithLinks(footnoteText, zoteroId)}</div>
|
|
145
103
|
{refsList ? (
|
|
146
104
|
<>
|
|
147
105
|
{/** some footnotes are never parent so we need the parent to reference */}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
4
|
+
import FootnotesBlockView from './FootnotesBlockView';
|
|
5
|
+
|
|
6
|
+
jest.mock('@plone/volto/components', () => ({
|
|
7
|
+
UniversalLink: ({ children, href }) => <a href={href}>{children}</a>,
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
jest.mock('@eeacms/volto-slate-footnote/editor/utils', () => ({
|
|
11
|
+
openAccordionOrTabIfContainsFootnoteReference: jest.fn(),
|
|
12
|
+
renderTextWithLinks: jest.fn(),
|
|
13
|
+
getAllBlocksAndSlateFields: jest.fn(() => [
|
|
14
|
+
{ id: 'block1', footnote: 'Footnote with no link' },
|
|
15
|
+
{ id: 'block2', footnote: 'Footnote with link http://example.com' },
|
|
16
|
+
{ id: 'block3', footnote: 'Footnote with <b>HTML</b>' },
|
|
17
|
+
]),
|
|
18
|
+
makeFootnoteListOfUniqueItems: jest.fn((blocks) => ({
|
|
19
|
+
note1: {
|
|
20
|
+
uid: '1',
|
|
21
|
+
footnote: 'First note with a reference',
|
|
22
|
+
zoteroId: 'zotero1',
|
|
23
|
+
refs: { ref1: 'ref1' },
|
|
24
|
+
},
|
|
25
|
+
note2: {
|
|
26
|
+
uid: '2',
|
|
27
|
+
footnote: 'Second note with multiple references',
|
|
28
|
+
zoteroId: null,
|
|
29
|
+
refs: { ref2: 'ref2', ref3: 'ref3' },
|
|
30
|
+
},
|
|
31
|
+
note3: {
|
|
32
|
+
uid: '3',
|
|
33
|
+
footnote: '<i>Note with HTML</i>',
|
|
34
|
+
zoteroId: 'zotero3',
|
|
35
|
+
refs: {},
|
|
36
|
+
},
|
|
37
|
+
})),
|
|
38
|
+
}));
|
|
39
|
+
|
|
40
|
+
describe('FootnotesBlockView', () => {
|
|
41
|
+
const propsVariations = [
|
|
42
|
+
{
|
|
43
|
+
description: 'renders with global metadata',
|
|
44
|
+
props: {
|
|
45
|
+
data: { title: 'Global Metadata', global: true, placeholder: 'Global' },
|
|
46
|
+
properties: { test: 'metadata' },
|
|
47
|
+
tabData: null,
|
|
48
|
+
content: null,
|
|
49
|
+
metadata: { test: 'metadata' },
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
description: 'renders with tabData',
|
|
54
|
+
props: {
|
|
55
|
+
data: { title: 'Tab Data', global: false, placeholder: 'Tab' },
|
|
56
|
+
properties: { test: 'tabProperties' },
|
|
57
|
+
tabData: { test: 'tabData' },
|
|
58
|
+
content: null,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
description: 'renders with content',
|
|
63
|
+
props: {
|
|
64
|
+
data: { title: 'Content Data', global: false, placeholder: 'Content' },
|
|
65
|
+
properties: { test: 'contentProperties' },
|
|
66
|
+
tabData: null,
|
|
67
|
+
content: { test: 'contentData' },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
description: 'renders with no metadata',
|
|
72
|
+
props: {
|
|
73
|
+
data: { title: 'No Metadata', global: false, placeholder: 'Default' },
|
|
74
|
+
properties: { test: 'defaultProperties' },
|
|
75
|
+
tabData: null,
|
|
76
|
+
content: null,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
test.each(propsVariations)('$description', ({ props }) => {
|
|
82
|
+
render(<FootnotesBlockView {...props} />);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -1,23 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { defineMessages } from 'react-intl';
|
|
2
|
+
|
|
3
|
+
const messages = defineMessages({
|
|
4
|
+
footnoteBlock: {
|
|
5
|
+
id: 'footnoteBlock',
|
|
6
|
+
defaultMessage: 'Footnote block',
|
|
7
|
+
},
|
|
8
|
+
default: {
|
|
9
|
+
id: 'default',
|
|
10
|
+
defaultMessage: 'Default',
|
|
11
|
+
},
|
|
12
|
+
blockTitle: {
|
|
13
|
+
id: 'blockTitle',
|
|
14
|
+
defaultMessage: 'Block title',
|
|
15
|
+
},
|
|
16
|
+
blockTitleDescription: {
|
|
17
|
+
id: 'blockTitleDescription',
|
|
18
|
+
defaultMessage: 'Friendly name to be displayed as block title',
|
|
19
|
+
},
|
|
20
|
+
entireDocument: {
|
|
21
|
+
id: 'entireDocument',
|
|
22
|
+
defaultMessage: 'Entire document',
|
|
23
|
+
},
|
|
24
|
+
entireDocumentDescription: {
|
|
25
|
+
id: 'entireDocumentDescription',
|
|
26
|
+
defaultMessage: 'Lookup citation references on the entire document',
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export const FootnoteBlockSchema = (intl) => ({
|
|
31
|
+
title: intl.formatMessage(messages.footnoteBlock),
|
|
3
32
|
fieldsets: [
|
|
4
33
|
{
|
|
5
34
|
id: 'default',
|
|
6
|
-
title:
|
|
35
|
+
title: intl.formatMessage(messages.default),
|
|
7
36
|
fields: ['title', 'global'],
|
|
8
37
|
},
|
|
9
38
|
],
|
|
10
39
|
properties: {
|
|
11
40
|
title: {
|
|
12
|
-
title:
|
|
13
|
-
description:
|
|
41
|
+
title: intl.formatMessage(messages.blockTitle),
|
|
42
|
+
description: intl.formatMessage(messages.blockTitleDescription),
|
|
14
43
|
type: 'string',
|
|
15
44
|
},
|
|
16
45
|
global: {
|
|
17
|
-
title:
|
|
18
|
-
description:
|
|
46
|
+
title: intl.formatMessage(messages.entireDocument),
|
|
47
|
+
description: intl.formatMessage(messages.entireDocumentDescription),
|
|
19
48
|
type: 'boolean',
|
|
20
49
|
},
|
|
21
50
|
},
|
|
22
51
|
required: [],
|
|
23
|
-
};
|
|
52
|
+
});
|
package/src/editor/render.jsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Popup, List } from 'semantic-ui-react';
|
|
3
3
|
import { useEditorContext } from '@plone/volto-slate/hooks';
|
|
4
|
+
|
|
4
5
|
import { getAllBlocksAndSlateFields } from '@eeacms/volto-slate-footnote/editor/utils';
|
|
5
6
|
import {
|
|
6
7
|
makeFootnoteListOfUniqueItems,
|
|
@@ -8,7 +9,9 @@ import {
|
|
|
8
9
|
} from './utils';
|
|
9
10
|
import { isEmpty } from 'lodash';
|
|
10
11
|
import { useSelector } from 'react-redux';
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
import { renderTextWithLinks } from './utils';
|
|
14
|
+
import { useHistory } from 'react-router-dom';
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
17
|
* Removes '<?xml version="1.0"?>' from footnote
|
|
@@ -16,14 +19,13 @@ import { UniversalLink } from '@plone/volto/components';
|
|
|
16
19
|
* @returns {string} formatted footnote
|
|
17
20
|
*/
|
|
18
21
|
|
|
19
|
-
const urlRegex = /https?:\/\/[^\s]+/g;
|
|
20
|
-
|
|
21
22
|
export const FootnoteElement = (props) => {
|
|
22
23
|
const { attributes, children, element, mode, extras } = props;
|
|
23
24
|
const { data = {} } = element;
|
|
24
25
|
const { uid, zoteroId } = data;
|
|
25
26
|
const editor = useEditorContext();
|
|
26
27
|
const ref = React.useRef();
|
|
28
|
+
const history = useHistory();
|
|
27
29
|
|
|
28
30
|
const initialFormData = useSelector((state) => state?.content?.data || {});
|
|
29
31
|
const blockProps = editor?.getBlockProps ? editor.getBlockProps() : null;
|
|
@@ -51,35 +53,6 @@ export const FootnoteElement = (props) => {
|
|
|
51
53
|
: // no extra citations (no multiples)
|
|
52
54
|
`[${Object.keys(notesObjResult).indexOf(zoteroId) + 1}]`;
|
|
53
55
|
|
|
54
|
-
const renderTextWithLinks = (text) => {
|
|
55
|
-
if (!text) return null;
|
|
56
|
-
const parts = text.split(urlRegex);
|
|
57
|
-
const links = text.match(urlRegex);
|
|
58
|
-
let result = [];
|
|
59
|
-
|
|
60
|
-
parts.forEach((part, index) => {
|
|
61
|
-
result.push(
|
|
62
|
-
<div
|
|
63
|
-
dangerouslySetInnerHTML={{
|
|
64
|
-
__html: part,
|
|
65
|
-
}}
|
|
66
|
-
/>,
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
if (links && links[index]) {
|
|
70
|
-
result.push(
|
|
71
|
-
<UniversalLink
|
|
72
|
-
key={`link-${index}`}
|
|
73
|
-
href={links[index]}
|
|
74
|
-
openLinkInNewTab={false}
|
|
75
|
-
>
|
|
76
|
-
{links[index]}
|
|
77
|
-
</UniversalLink>,
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
return result;
|
|
82
|
-
};
|
|
83
56
|
const citationIndice = zoteroId // ZOTERO
|
|
84
57
|
? indiceIfZoteroId
|
|
85
58
|
: // FOOTNOTES
|
|
@@ -142,16 +115,20 @@ export const FootnoteElement = (props) => {
|
|
|
142
115
|
<List divided relaxed selection>
|
|
143
116
|
<List.Item
|
|
144
117
|
href={`#footnote-${citationRefId}`}
|
|
145
|
-
onClick={() =>
|
|
118
|
+
onClick={(e) => {
|
|
146
119
|
openAccordionOrTabIfContainsFootnoteReference(
|
|
147
120
|
`#footnote-${citationRefId}`,
|
|
148
|
-
)
|
|
149
|
-
|
|
121
|
+
);
|
|
122
|
+
if (e.target.tagName !== 'A') {
|
|
123
|
+
e.preventDefault();
|
|
124
|
+
history.push(`#footnote-${citationRefId}`);
|
|
125
|
+
}
|
|
126
|
+
}}
|
|
150
127
|
key={`#footnote-${citationRefId}`}
|
|
151
128
|
>
|
|
152
129
|
<List.Content>
|
|
153
130
|
<List.Description>
|
|
154
|
-
{renderTextWithLinks(footnoteText)}
|
|
131
|
+
{renderTextWithLinks(footnoteText, zoteroId)}
|
|
155
132
|
</List.Description>
|
|
156
133
|
</List.Content>
|
|
157
134
|
</List.Item>
|
|
@@ -164,16 +141,22 @@ export const FootnoteElement = (props) => {
|
|
|
164
141
|
return (
|
|
165
142
|
<List.Item
|
|
166
143
|
href={`#footnote-${item.zoteroId || item.uid}`}
|
|
167
|
-
onClick={() =>
|
|
144
|
+
onClick={(e) => {
|
|
168
145
|
openAccordionOrTabIfContainsFootnoteReference(
|
|
169
146
|
`#footnote-${item.zoteroId || item.uid}`,
|
|
170
|
-
)
|
|
171
|
-
|
|
147
|
+
);
|
|
148
|
+
if (e.target.tagName !== 'A') {
|
|
149
|
+
e.preventDefault();
|
|
150
|
+
history.push(
|
|
151
|
+
`#footnote-${item.zoteroId || item.uid}`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}}
|
|
172
155
|
key={`#footnote-${item.zoteroId || item.uid}`}
|
|
173
156
|
>
|
|
174
157
|
<List.Content>
|
|
175
158
|
<List.Description>
|
|
176
|
-
{renderTextWithLinks(footnoteText)}
|
|
159
|
+
{renderTextWithLinks(footnoteText, item.zoteroId)}
|
|
177
160
|
</List.Description>
|
|
178
161
|
</List.Content>
|
|
179
162
|
</List.Item>
|
|
@@ -202,16 +185,20 @@ export const FootnoteElement = (props) => {
|
|
|
202
185
|
<List divided relaxed selection>
|
|
203
186
|
<List.Item
|
|
204
187
|
href={`#footnote-${citationRefId}`}
|
|
205
|
-
onClick={() =>
|
|
188
|
+
onClick={(e) => {
|
|
206
189
|
openAccordionOrTabIfContainsFootnoteReference(
|
|
207
190
|
`#footnote-${citationRefId}`,
|
|
208
|
-
)
|
|
209
|
-
|
|
191
|
+
);
|
|
192
|
+
if (e.target.tagName !== 'A') {
|
|
193
|
+
e.preventDefault();
|
|
194
|
+
history.push(`#footnote-${citationRefId}`);
|
|
195
|
+
}
|
|
196
|
+
}}
|
|
210
197
|
key={`#footnote-${citationRefId}`}
|
|
211
198
|
>
|
|
212
199
|
<List.Content>
|
|
213
200
|
<List.Description>
|
|
214
|
-
{renderTextWithLinks(footnoteText)}
|
|
201
|
+
{renderTextWithLinks(footnoteText, zoteroId)}
|
|
215
202
|
</List.Description>
|
|
216
203
|
</List.Content>
|
|
217
204
|
</List.Item>
|
|
@@ -219,16 +206,20 @@ export const FootnoteElement = (props) => {
|
|
|
219
206
|
data.extra.map((item) => (
|
|
220
207
|
<List.Item
|
|
221
208
|
href={`#footnote-${item.zoteroId || item.uid}`}
|
|
222
|
-
onClick={() =>
|
|
209
|
+
onClick={(e) => {
|
|
223
210
|
openAccordionOrTabIfContainsFootnoteReference(
|
|
224
211
|
`#footnote-${item.zoteroId || item.uid}`,
|
|
225
|
-
)
|
|
226
|
-
|
|
212
|
+
);
|
|
213
|
+
if (e.target.tagName !== 'A') {
|
|
214
|
+
e.preventDefault();
|
|
215
|
+
history.push(`#footnote-${citationRefId}`);
|
|
216
|
+
}
|
|
217
|
+
}}
|
|
227
218
|
key={`#footnote-${item.zoteroId || item.uid}`}
|
|
228
219
|
>
|
|
229
220
|
<List.Content>
|
|
230
221
|
<List.Description>
|
|
231
|
-
{renderTextWithLinks(item.footnote)}
|
|
222
|
+
{renderTextWithLinks(item.footnote, item.zoteroId)}
|
|
232
223
|
</List.Description>
|
|
233
224
|
</List.Content>
|
|
234
225
|
</List.Item>
|
package/src/editor/utils.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import config from '@plone/volto/registry';
|
|
2
2
|
import { Node } from 'slate';
|
|
3
3
|
import { getAllBlocks } from '@plone/volto-slate/utils';
|
|
4
|
+
import { escapeRegExp } from 'lodash';
|
|
5
|
+
import { UniversalLink } from '@plone/volto/components';
|
|
6
|
+
const urlRegex =
|
|
7
|
+
/\b((http|https|ftp):\/\/)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(:\d+)?(\/[^\s<>)]*)?(?=\s|$|<|>|\))/g;
|
|
8
|
+
|
|
4
9
|
/**
|
|
5
10
|
* retrive all slate children of nested objects
|
|
6
11
|
* @param {object} path - the keys that we want to extract the slate children from
|
|
@@ -9,7 +14,7 @@ import { getAllBlocks } from '@plone/volto-slate/utils';
|
|
|
9
14
|
* path:{items:'value'}
|
|
10
15
|
* @returns string
|
|
11
16
|
*/
|
|
12
|
-
const retriveValuesOfSlateFromNestedPath = (path, value) => {
|
|
17
|
+
export const retriveValuesOfSlateFromNestedPath = (path, value) => {
|
|
13
18
|
if (Array.isArray(value)) {
|
|
14
19
|
let allSlateValue = [];
|
|
15
20
|
value.forEach((element) => {
|
|
@@ -276,3 +281,72 @@ const iterateFootnoteObj = (notesObjResultTemp, node, parentUid) => {
|
|
|
276
281
|
};
|
|
277
282
|
}
|
|
278
283
|
};
|
|
284
|
+
|
|
285
|
+
export function isValidHTML(htmlString) {
|
|
286
|
+
if (
|
|
287
|
+
__CLIENT__ &&
|
|
288
|
+
typeof window !== 'undefined' &&
|
|
289
|
+
typeof DOMParser !== 'undefined'
|
|
290
|
+
) {
|
|
291
|
+
// The environment is client-side, and DOMParser is available
|
|
292
|
+
const parser = new DOMParser();
|
|
293
|
+
const parsedDocument = parser.parseFromString(htmlString, 'text/html');
|
|
294
|
+
const errors = parsedDocument.querySelectorAll('parsererror');
|
|
295
|
+
return errors.length === 0;
|
|
296
|
+
}
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export const renderTextWithLinks = (text, zoteroId) => {
|
|
301
|
+
if (!text) return null;
|
|
302
|
+
|
|
303
|
+
const links = text.match(urlRegex);
|
|
304
|
+
let isValid = false;
|
|
305
|
+
if (zoteroId && isValidHTML(text)) isValid = true;
|
|
306
|
+
|
|
307
|
+
if (!links) {
|
|
308
|
+
if (isValid)
|
|
309
|
+
return (
|
|
310
|
+
<span
|
|
311
|
+
dangerouslySetInnerHTML={{
|
|
312
|
+
__html: text,
|
|
313
|
+
}}
|
|
314
|
+
/>
|
|
315
|
+
);
|
|
316
|
+
else return text;
|
|
317
|
+
}
|
|
318
|
+
let result = [];
|
|
319
|
+
const parts = text.split(
|
|
320
|
+
new RegExp(`(${links.map((link) => escapeRegExp(link)).join('|')})`),
|
|
321
|
+
);
|
|
322
|
+
parts.forEach((part, index) => {
|
|
323
|
+
if (links.includes(part) && zoteroId) {
|
|
324
|
+
result.push(`
|
|
325
|
+
<a key=link-${index} href=${part} rel="noopener">
|
|
326
|
+
${part}
|
|
327
|
+
</a>`);
|
|
328
|
+
return;
|
|
329
|
+
} else if (links.includes(part)) {
|
|
330
|
+
result.push(
|
|
331
|
+
<UniversalLink
|
|
332
|
+
key={`link-${index}`}
|
|
333
|
+
href={part}
|
|
334
|
+
openLinkInNewTab={false}
|
|
335
|
+
>
|
|
336
|
+
{part}
|
|
337
|
+
</UniversalLink>,
|
|
338
|
+
);
|
|
339
|
+
return;
|
|
340
|
+
} else result.push(part);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
if (isValid)
|
|
344
|
+
return (
|
|
345
|
+
<span
|
|
346
|
+
dangerouslySetInnerHTML={{
|
|
347
|
+
__html: result.reduce((acc, c) => acc + c, ''),
|
|
348
|
+
}}
|
|
349
|
+
/>
|
|
350
|
+
);
|
|
351
|
+
else return <div>{result}</div>;
|
|
352
|
+
};
|
package/src/editor/utils.test.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
openAccordionOrTabIfContainsFootnoteReference,
|
|
3
3
|
getAllBlocksAndSlateFields,
|
|
4
|
+
isValidHTML,
|
|
5
|
+
retriveValuesOfSlateFromNestedPath,
|
|
4
6
|
} from './utils';
|
|
5
7
|
import { getAllBlocks } from '@plone/volto-slate/utils';
|
|
6
8
|
|
|
@@ -8,6 +10,47 @@ jest.mock('@plone/volto-slate/utils', () => ({
|
|
|
8
10
|
getAllBlocks: jest.fn(),
|
|
9
11
|
}));
|
|
10
12
|
|
|
13
|
+
describe('retriveValuesOfSlateFromNestedPath', () => {
|
|
14
|
+
test('should return values for a given string path in an object', () => {
|
|
15
|
+
const obj = { key: ['value1', 'value2'] };
|
|
16
|
+
expect(retriveValuesOfSlateFromNestedPath('key', obj)).toEqual([
|
|
17
|
+
'value1',
|
|
18
|
+
'value2',
|
|
19
|
+
]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('should return an empty array when the path is not found', () => {
|
|
23
|
+
const obj = { key: [] };
|
|
24
|
+
expect(retriveValuesOfSlateFromNestedPath('key', obj)).toEqual([]);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('should return values from an array of objects', () => {
|
|
28
|
+
const objArray = [{ key: ['value1'] }, { key: ['value2'] }];
|
|
29
|
+
expect(retriveValuesOfSlateFromNestedPath('key', objArray)).toEqual([
|
|
30
|
+
'value1',
|
|
31
|
+
'value2',
|
|
32
|
+
]);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('should handle nested object paths', () => {
|
|
36
|
+
const obj = { level1: { level2: ['value'] } };
|
|
37
|
+
expect(
|
|
38
|
+
retriveValuesOfSlateFromNestedPath({ level1: 'level2' }, obj),
|
|
39
|
+
).toEqual(['value']);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('should return an empty array for invalid inputs', () => {
|
|
43
|
+
expect(retriveValuesOfSlateFromNestedPath('key', null)).toEqual([]);
|
|
44
|
+
expect(retriveValuesOfSlateFromNestedPath('key', undefined)).toEqual([]);
|
|
45
|
+
expect(retriveValuesOfSlateFromNestedPath({}, {})).toEqual([]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('should return empty array if given an empty path object', () => {
|
|
49
|
+
expect(retriveValuesOfSlateFromNestedPath({}, { key: 'value' })).toEqual(
|
|
50
|
+
[],
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
11
54
|
describe('openAccordionOrTabIfContainsFootnoteReference', () => {
|
|
12
55
|
it('should open accordion if it contains footnote reference', () => {
|
|
13
56
|
document.body.innerHTML = `
|
|
@@ -197,3 +240,29 @@ describe('getAllBlocksAndSlateFields', () => {
|
|
|
197
240
|
expect(result).toEqual(expected);
|
|
198
241
|
});
|
|
199
242
|
});
|
|
243
|
+
|
|
244
|
+
describe('isValidHTML', () => {
|
|
245
|
+
beforeAll(() => {
|
|
246
|
+
global.DOMParser = class {
|
|
247
|
+
parseFromString(str, type) {
|
|
248
|
+
const doc = {
|
|
249
|
+
querySelectorAll: (selector) => {
|
|
250
|
+
if (selector === 'parsererror' && str.includes('<error>')) {
|
|
251
|
+
return [{}]; // Simulate an error
|
|
252
|
+
}
|
|
253
|
+
return [];
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
return doc;
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test('returns true for valid HTML', () => {
|
|
262
|
+
expect(isValidHTML('<div>Hello</div>')).toBe(true);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
test('returns false for invalid HTML', () => {
|
|
266
|
+
expect(isValidHTML('<error>Invalid HTML</error>')).toBe(false);
|
|
267
|
+
});
|
|
268
|
+
});
|
package/src/index.js
CHANGED
|
@@ -6,6 +6,14 @@ import FootnotesBlockSchema from './Blocks/Footnote/FootnotesBlockSchema';
|
|
|
6
6
|
import { FOOTNOTE } from './constants';
|
|
7
7
|
import installFootnoteEditor from './editor';
|
|
8
8
|
import SearchWidget from '@eeacms/volto-slate-footnote/editor/MultiSelectSearchWidget';
|
|
9
|
+
import { defineMessages } from 'react-intl';
|
|
10
|
+
|
|
11
|
+
defineMessages({
|
|
12
|
+
footnotes: {
|
|
13
|
+
id: 'Footnotes',
|
|
14
|
+
defaultMessage: 'Footnotes',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
9
17
|
|
|
10
18
|
/**
|
|
11
19
|
* @summary Called from Volto to configure new or existing Volto block types.
|