@plone/volto 18.9.0 → 18.9.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 +28 -0
- package/README.md +0 -1
- package/package.json +3 -3
- package/src/components/manage/Add/Add.jsx +5 -1
- package/src/components/manage/AnchorPlugin/components/LinkButton/AddLinkForm.jsx +2 -0
- package/src/components/manage/BlockChooser/BlockChooser.jsx +1 -0
- package/src/components/manage/BlockChooser/BlockChooserButton.jsx +1 -0
- package/src/components/manage/BlockChooser/BlockChooserSearch.jsx +1 -0
- package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +1 -0
- package/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +2 -0
- package/src/components/manage/Blocks/Container/NewBlockAddButton.jsx +1 -0
- package/src/components/manage/Blocks/Container/SimpleContainerToolbar.jsx +2 -0
- package/src/components/manage/Blocks/HTML/Edit.jsx +9 -1
- package/src/components/manage/Blocks/Image/ImageSidebar.jsx +1 -0
- package/src/components/manage/Blocks/Listing/ImageGallery.jsx +2 -0
- package/src/components/manage/Blocks/Maps/Edit.jsx +2 -0
- package/src/components/manage/Blocks/Search/components/Facets.jsx +1 -0
- package/src/components/manage/Blocks/Search/components/FilterList.jsx +1 -0
- package/src/components/manage/Blocks/Search/components/SearchInput.jsx +1 -0
- package/src/components/manage/Blocks/Search/components/SortOn.jsx +2 -0
- package/src/components/manage/Blocks/Teaser/Data.jsx +2 -0
- package/src/components/manage/Blocks/Video/Edit.jsx +2 -0
- package/src/components/manage/Delete/Delete.jsx +1 -0
- package/src/components/manage/Diff/Diff.jsx +1 -0
- package/src/components/manage/Edit/Edit.jsx +1 -0
- package/src/components/manage/Form/Form.jsx +1 -0
- package/src/components/manage/Form/ModalForm.jsx +1 -0
- package/src/components/manage/Form/UndoToolbar.jsx +2 -0
- package/src/components/manage/Sidebar/AlignBlock.jsx +1 -0
- package/src/components/manage/Sidebar/ObjectBrowserNav.jsx +1 -0
- package/src/components/manage/Sidebar/Sidebar.jsx +2 -0
- package/src/components/manage/TemplateChooser/TemplateChooser.jsx +1 -0
- package/src/components/manage/Widgets/CheckboxWidget.jsx +1 -0
- package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.jsx +2 -1
- package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.test.jsx +67 -10
- package/src/components/theme/Comments/Comments.jsx +1 -1
- package/src/components/theme/Image/Image.jsx +1 -2
- package/src/components/theme/Image/Image.test.jsx +8 -0
- package/src/storybook.jsx +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,34 @@ myst:
|
|
|
17
17
|
|
|
18
18
|
<!-- towncrier release notes start -->
|
|
19
19
|
|
|
20
|
+
## 18.9.2 (2025-03-07)
|
|
21
|
+
|
|
22
|
+
### Bugfix
|
|
23
|
+
|
|
24
|
+
- Does not show empty `class` attribute when rendering `img` tag with `Image` component. @wesleybl [#6788](https://github.com/plone/volto/issues/6788)
|
|
25
|
+
- Fixed button types across several components to allow reuse in more complex forms @pnicolli [#6791](https://github.com/plone/volto/issues/6791)
|
|
26
|
+
- Fixed `AlternateHrefLangs` component, missing `FlattenToAppURL`. @sneridagh [#6799](https://github.com/plone/volto/issues/6799)
|
|
27
|
+
- a11y - Added id attribute to checkbox widget for proper identification and fixes label functionality for screen readers. @Wagner3UB [#6802](https://github.com/plone/volto/issues/6802)
|
|
28
|
+
|
|
29
|
+
### Documentation
|
|
30
|
+
|
|
31
|
+
- Improve the wording on theming docs. @erral [#6767](https://github.com/plone/volto/issues/6767)
|
|
32
|
+
- Fix MyST warnings about bad references, remove cookiecutter-plone-starter link, and remove `rietveldschroderhuis.nl` due to repeated failures and no response in https://github.com/collective/awesome-volto/pull/27. @stevepiercy [#6812](https://github.com/plone/volto/issues/6812)
|
|
33
|
+
|
|
34
|
+
## 18.9.1 (2025-02-20)
|
|
35
|
+
|
|
36
|
+
### Bugfix
|
|
37
|
+
|
|
38
|
+
- Fix load more comments link. @sneridagh [#6759](https://github.com/plone/volto/issues/6759)
|
|
39
|
+
|
|
40
|
+
### Internal
|
|
41
|
+
|
|
42
|
+
- Move Seven to its own branch. @sneridagh [#6769](https://github.com/plone/volto/issues/6769)
|
|
43
|
+
|
|
44
|
+
### Documentation
|
|
45
|
+
|
|
46
|
+
- Fix reference to `link.svg` and include of `_inc/_install-browser-reqs-volto.md`. @stevepiercy [#6760](https://github.com/plone/volto/issues/6760)
|
|
47
|
+
|
|
20
48
|
## 18.9.0 (2025-02-17)
|
|
21
49
|
|
|
22
50
|
### Feature
|
package/README.md
CHANGED
|
@@ -194,5 +194,4 @@ You should check the dependencies in their `package.json` for more details.
|
|
|
194
194
|
- [volto-centraalmuseum-theme](https://github.com/intk/volto-centraalmuseum-theme) - Volto project for the [Centraal Museum & Rietveld](https://www.centraalmuseum.nl/nl) made for [INTK](https://www.intk.com/en).
|
|
195
195
|
- [volto-eea-design-system](https://github.com/eea/volto-eea-design-system) - EEA Design System Plone 6 Kit Volto project for [European Environment Agency web sites](https://eea.github.io/volto-eea-design-system/)
|
|
196
196
|
- [volto-eea-kitkat](https://github.com/eea/volto-eea-kitkat) - A known good set of Volto add-ons to be used within all EEA projects and beyond, made for [European Environment Agency](https://www.eea.europa.eu/en)
|
|
197
|
-
- [volto-rietveldschroderhuis-theme](https://github.com/intk/volto-rietveldschroderhuis-theme) - Volto project for the [Rietveld Schröder House](https://www.rietveldschroderhuis.nl/en) made for [INTK](https://www.intk.com/en).
|
|
198
197
|
- [volto-zeeuwsmuseum-theme](https://github.com/intk/volto-zeeuwsmuseum-theme) - Volto project for the [Zeeuws Museum](https://www.zeeuwsmuseum.nl/en) made for [INTK](https://www.intk.com/en).
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
}
|
|
10
10
|
],
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"version": "18.9.
|
|
12
|
+
"version": "18.9.2",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
15
|
"url": "git@github.com:plone/volto.git"
|
|
@@ -237,8 +237,8 @@
|
|
|
237
237
|
"use-deep-compare-effect": "1.8.1",
|
|
238
238
|
"uuid": "^8.3.2",
|
|
239
239
|
"@plone/registry": "2.4.1",
|
|
240
|
-
"@plone/
|
|
241
|
-
"@plone/
|
|
240
|
+
"@plone/volto-slate": "18.2.3",
|
|
241
|
+
"@plone/scripts": "3.8.2"
|
|
242
242
|
},
|
|
243
243
|
"devDependencies": {
|
|
244
244
|
"@babel/core": "^7.0.0",
|
|
@@ -425,7 +425,11 @@ class Add extends Component {
|
|
|
425
425
|
title={this.props.intl.formatMessage(messages.save)}
|
|
426
426
|
/>
|
|
427
427
|
</Button>
|
|
428
|
-
<Button
|
|
428
|
+
<Button
|
|
429
|
+
className="cancel"
|
|
430
|
+
onClick={() => this.onCancel()}
|
|
431
|
+
type="button"
|
|
432
|
+
>
|
|
429
433
|
<Icon
|
|
430
434
|
name={clearSVG}
|
|
431
435
|
className="circled"
|
|
@@ -258,6 +258,7 @@ class AddLinkForm extends Component {
|
|
|
258
258
|
{value.length > 0 ? (
|
|
259
259
|
<Button.Group>
|
|
260
260
|
<Button
|
|
261
|
+
type="button"
|
|
261
262
|
basic
|
|
262
263
|
className="cancel"
|
|
263
264
|
aria-label={this.props.intl.formatMessage(messages.clear)}
|
|
@@ -274,6 +275,7 @@ class AddLinkForm extends Component {
|
|
|
274
275
|
) : this.props.objectBrowserPickerType === 'link' ? (
|
|
275
276
|
<Button.Group>
|
|
276
277
|
<Button
|
|
278
|
+
type="button"
|
|
277
279
|
basic
|
|
278
280
|
icon
|
|
279
281
|
aria-label={this.props.intl.formatMessage(
|
|
@@ -66,6 +66,7 @@ const EditBlockWrapper = (props) => {
|
|
|
66
66
|
aria-label={intl.formatMessage(messages.reset, {
|
|
67
67
|
index,
|
|
68
68
|
})}
|
|
69
|
+
type="button"
|
|
69
70
|
basic
|
|
70
71
|
icon
|
|
71
72
|
onClick={(e) => onResetBlock(block, {})}
|
|
@@ -75,6 +76,7 @@ const EditBlockWrapper = (props) => {
|
|
|
75
76
|
</Button>
|
|
76
77
|
) : (
|
|
77
78
|
<Button
|
|
79
|
+
type="button"
|
|
78
80
|
basic
|
|
79
81
|
icon
|
|
80
82
|
className="remove-block-button"
|
|
@@ -25,6 +25,7 @@ const SimpleContainerToolbar = (props) => {
|
|
|
25
25
|
<Button.Group>
|
|
26
26
|
<Button
|
|
27
27
|
aria-label={intl.formatMessage(messages.addBlock)}
|
|
28
|
+
type="button"
|
|
28
29
|
icon
|
|
29
30
|
basic
|
|
30
31
|
disabled={data?.blocks_layout?.items?.length >= maxLength}
|
|
@@ -36,6 +37,7 @@ const SimpleContainerToolbar = (props) => {
|
|
|
36
37
|
<Button.Group>
|
|
37
38
|
<Button
|
|
38
39
|
aria-label={intl.formatMessage(messages.blockSettings)}
|
|
40
|
+
type="button"
|
|
39
41
|
icon
|
|
40
42
|
basic
|
|
41
43
|
onClick={(e) => {
|
|
@@ -248,6 +248,7 @@ class Edit extends Component {
|
|
|
248
248
|
<Popup
|
|
249
249
|
trigger={
|
|
250
250
|
<Button
|
|
251
|
+
type="button"
|
|
251
252
|
icon
|
|
252
253
|
basic
|
|
253
254
|
aria-label={this.props.intl.formatMessage(messages.source)}
|
|
@@ -264,6 +265,7 @@ class Edit extends Component {
|
|
|
264
265
|
<Popup
|
|
265
266
|
trigger={
|
|
266
267
|
<Button
|
|
268
|
+
type="button"
|
|
267
269
|
icon
|
|
268
270
|
basic
|
|
269
271
|
aria-label={this.props.intl.formatMessage(messages.preview)}
|
|
@@ -280,6 +282,7 @@ class Edit extends Component {
|
|
|
280
282
|
<Popup
|
|
281
283
|
trigger={
|
|
282
284
|
<Button
|
|
285
|
+
type="button"
|
|
283
286
|
icon
|
|
284
287
|
basic
|
|
285
288
|
aria-label={this.props.intl.formatMessage(messages.prettier)}
|
|
@@ -296,7 +299,12 @@ class Edit extends Component {
|
|
|
296
299
|
<Popup
|
|
297
300
|
trigger={
|
|
298
301
|
<Button.Group>
|
|
299
|
-
<Button
|
|
302
|
+
<Button
|
|
303
|
+
type="button"
|
|
304
|
+
icon
|
|
305
|
+
basic
|
|
306
|
+
onClick={() => this.onChangeCode('')}
|
|
307
|
+
>
|
|
300
308
|
<Icon name={clearSVG} size="24px" color="#e40166" />
|
|
301
309
|
</Button>
|
|
302
310
|
</Button.Group>
|
|
@@ -19,6 +19,7 @@ const ImageGallery = loadable(() => import('react-image-gallery'));
|
|
|
19
19
|
const renderLeftNav = (onClick, disabled) => {
|
|
20
20
|
return (
|
|
21
21
|
<Button
|
|
22
|
+
type="button"
|
|
22
23
|
className="image-gallery-icon image-gallery-left-nav primary basic"
|
|
23
24
|
disabled={disabled}
|
|
24
25
|
onClick={onClick}
|
|
@@ -30,6 +31,7 @@ const renderLeftNav = (onClick, disabled) => {
|
|
|
30
31
|
const renderRightNav = (onClick, disabled) => {
|
|
31
32
|
return (
|
|
32
33
|
<Button
|
|
34
|
+
type="button"
|
|
33
35
|
className="image-gallery-icon image-gallery-right-nav primary basic"
|
|
34
36
|
disabled={disabled}
|
|
35
37
|
onClick={onClick}
|
|
@@ -135,6 +135,7 @@ const Edit = React.memo((props) => {
|
|
|
135
135
|
{url && (
|
|
136
136
|
<Button.Group>
|
|
137
137
|
<Button
|
|
138
|
+
type="button"
|
|
138
139
|
basic
|
|
139
140
|
className="cancel"
|
|
140
141
|
onClick={(e) => {
|
|
@@ -148,6 +149,7 @@ const Edit = React.memo((props) => {
|
|
|
148
149
|
)}
|
|
149
150
|
<Button.Group>
|
|
150
151
|
<Button
|
|
152
|
+
type="button"
|
|
151
153
|
basic
|
|
152
154
|
primary
|
|
153
155
|
onClick={(e) => {
|
|
@@ -113,6 +113,7 @@ const SortOn = (props) => {
|
|
|
113
113
|
{activeSortOn ? (
|
|
114
114
|
<>
|
|
115
115
|
<Button
|
|
116
|
+
type="button"
|
|
116
117
|
icon
|
|
117
118
|
basic
|
|
118
119
|
compact
|
|
@@ -127,6 +128,7 @@ const SortOn = (props) => {
|
|
|
127
128
|
<Icon name={downSVG} size="25px" />
|
|
128
129
|
</Button>
|
|
129
130
|
<Button
|
|
131
|
+
type="button"
|
|
130
132
|
icon
|
|
131
133
|
basic
|
|
132
134
|
compact
|
|
@@ -117,6 +117,7 @@ const TeaserData = (props) => {
|
|
|
117
117
|
<Button.Group>
|
|
118
118
|
<Button
|
|
119
119
|
aria-label={intl.formatMessage(messages.resetTeaser)}
|
|
120
|
+
type="button"
|
|
120
121
|
basic
|
|
121
122
|
disabled={isReseteable}
|
|
122
123
|
onClick={() => reset()}
|
|
@@ -130,6 +131,7 @@ const TeaserData = (props) => {
|
|
|
130
131
|
<Button.Group className="refresh teaser">
|
|
131
132
|
<Button
|
|
132
133
|
aria-label={intl.formatMessage(messages.refreshTeaser)}
|
|
134
|
+
type="button"
|
|
133
135
|
basic
|
|
134
136
|
onClick={() => refresh()}
|
|
135
137
|
disabled={isEmpty(data.href)}
|
|
@@ -96,6 +96,7 @@ const Edit = (props) => {
|
|
|
96
96
|
{url && (
|
|
97
97
|
<Button.Group>
|
|
98
98
|
<Button
|
|
99
|
+
type="button"
|
|
99
100
|
basic
|
|
100
101
|
className="cancel"
|
|
101
102
|
onClick={(e) => {
|
|
@@ -109,6 +110,7 @@ const Edit = (props) => {
|
|
|
109
110
|
)}
|
|
110
111
|
<Button.Group>
|
|
111
112
|
<Button
|
|
113
|
+
type="button"
|
|
112
114
|
basic
|
|
113
115
|
primary
|
|
114
116
|
onClick={(e) => {
|
|
@@ -39,6 +39,7 @@ const UndoToolbar = ({ state, onUndoRedo, maxUndoLevels, enableHotKeys }) => {
|
|
|
39
39
|
dependencies={[canUndo, canRedo]}
|
|
40
40
|
>
|
|
41
41
|
<Button
|
|
42
|
+
type="button"
|
|
42
43
|
className="undo"
|
|
43
44
|
onClick={() => doUndo()}
|
|
44
45
|
aria-label={intl.formatMessage(messages.undo)}
|
|
@@ -58,6 +59,7 @@ const UndoToolbar = ({ state, onUndoRedo, maxUndoLevels, enableHotKeys }) => {
|
|
|
58
59
|
dependencies={[canUndo, canRedo]}
|
|
59
60
|
>
|
|
60
61
|
<Button
|
|
62
|
+
type="button"
|
|
61
63
|
className="redo"
|
|
62
64
|
onClick={() => doRedo()}
|
|
63
65
|
aria-label={intl.formatMessage(messages.redo)}
|
|
@@ -113,6 +113,7 @@ const Sidebar = (props) => {
|
|
|
113
113
|
style={size > 0 ? { width: size } : null}
|
|
114
114
|
>
|
|
115
115
|
<Button
|
|
116
|
+
type="button"
|
|
116
117
|
aria-label={
|
|
117
118
|
expanded
|
|
118
119
|
? intl.formatMessage(messages.shrinkSidebar)
|
|
@@ -126,6 +127,7 @@ const Sidebar = (props) => {
|
|
|
126
127
|
onClick={onToggleExpanded}
|
|
127
128
|
/>
|
|
128
129
|
<Button
|
|
130
|
+
type="button"
|
|
129
131
|
className="full-size-sidenav-btn"
|
|
130
132
|
onClick={onToggleFullSize}
|
|
131
133
|
aria-label="full-screen-sidenav"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import config from '@plone/volto/registry';
|
|
2
2
|
import Helmet from '@plone/volto/helpers/Helmet/Helmet';
|
|
3
|
+
import { flattenToAppURL, toPublicURL } from '@plone/volto/helpers/Url/Url';
|
|
3
4
|
|
|
4
5
|
const AlternateHrefLangs = (props) => {
|
|
5
6
|
const { content } = props;
|
|
@@ -16,7 +17,7 @@ const AlternateHrefLangs = (props) => {
|
|
|
16
17
|
key={key}
|
|
17
18
|
rel="alternate"
|
|
18
19
|
hrefLang={item.language}
|
|
19
|
-
href={item['@id']}
|
|
20
|
+
href={toPublicURL(flattenToAppURL(item['@id']))}
|
|
20
21
|
/>
|
|
21
22
|
);
|
|
22
23
|
})}
|
|
@@ -35,16 +35,18 @@ describe('AlternateHrefLangs', () => {
|
|
|
35
35
|
const helmetLinks = Helmet.peek().linkTags;
|
|
36
36
|
expect(helmetLinks.length).toBe(0);
|
|
37
37
|
});
|
|
38
|
+
|
|
38
39
|
it('multilingual site, with some translations', () => {
|
|
40
|
+
config.settings.publicURL = 'https://plone.org';
|
|
39
41
|
config.settings.isMultilingual = true;
|
|
40
42
|
config.settings.supportedLanguages = ['en', 'es', 'eu'];
|
|
41
43
|
|
|
42
44
|
const content = {
|
|
43
|
-
'@id': '/en',
|
|
45
|
+
'@id': 'http://localhost:8080/Plone/en',
|
|
44
46
|
language: { token: 'en', title: 'English' },
|
|
45
47
|
'@components': {
|
|
46
48
|
translations: {
|
|
47
|
-
items: [{ '@id': '/es', language: 'es' }],
|
|
49
|
+
items: [{ '@id': 'http://localhost:8080/Plone/es', language: 'es' }],
|
|
48
50
|
},
|
|
49
51
|
},
|
|
50
52
|
};
|
|
@@ -71,17 +73,72 @@ describe('AlternateHrefLangs', () => {
|
|
|
71
73
|
|
|
72
74
|
expect(helmetLinks).toContainEqual({
|
|
73
75
|
rel: 'alternate',
|
|
74
|
-
href: '/es',
|
|
76
|
+
href: 'https://plone.org/es',
|
|
75
77
|
hrefLang: 'es',
|
|
76
78
|
});
|
|
77
79
|
expect(helmetLinks).toContainEqual({
|
|
78
80
|
rel: 'alternate',
|
|
79
|
-
href: '/en',
|
|
81
|
+
href: 'https://plone.org/en',
|
|
80
82
|
hrefLang: 'en',
|
|
81
83
|
});
|
|
82
84
|
});
|
|
83
85
|
|
|
84
86
|
it('multilingual site, with all available translations', () => {
|
|
87
|
+
config.settings.publicURL = 'https://plone.org';
|
|
88
|
+
config.settings.isMultilingual = true;
|
|
89
|
+
config.settings.supportedLanguages = ['en', 'es', 'eu'];
|
|
90
|
+
const store = mockStore({
|
|
91
|
+
intl: {
|
|
92
|
+
locale: 'en',
|
|
93
|
+
messages: {},
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const content = {
|
|
98
|
+
'@id': 'http://localhost:8080/Plone/en',
|
|
99
|
+
language: { token: 'en', title: 'English' },
|
|
100
|
+
'@components': {
|
|
101
|
+
translations: {
|
|
102
|
+
items: [
|
|
103
|
+
{ '@id': 'http://localhost:8080/Plone/eu', language: 'eu' },
|
|
104
|
+
{ '@id': 'http://localhost:8080/Plone/es', language: 'es' },
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// We need to force the component rendering
|
|
111
|
+
// to fill the Helmet
|
|
112
|
+
renderer.create(
|
|
113
|
+
<Provider store={store}>
|
|
114
|
+
<AlternateHrefLangs content={content} />
|
|
115
|
+
</Provider>,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const helmetLinks = Helmet.peek().linkTags;
|
|
119
|
+
|
|
120
|
+
// We expect having 3 links
|
|
121
|
+
expect(helmetLinks.length).toBe(3);
|
|
122
|
+
|
|
123
|
+
expect(helmetLinks).toContainEqual({
|
|
124
|
+
rel: 'alternate',
|
|
125
|
+
href: 'https://plone.org/eu',
|
|
126
|
+
hrefLang: 'eu',
|
|
127
|
+
});
|
|
128
|
+
expect(helmetLinks).toContainEqual({
|
|
129
|
+
rel: 'alternate',
|
|
130
|
+
href: 'https://plone.org/es',
|
|
131
|
+
hrefLang: 'es',
|
|
132
|
+
});
|
|
133
|
+
expect(helmetLinks).toContainEqual({
|
|
134
|
+
rel: 'alternate',
|
|
135
|
+
href: 'https://plone.org/en',
|
|
136
|
+
hrefLang: 'en',
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('multilingual site, with all available translations - with server URL', () => {
|
|
141
|
+
config.settings.publicURL = 'https://plone.org';
|
|
85
142
|
config.settings.isMultilingual = true;
|
|
86
143
|
config.settings.supportedLanguages = ['en', 'es', 'eu'];
|
|
87
144
|
const store = mockStore({
|
|
@@ -92,13 +149,13 @@ describe('AlternateHrefLangs', () => {
|
|
|
92
149
|
});
|
|
93
150
|
|
|
94
151
|
const content = {
|
|
95
|
-
'@id': '/en',
|
|
152
|
+
'@id': 'http://localhost:8080/Plone/en',
|
|
96
153
|
language: { token: 'en', title: 'English' },
|
|
97
154
|
'@components': {
|
|
98
155
|
translations: {
|
|
99
156
|
items: [
|
|
100
|
-
{ '@id': '/eu', language: 'eu' },
|
|
101
|
-
{ '@id': '/es', language: 'es' },
|
|
157
|
+
{ '@id': 'http://localhost:8080/Plone/eu', language: 'eu' },
|
|
158
|
+
{ '@id': 'http://localhost:8080/Plone/es', language: 'es' },
|
|
102
159
|
],
|
|
103
160
|
},
|
|
104
161
|
},
|
|
@@ -119,17 +176,17 @@ describe('AlternateHrefLangs', () => {
|
|
|
119
176
|
|
|
120
177
|
expect(helmetLinks).toContainEqual({
|
|
121
178
|
rel: 'alternate',
|
|
122
|
-
href: '/eu',
|
|
179
|
+
href: 'https://plone.org/eu',
|
|
123
180
|
hrefLang: 'eu',
|
|
124
181
|
});
|
|
125
182
|
expect(helmetLinks).toContainEqual({
|
|
126
183
|
rel: 'alternate',
|
|
127
|
-
href: '/es',
|
|
184
|
+
href: 'https://plone.org/es',
|
|
128
185
|
hrefLang: 'es',
|
|
129
186
|
});
|
|
130
187
|
expect(helmetLinks).toContainEqual({
|
|
131
188
|
rel: 'alternate',
|
|
132
|
-
href: '/en',
|
|
189
|
+
href: 'https://plone.org/en',
|
|
133
190
|
hrefLang: 'en',
|
|
134
191
|
});
|
|
135
192
|
});
|
|
@@ -27,10 +27,10 @@ export default function Image({
|
|
|
27
27
|
// TypeScript hints for editor autocomplete :)
|
|
28
28
|
/** @type {React.ImgHTMLAttributes<HTMLImageElement>} */
|
|
29
29
|
const attrs = {};
|
|
30
|
+
attrs.className = cx(className, { responsive }) || undefined;
|
|
30
31
|
|
|
31
32
|
if (!item && src) {
|
|
32
33
|
attrs.src = src;
|
|
33
|
-
attrs.className = cx(className, { responsive });
|
|
34
34
|
} else {
|
|
35
35
|
const isFromRealObject = !item.image_scales;
|
|
36
36
|
const imageFieldWithDefault = imageField || item.image_field || 'image';
|
|
@@ -51,7 +51,6 @@ export default function Image({
|
|
|
51
51
|
attrs.src = `${flattenToAppURL(basePath)}/${image.download}`;
|
|
52
52
|
attrs.width = image.width;
|
|
53
53
|
attrs.height = image.height;
|
|
54
|
-
attrs.className = cx(className, { responsive });
|
|
55
54
|
|
|
56
55
|
if (!isSvg && image.scales && Object.keys(image.scales).length > 0) {
|
|
57
56
|
const sortedScales = Object.values({
|
|
@@ -155,3 +155,11 @@ test('renders an image component from a string src', () => {
|
|
|
155
155
|
const json = component.toJSON();
|
|
156
156
|
expect(json).toMatchSnapshot();
|
|
157
157
|
});
|
|
158
|
+
|
|
159
|
+
test('should not render empty class attribute in img tag', () => {
|
|
160
|
+
const component = renderer.create(
|
|
161
|
+
<Image src="/image.png" alt="no class attribute" />,
|
|
162
|
+
);
|
|
163
|
+
const json = component.toJSON();
|
|
164
|
+
expect(json).toMatchSnapshot();
|
|
165
|
+
});
|
package/src/storybook.jsx
CHANGED
|
@@ -1490,6 +1490,7 @@ export const FormUndoWrapper = ({
|
|
|
1490
1490
|
onClick={() => doUndo()}
|
|
1491
1491
|
aria-label="Undo"
|
|
1492
1492
|
disabled={!canUndo}
|
|
1493
|
+
type="button"
|
|
1493
1494
|
>
|
|
1494
1495
|
Undo
|
|
1495
1496
|
</Button>
|
|
@@ -1500,6 +1501,7 @@ export const FormUndoWrapper = ({
|
|
|
1500
1501
|
onClick={() => doRedo()}
|
|
1501
1502
|
aria-label="Redo"
|
|
1502
1503
|
disabled={!canRedo}
|
|
1504
|
+
type="button"
|
|
1503
1505
|
>
|
|
1504
1506
|
Redo
|
|
1505
1507
|
</Button>
|