@eeacms/volto-slate-footnote 7.1.1 → 7.2.1
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 +11 -30
- 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 -31
- package/src/Blocks/Footnote/FootnotesBlockView.test.jsx +84 -0
- package/src/Blocks/Footnote/schema.js +37 -8
- package/src/editor/render.jsx +37 -46
- 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,17 @@ 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.1](https://github.com/eea/volto-slate-footnote/compare/7.2.0...7.2.1) - 30 January 2025
|
|
8
|
+
|
|
9
|
+
#### :bug: Bug Fixes
|
|
10
|
+
|
|
11
|
+
- 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)]
|
|
12
|
+
|
|
13
|
+
#### :hammer_and_wrench: Others
|
|
14
|
+
|
|
15
|
+
- i18n: Add german translations [Valentin Dumitru - [`aedee6f`](https://github.com/eea/volto-slate-footnote/commit/aedee6fab827de485137e703854f98d8a29b45e9)]
|
|
16
|
+
### [7.2.0](https://github.com/eea/volto-slate-footnote/compare/7.1.1...7.2.0) - 28 November 2024
|
|
17
|
+
|
|
7
18
|
### [7.1.1](https://github.com/eea/volto-slate-footnote/compare/7.1.0...7.1.1) - 16 September 2024
|
|
8
19
|
|
|
9
20
|
### [7.1.0](https://github.com/eea/volto-slate-footnote/compare/7.0.1...7.1.0) - 13 September 2024
|
|
@@ -29,8 +40,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
29
40
|
|
|
30
41
|
#### :hammer_and_wrench: Others
|
|
31
42
|
|
|
32
|
-
- Add Sonarqube tag using insitu-frontend addons list [EEA Jenkins - [`1258c37`](https://github.com/eea/volto-slate-footnote/commit/1258c370d2ce42ddff78d6b749ab8c45897991d3)]
|
|
33
|
-
- Add Sonarqube tag using freshwater-frontend addons list [EEA Jenkins - [`e1031b1`](https://github.com/eea/volto-slate-footnote/commit/e1031b1db0a34679e0bb312e8f0db9433bf08498)]
|
|
34
43
|
### [6.3.0](https://github.com/eea/volto-slate-footnote/compare/6.2.3...6.3.0) - 28 March 2024
|
|
35
44
|
|
|
36
45
|
#### :hammer_and_wrench: Others
|
|
@@ -50,7 +59,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
50
59
|
|
|
51
60
|
#### :hammer_and_wrench: Others
|
|
52
61
|
|
|
53
|
-
- Add Sonarqube tag using insitu-frontend addons list [EEA Jenkins - [`aa335f9`](https://github.com/eea/volto-slate-footnote/commit/aa335f9eedd9d994b6fbceb57102d848dbdbae15)]
|
|
54
62
|
### [6.2.2](https://github.com/eea/volto-slate-footnote/compare/6.2.1...6.2.2) - 20 January 2024
|
|
55
63
|
|
|
56
64
|
#### :hammer_and_wrench: Others
|
|
@@ -75,15 +83,9 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
75
83
|
|
|
76
84
|
#### :house: Internal changes
|
|
77
85
|
|
|
78
|
-
- chore: [JENKINS] Refactor automated testing [valentinab25 - [`5a5e1ad`](https://github.com/eea/volto-slate-footnote/commit/5a5e1adf997af84e93a4015dc66b7299abba0874)]
|
|
79
86
|
|
|
80
87
|
#### :hammer_and_wrench: Others
|
|
81
88
|
|
|
82
|
-
- test: [JENKINS] Use java17 for sonarqube scanner [valentinab25 - [`af6d78f`](https://github.com/eea/volto-slate-footnote/commit/af6d78f60dd040fe61ebb225f4a689ac21ffb55c)]
|
|
83
|
-
- test: [JENKINS] Run cypress in started frontend container [valentinab25 - [`7f4c07f`](https://github.com/eea/volto-slate-footnote/commit/7f4c07f1fc2e9893d1f925152a473855a7e0f064)]
|
|
84
|
-
- test: [JENKINS] Add cpu limit on cypress docker [valentinab25 - [`0670217`](https://github.com/eea/volto-slate-footnote/commit/0670217cca01571e8a3bd64ee3d85bb53ce447be)]
|
|
85
|
-
- test: [JENKINS] Increase shm-size to cypress docker [valentinab25 - [`ec08749`](https://github.com/eea/volto-slate-footnote/commit/ec08749f9547d2c133b2174ab8d60cf2bdb1b23a)]
|
|
86
|
-
- test: [JENKINS] Improve cypress time [valentinab25 - [`237e6a3`](https://github.com/eea/volto-slate-footnote/commit/237e6a331e3608aa35d1c93a03c435daf330c2bd)]
|
|
87
89
|
### [6.1.8](https://github.com/eea/volto-slate-footnote/compare/6.1.7...6.1.8) - 22 October 2023
|
|
88
90
|
|
|
89
91
|
#### :house: Internal changes
|
|
@@ -153,25 +155,17 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
153
155
|
|
|
154
156
|
#### :house: Internal changes
|
|
155
157
|
|
|
156
|
-
- chore: [JENKINS] Deprecate circularity website [valentinab25 - [`ded882a`](https://github.com/eea/volto-slate-footnote/commit/ded882a1ca1183c2ba74ff4246111123ee36e6cb)]
|
|
157
158
|
|
|
158
159
|
#### :hammer_and_wrench: Others
|
|
159
160
|
|
|
160
161
|
- test: jest should look for addons in node_modules Refs #253277 [valentinab25 - [`3e0749c`](https://github.com/eea/volto-slate-footnote/commit/3e0749cc5bd7f5810ac6fd7a3feee4df0435ee0a)]
|
|
161
162
|
- test: Add unit tests for utils - refs #253277 [ana-oprea - [`a709895`](https://github.com/eea/volto-slate-footnote/commit/a709895d9953742ef6d39f8d9673c06b2efe6a64)]
|
|
162
163
|
- test: Fix test config, coverage Refs #253277 [valentinab25 - [`dc4d6dc`](https://github.com/eea/volto-slate-footnote/commit/dc4d6dc9b39bfe2c892156f32c764153d1366486)]
|
|
163
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`4f0ecee`](https://github.com/eea/volto-slate-footnote/commit/4f0ecee224d5d6604dfbb562556e45437edbb8ec)]
|
|
164
164
|
### [6.1.0](https://github.com/eea/volto-slate-footnote/compare/6.0.2...6.1.0) - 27 March 2023
|
|
165
165
|
|
|
166
166
|
#### :hammer_and_wrench: Others
|
|
167
167
|
|
|
168
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`23959ee`](https://github.com/eea/volto-slate-footnote/commit/23959ee43d45ec5eaa483590415a75fc58faae03)]
|
|
169
|
-
- Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`7aa6f34`](https://github.com/eea/volto-slate-footnote/commit/7aa6f3439953cc3d8f28875eff9fbcc24084cbc7)]
|
|
170
|
-
- Add Sonarqube tag using advisory-board-frontend addons list [EEA Jenkins - [`b117d15`](https://github.com/eea/volto-slate-footnote/commit/b117d15e51b3cf10717b9dd9dfef8304d46ad556)]
|
|
171
168
|
- test(Jenkins): Run tests and cypress with latest canary @plone/volto [Alin Voinea - [`97ed8fb`](https://github.com/eea/volto-slate-footnote/commit/97ed8fbd92f76c2b3128b62cdc1a77611e79410a)]
|
|
172
|
-
- Add Sonarqube tag using cca-frontend addons list [EEA Jenkins - [`cb22f5e`](https://github.com/eea/volto-slate-footnote/commit/cb22f5e8e9d3aed0a3b4374b6d4d80c8c2bb66e1)]
|
|
173
|
-
- yarn 3 [Alin Voinea - [`f5bb904`](https://github.com/eea/volto-slate-footnote/commit/f5bb904eecf740ffd57dbccf9a597c99ea2dfc0c)]
|
|
174
|
-
- Add Sonarqube tag using demo-kitkat-frontend addons list [EEA Jenkins - [`59cf6d3`](https://github.com/eea/volto-slate-footnote/commit/59cf6d334a460e373dda3e2e28754fcdd9fb0281)]
|
|
175
169
|
### [6.0.2](https://github.com/eea/volto-slate-footnote/compare/6.0.1...6.0.2) - 16 November 2022
|
|
176
170
|
|
|
177
171
|
#### :hammer_and_wrench: Others
|
|
@@ -187,37 +181,27 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
187
181
|
|
|
188
182
|
#### :hammer_and_wrench: Others
|
|
189
183
|
|
|
190
|
-
- Add Sonarqube tag using marine-frontend addons list [EEA Jenkins - [`dc3c7de`](https://github.com/eea/volto-slate-footnote/commit/dc3c7deaa8c692689ea0cec66cf019f05f9c4e22)]
|
|
191
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`133969a`](https://github.com/eea/volto-slate-footnote/commit/133969a37a6153a19af121d2f6031a70bc67cc9d)]
|
|
192
184
|
### [5.0.1](https://github.com/eea/volto-slate-footnote/compare/5.0.0...5.0.1) - 30 June 2022
|
|
193
185
|
|
|
194
186
|
#### :hammer_and_wrench: Others
|
|
195
187
|
|
|
196
|
-
- Add Sonarqube tag using circularity-frontend addons list [EEA Jenkins - [`4d5af13`](https://github.com/eea/volto-slate-footnote/commit/4d5af1345aad9071c031f7f00efd6bc5da04541f)]
|
|
197
188
|
## [5.0.0](https://github.com/eea/volto-slate-footnote/compare/4.0.5...5.0.0) - 19 May 2022
|
|
198
189
|
|
|
199
190
|
### [4.0.5](https://github.com/eea/volto-slate-footnote/compare/4.0.4...4.0.5) - 17 May 2022
|
|
200
191
|
|
|
201
192
|
#### :hammer_and_wrench: Others
|
|
202
193
|
|
|
203
|
-
- Add Sonarqube tag using clms-frontend addons list [EEA Jenkins - [`85a16ee`](https://github.com/eea/volto-slate-footnote/commit/85a16ee73d21d696282dc24933169d3c31383027)]
|
|
204
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`418349c`](https://github.com/eea/volto-slate-footnote/commit/418349ce22d98bf5dee58130d6f1cb9f45bbaa46)]
|
|
205
194
|
### [4.0.4](https://github.com/eea/volto-slate-footnote/compare/4.0.3...4.0.4) - 3 January 2022
|
|
206
195
|
|
|
207
196
|
### [4.0.3](https://github.com/eea/volto-slate-footnote/compare/4.0.2...4.0.3) - 18 December 2021
|
|
208
197
|
|
|
209
198
|
#### :hammer_and_wrench: Others
|
|
210
199
|
|
|
211
|
-
- Add Sonarqube tag using freshwater-frontend addons list [EEA Jenkins - [`ad06940`](https://github.com/eea/volto-slate-footnote/commit/ad0694074a06eb56ec1891256b262e9854c0303d)]
|
|
212
200
|
- Refs #142010 - Optimize Volto-addons gitflow pipelines [valentinab25 - [`1081079`](https://github.com/eea/volto-slate-footnote/commit/1081079444f5ac806e9d56765c4ccf0b9e415a73)]
|
|
213
|
-
- Add Sonarqube tag using industry-frontend addons list [EEA Jenkins - [`307687b`](https://github.com/eea/volto-slate-footnote/commit/307687b93d966e0df5c4a3f813dbb19442d2e169)]
|
|
214
|
-
- Add Sonarqube tag using clms-frontend addons list [EEA Jenkins - [`0460e2a`](https://github.com/eea/volto-slate-footnote/commit/0460e2a73a4c8ede00b0c1fc3f05624eaa345a33)]
|
|
215
|
-
- Add Sonarqube tag using forests-frontend addons list [EEA Jenkins - [`8aecee9`](https://github.com/eea/volto-slate-footnote/commit/8aecee99f11387e4ce31825209798772d7fee060)]
|
|
216
201
|
### [4.0.2](https://github.com/eea/volto-slate-footnote/compare/4.0.1...4.0.2) - 30 September 2021
|
|
217
202
|
|
|
218
203
|
#### :hammer_and_wrench: Others
|
|
219
204
|
|
|
220
|
-
- Add Sonarqube tag using sustainability-frontend addons list [EEA Jenkins - [`cf33efe`](https://github.com/eea/volto-slate-footnote/commit/cf33efec91b4b8d13562b8c8f660e7a78191d9e0)]
|
|
221
205
|
- Remove :asDefault dependency from volto-slate [Alin Voinea - [`13dad5e`](https://github.com/eea/volto-slate-footnote/commit/13dad5ed23043fa7a24682e1ac6addc86632bfe0)]
|
|
222
206
|
### [4.0.1](https://github.com/eea/volto-slate-footnote/compare/4.0.0...4.0.1) - 29 September 2021
|
|
223
207
|
|
|
@@ -225,7 +209,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
225
209
|
|
|
226
210
|
#### :hammer_and_wrench: Others
|
|
227
211
|
|
|
228
|
-
- Add Sonarqube tag using climate-energy-frontend addons list [EEA Jenkins - [`80a159b`](https://github.com/eea/volto-slate-footnote/commit/80a159bb67698cddedadc494e7ae2da32a96faea)]
|
|
229
212
|
### [3.2.0](https://github.com/eea/volto-slate-footnote/compare/3.1.1...3.2.0) - 13 September 2021
|
|
230
213
|
|
|
231
214
|
#### :hammer_and_wrench: Others
|
|
@@ -238,7 +221,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
238
221
|
- Remove console.log [Alin Voinea - [`b5d83e7`](https://github.com/eea/volto-slate-footnote/commit/b5d83e7c13240151f602d122ecf09ba9b8e335f3)]
|
|
239
222
|
- Fix slate json field default value in DX layout [Alin Voinea - [`f2805bb`](https://github.com/eea/volto-slate-footnote/commit/f2805bbc15c51ebd914ee5f4eb9dd34ef32e095b)]
|
|
240
223
|
- Fix cypress api_url [Alin Voinea - [`6a4966a`](https://github.com/eea/volto-slate-footnote/commit/6a4966a2f92e932e1d0df35351989cda535f15c8)]
|
|
241
|
-
- Add Sonarqube tag using ims-frontend addons list [EEA Jenkins - [`aed3984`](https://github.com/eea/volto-slate-footnote/commit/aed39840ecd467689eaf0adb352bd00ce95bdbbe)]
|
|
242
224
|
### [3.1.0](https://github.com/eea/volto-slate-footnote/compare/3.0.0...3.1.0) - 9 September 2021
|
|
243
225
|
|
|
244
226
|
#### :hammer_and_wrench: Others
|
|
@@ -259,7 +241,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
259
241
|
- Bump version to 2.4.0 [Alin Voinea - [`bef0d34`](https://github.com/eea/volto-slate-footnote/commit/bef0d34c2b9c20915578ffaefb4fd30cbf42f0a1)]
|
|
260
242
|
- Fix Slate point from DOM crash [Alin Voinea - [`c852f79`](https://github.com/eea/volto-slate-footnote/commit/c852f7987ffe8db433235b70792002d40ade690f)]
|
|
261
243
|
- Fix crash on copy&paste beforeInsert condition [Alin Voinea - [`85172cf`](https://github.com/eea/volto-slate-footnote/commit/85172cff3e2ea95a86d4b4fb452f3c0287b80e8f)]
|
|
262
|
-
- Add Sonarqube tag using frontend addons list [EEA Jenkins - [`b471c41`](https://github.com/eea/volto-slate-footnote/commit/b471c418d198b1bde95acfe0b256f642bacc6865)]
|
|
263
244
|
### [2.3.1](https://github.com/eea/volto-slate-footnote/compare/2.3.0...2.3.1) - 25 June 2021
|
|
264
245
|
|
|
265
246
|
### [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,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
|
|
2
3
|
import {
|
|
3
4
|
openAccordionOrTabIfContainsFootnoteReference,
|
|
4
5
|
getAllBlocksAndSlateFields,
|
|
@@ -7,9 +8,9 @@ import {
|
|
|
7
8
|
import './less/public.less';
|
|
8
9
|
|
|
9
10
|
import { UniversalLink } from '@plone/volto/components';
|
|
11
|
+
import { renderTextWithLinks } from '../../editor/utils';
|
|
10
12
|
|
|
11
13
|
const alphabet = 'abcdefghijklmnopqrstuvwxyz';
|
|
12
|
-
const urlRegex = /https?:\/\/[^\s]+/g;
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* @summary The React component that displays the list of footnotes inserted
|
|
@@ -76,35 +77,6 @@ const FootnotesBlockView = (props) => {
|
|
|
76
77
|
startList = citationIndice;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
const renderTextWithLinks = (text) => {
|
|
80
|
-
if (!text) return null;
|
|
81
|
-
const parts = text.split(urlRegex);
|
|
82
|
-
const links = text.match(urlRegex);
|
|
83
|
-
let result = [];
|
|
84
|
-
|
|
85
|
-
parts.forEach((part, index) => {
|
|
86
|
-
result.push(
|
|
87
|
-
<div
|
|
88
|
-
dangerouslySetInnerHTML={{
|
|
89
|
-
__html: part,
|
|
90
|
-
}}
|
|
91
|
-
/>,
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
if (links && links[index]) {
|
|
95
|
-
result.push(
|
|
96
|
-
<UniversalLink
|
|
97
|
-
key={`link-${index}`}
|
|
98
|
-
href={links[index]}
|
|
99
|
-
openLinkInNewTab={false}
|
|
100
|
-
>
|
|
101
|
-
{links[index]}
|
|
102
|
-
</UniversalLink>,
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
return result;
|
|
107
|
-
};
|
|
108
80
|
return (
|
|
109
81
|
<div className="footnotes-listing-block">
|
|
110
82
|
<h3 title={placeholder}>{title}</h3>
|
|
@@ -127,7 +99,7 @@ const FootnotesBlockView = (props) => {
|
|
|
127
99
|
key={`footnote-${zoteroId || uid}`}
|
|
128
100
|
id={`footnote-${zoteroId || uid}`}
|
|
129
101
|
>
|
|
130
|
-
<div>{renderTextWithLinks(footnoteText)}</div>
|
|
102
|
+
<div>{renderTextWithLinks(footnoteText, zoteroId)}</div>
|
|
131
103
|
{refsList ? (
|
|
132
104
|
<>
|
|
133
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,11 +185,15 @@ 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>
|
|
@@ -219,11 +206,15 @@ 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>
|
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.
|