@plone/volto 17.1.0 → 17.1.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 CHANGED
@@ -8,6 +8,14 @@
8
8
 
9
9
  <!-- towncrier release notes start -->
10
10
 
11
+ ## 17.1.1 (2023-10-13)
12
+
13
+ ### Bugfix
14
+
15
+ - Normalize the shape of the image component item prop if it contains the serialized object after creation to match the one in the catalog. @sneridagh [#5266](https://github.com/plone/volto/issues/5266)
16
+ - Added guard in `flattenScales` in edge case image is undefined @sneridagh [#5318](https://github.com/plone/volto/issues/5318)
17
+
18
+
11
19
  ## 17.1.0 (2023-10-11)
12
20
 
13
21
  ### Feature
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "17.1.0",
12
+ "version": "17.1.1",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git@github.com:plone/volto.git"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plone/volto-slate",
3
- "version": "17.1.0",
3
+ "version": "17.1.1",
4
4
  "description": "Slate.js integration with Volto",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -19,14 +19,15 @@ test('renders a Lead Image block Sidebar component', () => {
19
19
  <LeadImageSidebar
20
20
  data={{}}
21
21
  properties={{
22
+ '@id': 'http://localhost:3000/image.png',
22
23
  image: {
23
- download: 'http://localhost:3000/image.png',
24
+ download: 'http://localhost:3000/image.png/@@images/image-1200.png',
24
25
  width: 400,
25
26
  height: 400,
26
27
  scales: {
27
28
  preview: {
28
29
  download:
29
- 'http://localhost:3000/image.png/@@images/image/image-400.png',
30
+ 'http://localhost:3000/image.png/@@images/image-400.png',
30
31
  width: 400,
31
32
  height: 400,
32
33
  },
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import cx from 'classnames';
3
- import { flattenToAppURL } from '@plone/volto/helpers';
3
+ import { flattenToAppURL, flattenScales } from '@plone/volto/helpers';
4
4
 
5
5
  /**
6
6
  * Image component
@@ -36,16 +36,17 @@ export default function Image({
36
36
  const imageFieldWithDefault = imageField || item.image_field || 'image';
37
37
 
38
38
  const image = isFromRealObject
39
- ? item[imageFieldWithDefault]
40
- : item.image_scales[imageFieldWithDefault]?.[0];
39
+ ? flattenScales(item['@id'], item[imageFieldWithDefault])
40
+ : flattenScales(
41
+ item['@id'],
42
+ item.image_scales[imageFieldWithDefault]?.[0],
43
+ );
41
44
 
42
45
  if (!image) return null;
43
46
 
44
47
  const isSvg = image['content-type'] === 'image/svg+xml';
45
48
 
46
- const baseUrl = isFromRealObject ? '' : flattenToAppURL(item['@id'] + '/');
47
-
48
- attrs.src = `${baseUrl}${flattenToAppURL(image.download)}`;
49
+ attrs.src = `${flattenToAppURL(item['@id'])}/${image.download}`;
49
50
  attrs.width = image.width;
50
51
  attrs.height = image.height;
51
52
  attrs.className = cx(className, { responsive });
@@ -60,7 +61,7 @@ export default function Image({
60
61
  attrs.srcSet = sortedScales
61
62
  .map(
62
63
  (scale) =>
63
- `${baseUrl}${flattenToAppURL(scale.download)} ${scale.width}w`,
64
+ `${flattenToAppURL(item['@id'])}/${scale.download} ${scale.width}w`,
64
65
  )
65
66
  .join(', ');
66
67
  }
@@ -6,14 +6,14 @@ test('renders an image component with fetchpriority high', () => {
6
6
  const component = renderer.create(
7
7
  <Image
8
8
  item={{
9
+ '@id': 'http://localhost:3000/image',
9
10
  image: {
10
- download: 'http://localhost:3000/image/@@images/image/image.png',
11
+ download: 'http://localhost:3000/image/@@images/image.png',
11
12
  width: 400,
12
13
  height: 400,
13
14
  scales: {
14
15
  preview: {
15
- download:
16
- 'http://localhost:3000/image/@@images/image/image-400.png',
16
+ download: 'http://localhost:3000/image/@@images/image-400.png',
17
17
  width: 400,
18
18
  height: 400,
19
19
  },
@@ -32,14 +32,14 @@ test('renders an image component with lazy loading', () => {
32
32
  const component = renderer.create(
33
33
  <Image
34
34
  item={{
35
+ '@id': 'http://localhost:3000/image',
35
36
  image: {
36
- download: 'http://localhost:3000/image/@@images/image/image.png',
37
+ download: 'http://localhost:3000/image/@@images/image.png',
37
38
  width: 400,
38
39
  height: 400,
39
40
  scales: {
40
41
  preview: {
41
- download:
42
- 'http://localhost:3000/image/@@images/image/image-400.png',
42
+ download: 'http://localhost:3000/image/@@images/image-400.png',
43
43
  width: 400,
44
44
  height: 400,
45
45
  },
@@ -59,14 +59,14 @@ test('renders an image component with responsive class', () => {
59
59
  const component = renderer.create(
60
60
  <Image
61
61
  item={{
62
+ '@id': 'http://localhost:3000/image',
62
63
  image: {
63
- download: 'http://localhost:3000/image/@@images/image/image.png',
64
+ download: 'http://localhost:3000/image/@@images/image-1200.png',
64
65
  width: 400,
65
66
  height: 400,
66
67
  scales: {
67
68
  preview: {
68
- download:
69
- 'http://localhost:3000/image/@@images/image/image-400.png',
69
+ download: 'http://localhost:3000/image/@@images/image-400.png',
70
70
  width: 400,
71
71
  height: 400,
72
72
  },
@@ -91,12 +91,12 @@ test('renders an image component from a catalog brain', () => {
91
91
  image_scales: {
92
92
  image: [
93
93
  {
94
- download: '@@images/image/image.png',
94
+ download: '@@images/image.png',
95
95
  width: 400,
96
96
  height: 400,
97
97
  scales: {
98
98
  preview: {
99
- download: '@@images/image/image-400.png',
99
+ download: '@@images/image-400.png',
100
100
  width: 400,
101
101
  height: 400,
102
102
  },
@@ -355,3 +355,32 @@ export const URLUtils = {
355
355
  isUrl,
356
356
  checkAndNormalizeUrl,
357
357
  };
358
+
359
+ /**
360
+ * Given an image info object, it does flatten all the scales information to
361
+ * match the ones stored in the catalog
362
+ * 'http://localhost:3000/{path}/@@images/{scalefile}' -> '@images/{scalefile}'
363
+ * @function flattenScales
364
+ * @param {string} path path of the content object
365
+ * @param {object} image image information object
366
+ * @returns {object} New object with the flattened scale URLs
367
+ */
368
+ export function flattenScales(path, image) {
369
+ function removeObjectIdFromURL(path, scale) {
370
+ return scale.replace(`${path}/`, '');
371
+ }
372
+ if (!image) return;
373
+
374
+ const imageInfo = {
375
+ ...image,
376
+ download: flattenToAppURL(removeObjectIdFromURL(path, image.download)),
377
+ };
378
+
379
+ Object.keys(imageInfo.scales).forEach((key) => {
380
+ imageInfo.scales[key].download = flattenToAppURL(
381
+ removeObjectIdFromURL(path, image.scales[key].download),
382
+ );
383
+ });
384
+
385
+ return imageInfo;
386
+ }
@@ -18,6 +18,7 @@ import {
18
18
  checkAndNormalizeUrl,
19
19
  normaliseMail,
20
20
  normalizeTelephone,
21
+ flattenScales,
21
22
  } from './Url';
22
23
 
23
24
  beforeEach(() => {
@@ -350,4 +351,107 @@ describe('Url', () => {
350
351
  );
351
352
  });
352
353
  });
354
+ describe('flattenScales', () => {
355
+ it('flattenScales image is not set', () => {
356
+ const id = '/halfdome2022-2.jpg';
357
+ const image = undefined;
358
+ expect(flattenScales(id, image)).toBe(undefined);
359
+ });
360
+
361
+ it('flattenScales test from the catalog', () => {
362
+ const id = '/halfdome2022-2.jpg';
363
+ const image = {
364
+ 'content-type': 'image/jpeg',
365
+ download: '@@images/image-1182-cf763ae23c52340d8a17a7afdb26c8cb.jpeg',
366
+ filename: 'halfdome2022.jpg',
367
+ height: 665,
368
+ scales: {
369
+ great: {
370
+ download:
371
+ '@@images/image-1200-539ab119ebadc7d011798980a4a5e8d4.jpeg',
372
+ height: 665,
373
+ width: 1182,
374
+ },
375
+ huge: {
376
+ download:
377
+ '@@images/image-1600-188968febc677890c1b99d5339f9bef1.jpeg',
378
+ height: 665,
379
+ width: 1182,
380
+ },
381
+ },
382
+ size: 319364,
383
+ width: 1182,
384
+ };
385
+ expect(flattenScales(id, image)).toStrictEqual({
386
+ 'content-type': 'image/jpeg',
387
+ download: '@@images/image-1182-cf763ae23c52340d8a17a7afdb26c8cb.jpeg',
388
+ filename: 'halfdome2022.jpg',
389
+ height: 665,
390
+ scales: {
391
+ great: {
392
+ download:
393
+ '@@images/image-1200-539ab119ebadc7d011798980a4a5e8d4.jpeg',
394
+ height: 665,
395
+ width: 1182,
396
+ },
397
+ huge: {
398
+ download:
399
+ '@@images/image-1600-188968febc677890c1b99d5339f9bef1.jpeg',
400
+ height: 665,
401
+ width: 1182,
402
+ },
403
+ },
404
+ size: 319364,
405
+ width: 1182,
406
+ });
407
+ });
408
+ it('flattenScales test from serialization', () => {
409
+ const id = 'http://localhost:3000/halfdome2022-2.jpg';
410
+ const image = {
411
+ 'content-type': 'image/jpeg',
412
+ download:
413
+ 'http://localhost:3000/halfdome2022-2.jpg/@@images/image-1182-cf763ae23c52340d8a17a7afdb26c8cb.jpeg',
414
+ filename: 'halfdome2022.jpg',
415
+ height: 665,
416
+ scales: {
417
+ great: {
418
+ download:
419
+ 'http://localhost:3000/halfdome2022-2.jpg/@@images/image-1200-539ab119ebadc7d011798980a4a5e8d4.jpeg',
420
+ height: 665,
421
+ width: 1182,
422
+ },
423
+ huge: {
424
+ download:
425
+ 'http://localhost:3000/halfdome2022-2.jpg/@@images/image-1600-188968febc677890c1b99d5339f9bef1.jpeg',
426
+ height: 665,
427
+ width: 1182,
428
+ },
429
+ },
430
+ size: 319364,
431
+ width: 1182,
432
+ };
433
+ expect(flattenScales(id, image)).toStrictEqual({
434
+ 'content-type': 'image/jpeg',
435
+ download: '@@images/image-1182-cf763ae23c52340d8a17a7afdb26c8cb.jpeg',
436
+ filename: 'halfdome2022.jpg',
437
+ height: 665,
438
+ scales: {
439
+ great: {
440
+ download:
441
+ '@@images/image-1200-539ab119ebadc7d011798980a4a5e8d4.jpeg',
442
+ height: 665,
443
+ width: 1182,
444
+ },
445
+ huge: {
446
+ download:
447
+ '@@images/image-1600-188968febc677890c1b99d5339f9bef1.jpeg',
448
+ height: 665,
449
+ width: 1182,
450
+ },
451
+ },
452
+ size: 319364,
453
+ width: 1182,
454
+ });
455
+ });
456
+ });
353
457
  });
@@ -29,6 +29,7 @@ export {
29
29
  normalizeUrl,
30
30
  removeProtocol,
31
31
  URLUtils,
32
+ flattenScales,
32
33
  } from '@plone/volto/helpers/Url/Url';
33
34
  export { generateRobots } from '@plone/volto/helpers/Robots/Robots';
34
35
  export {