@plone/volto 16.25.0 → 16.26.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.draft CHANGED
@@ -1,17 +1,12 @@
1
- ## 16.25.0 (2023-10-16)
2
-
3
- ### Feature
4
-
5
- - Add external className to slate Link view. @iFlameing [#5109](https://github.com/plone/volto/issues/5109)
1
+ ## 16.26.1 (2023-11-10)
6
2
 
7
3
  ### Bugfix
8
4
 
9
- - Fix empty slate text block in table of contents. @kreafox [#5156](https://github.com/plone/volto/issues/5156)
10
- - Fix standalone navigation action call if expander is set @sneridagh [#5197](https://github.com/plone/volto/issues/5197)
11
- - Added support for blocksConfig configuration in the listing block @sneridagh [#5310](https://github.com/plone/volto/issues/5310)
12
- - Fix adding multiple path criteria in search and listing blocks. @davisagli [#5317](https://github.com/plone/volto/issues/5317)
5
+ - Fix empty link element left hanging when hit enter at end of link. @iFlameing @tiberiuichim [#5291](https://github.com/plone/volto/issues/5291)
13
6
 
14
7
  ### Internal
15
8
 
16
- - Fix Cypress ECONNREFUSED error in CI due to latest Chrome headless option handling for Cypress < 12.14.0 @sneridagh [#5233](https://github.com/plone/volto/issues/5233)
9
+ - Added shim to keep working with value instead of initialValue in upgraded Slate @davisagli [#5291](https://github.com/plone/volto/issues/5291)
10
+ - Update internal Plone version to 6.0.8 @sneridagh [#5384](https://github.com/plone/volto/issues/5384)
11
+
17
12
 
Binary file
package/CHANGELOG.md CHANGED
@@ -8,6 +8,36 @@
8
8
 
9
9
  <!-- towncrier release notes start -->
10
10
 
11
+ ## 16.26.1 (2023-11-10)
12
+
13
+ ### Bugfix
14
+
15
+ - Fix empty link element left hanging when hit enter at end of link. @iFlameing @tiberiuichim [#5291](https://github.com/plone/volto/issues/5291)
16
+
17
+ ### Internal
18
+
19
+ - Added shim to keep working with value instead of initialValue in upgraded Slate @davisagli [#5291](https://github.com/plone/volto/issues/5291)
20
+ - Update internal Plone version to 6.0.8 @sneridagh [#5384](https://github.com/plone/volto/issues/5384)
21
+
22
+ ## 16.26.0 (2023-10-27)
23
+
24
+ ### Feature
25
+
26
+ - Updated aria-label for landmarks @ichim-david
27
+ Added landmark on sidebar @ichim-david
28
+ Added Pluggable section for skiplinks @ichim-david [#5290](https://github.com/plone/volto/issues/5290)
29
+
30
+ ### Bugfix
31
+
32
+ - (FIX): put padding so the text is not clipped #5305 @dobri1408 [#5305](https://github.com/plone/volto/issues/5305)
33
+ - Fix compare translations view @sneridagh [#5327](https://github.com/plone/volto/issues/5327)
34
+ - Fix DatetimeWidget on FF, the button default if no type is set is sending the form. @sneridagh
35
+ See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#formmethod [#5343](https://github.com/plone/volto/issues/5343)
36
+
37
+ ### Internal
38
+
39
+ - Add a new set of acceptance tests with the multilingual fixture using seamless mode. @sneridagh [#5332](https://github.com/plone/volto/issues/5332)
40
+
11
41
  ## 16.25.0 (2023-10-16)
12
42
 
13
43
  ### Feature
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "16.25.0",
12
+ "version": "16.26.1",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git@github.com:plone/volto.git"
@@ -197,6 +197,9 @@
197
197
  "release": true,
198
198
  "releaseName": "${version}",
199
199
  "releaseNotes": "cat .changelog.draft"
200
+ },
201
+ "npm": {
202
+ "tag": "lts"
200
203
  }
201
204
  },
202
205
  "lint-staged": {
@@ -381,9 +384,9 @@
381
384
  "semantic-ui-react": "2.0.3",
382
385
  "semver": "5.6.0",
383
386
  "serialize-javascript": "3.1.0",
384
- "slate": "0.84.0",
385
- "slate-hyperscript": "0.81.3",
386
- "slate-react": "0.83.2",
387
+ "slate": "0.100.0",
388
+ "slate-hyperscript": "0.100.0",
389
+ "slate-react": "0.98.4",
387
390
  "start-server-and-test": "1.14.0",
388
391
  "style-loader": "2",
389
392
  "stylelint": "14.0.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plone/volto-slate",
3
- "version": "16.25.0",
3
+ "version": "16.26.1",
4
4
  "description": "Slate.js integration with Volto",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -18,10 +18,10 @@
18
18
  "is-url": "1.2.4",
19
19
  "jsdom": "^16.6.0",
20
20
  "react-intersection-observer": "^8.32.0",
21
- "slate": "^0.71.0",
22
- "slate-history": "^0.66.0",
23
- "slate-hyperscript": "^0.67.0",
24
- "slate-react": "^0.71.0",
21
+ "slate": "0.100.0",
22
+ "slate-history": "0.100.0",
23
+ "slate-hyperscript": "0.100.0",
24
+ "slate-react": "0.98.4",
25
25
  "weak-key": "^1.0.2"
26
26
  },
27
27
  "devDependencies": {
@@ -1,4 +1,5 @@
1
1
  import ReactDOM from 'react-dom';
2
+ import { cloneDeep } from 'lodash';
2
3
  import { serializeNodesToText } from '@plone/volto-slate/editor/render';
3
4
  import { Editor } from 'slate';
4
5
  import {
@@ -8,6 +9,7 @@ import {
8
9
  isCursorAtBlockEnd,
9
10
  mergeSlateWithBlockBackward,
10
11
  mergeSlateWithBlockForward,
12
+ makeEditor,
11
13
  } from '@plone/volto-slate/utils';
12
14
  import {
13
15
  changeBlock,
@@ -15,7 +17,6 @@ import {
15
17
  getBlocksFieldname,
16
18
  getBlocksLayoutFieldname,
17
19
  } from '@plone/volto/helpers';
18
-
19
20
  /**
20
21
  * Joins the current block (which has an active Slate Editor)
21
22
  * with the previous block, to make a single block.
@@ -164,9 +165,11 @@ function getBlockEndAsRange(block) {
164
165
  const { value } = block;
165
166
  const location = [value.length - 1]; // adress of root node
166
167
  const editor = { children: value };
167
- const path = Editor.last(editor, location)[1]; // last Node in the block
168
+ const newEditor = makeEditor();
169
+ newEditor.children = cloneDeep(editor.children);
170
+ const path = Editor.last(newEditor, location)[1]; // last Node in the block
168
171
  // The last Text node (leaf node) entry inside the path computed just above.
169
- const [leaf, leafpath] = Editor.leaf(editor, path);
172
+ const [leaf, leafpath] = Editor.leaf(newEditor, path);
170
173
  // The offset of the Points in the collapsed Range computed below:
171
174
  const offset = (leaf.text || '').length;
172
175
 
@@ -135,6 +135,8 @@ class SlateEditor extends Component {
135
135
  } catch {}
136
136
  }, 100); // flush
137
137
  }
138
+
139
+ this.state.editor.normalize({ force: true });
138
140
  }
139
141
  }
140
142
 
@@ -257,7 +259,7 @@ class SlateEditor extends Component {
257
259
  <EditorContext.Provider value={editor}>
258
260
  <Slate
259
261
  editor={editor}
260
- value={this.props.value || slateSettings.defaultValue()}
262
+ initialValue={this.props.value || slateSettings.defaultValue()}
261
263
  onChange={this.handleChange}
262
264
  >
263
265
  {selected ? (
@@ -1,33 +1,38 @@
1
+ import { Text, Transforms, Element } from 'slate'; // Editor,
1
2
  import { SIMPLELINK } from '@plone/volto-slate/constants';
2
3
  import { jsx } from 'slate-hyperscript';
3
4
  import { deserialize } from '@plone/volto-slate/editor/deserialize';
4
5
 
5
- export const withSimpleLink = (editor) => {
6
- // const { insertData, insertText, isInline } = editor;
6
+ const nodeToText = (node) => {
7
+ if (Text.isText(node)) {
8
+ return node.text.trim();
9
+ } else {
10
+ return node.children.map(nodeToText).join('');
11
+ }
12
+ };
7
13
 
8
- const { isInline } = editor;
14
+ export const withSimpleLink = (editor) => {
15
+ const { isInline, normalizeNode } = editor;
9
16
 
10
17
  editor.isInline = (element) => {
11
18
  return element && element.type === SIMPLELINK ? true : isInline(element);
12
19
  };
13
20
 
14
- // editor.insertText = (text) => {
15
- // if (text && isUrl(text)) {
16
- // wrapLink(editor, text);
17
- // } else {
18
- // insertText(text);
19
- // }
20
- // };
21
- //
22
- // editor.insertData = (data) => {
23
- // const text = data.getData('text/plain');
24
- //
25
- // if (text && isUrl(text)) {
26
- // wrapLink(editor, text);
27
- // } else {
28
- // insertData(data);
29
- // }
30
- // };
21
+ editor.normalizeNode = (entry) => {
22
+ const [node, path] = entry;
23
+ const isTextNode = Text.isText(node);
24
+ const isElementNode = Element.isElement(node);
25
+ const isLinkTypeNode = node.type === SIMPLELINK;
26
+
27
+ // delete childless link nodes
28
+ if (!isTextNode && isElementNode && isLinkTypeNode && !nodeToText(node)) {
29
+ Transforms.removeNodes(editor, { at: path });
30
+ return;
31
+ }
32
+
33
+ return normalizeNode(entry);
34
+ };
35
+
31
36
  return editor;
32
37
  };
33
38
 
@@ -0,0 +1,26 @@
1
+ import { Slate as OrigSlate } from '@slate-react';
2
+
3
+ // Components
4
+ export { Editable, DefaultPlaceholder } from '@slate-react';
5
+
6
+ export { DefaultElement } from '@slate-react';
7
+ export { DefaultLeaf } from '@slate-react';
8
+
9
+ // Hooks
10
+ export { useEditor } from '@slate-react';
11
+ export { useSlateStatic } from '@slate-react';
12
+ export { useFocused } from '@slate-react';
13
+ export { useReadOnly } from '@slate-react';
14
+ export { useSelected } from '@slate-react';
15
+ export { useSlate, useSlateWithV } from '@slate-react';
16
+ export { useSlateSelector } from '@slate-react';
17
+ export { useSlateSelection } from '@slate-react';
18
+
19
+ // Plugin
20
+ export { ReactEditor } from '@slate-react';
21
+ export { withReact } from '@slate-react';
22
+
23
+ export const Slate = (props) => {
24
+ const initialValue = props.initialValue || props.value;
25
+ return OrigSlate({ ...props, initialValue });
26
+ };
@@ -1,7 +1,7 @@
1
- import { castArray } from 'lodash';
1
+ import { castArray, cloneDeep } from 'lodash';
2
2
  import { Editor, Transforms, Range, Node } from 'slate';
3
3
  import { ReactEditor } from 'slate-react';
4
- import { isCursorInList } from '@plone/volto-slate/utils';
4
+ import { isCursorInList, makeEditor } from '@plone/volto-slate/utils';
5
5
  import { LI } from '@plone/volto-slate/constants';
6
6
  import config from '@plone/volto/registry';
7
7
 
@@ -155,7 +155,8 @@ export function getFragmentFromStartOfSelectionToEndOfEditor(
155
155
  }
156
156
 
157
157
  // immer doesn't like editor.savedSelection
158
- const newEditor = { children: editor.children };
158
+ const newEditor = makeEditor();
159
+ newEditor.children = cloneDeep(editor.children);
159
160
  return Editor.fragment(newEditor, range);
160
161
  }
161
162
 
@@ -174,7 +175,9 @@ export function getFragmentFromBeginningOfEditorToStartOfSelection(
174
175
 
175
176
  // immer doesn't like editor.savedSelection
176
177
  // TODO: there's a bug here related to splitting lists
177
- const newEditor = { children: editor.children };
178
+ const newEditor = makeEditor();
179
+ newEditor.children = cloneDeep(editor.children);
180
+
178
181
  return Editor.fragment(
179
182
  newEditor,
180
183
  Editor.range(
package/razzle.config.js CHANGED
@@ -251,6 +251,9 @@ const defaultModify = ({
251
251
  // avoids including lodash multiple times.
252
252
  // semantic-ui-react uses lodash-es, everything else uses lodash
253
253
  'lodash-es': path.dirname(require.resolve('lodash')),
254
+ // workaround for backwards-incompatible change in slate-react
255
+ '@slate-react': path.dirname(require.resolve('slate-react')),
256
+ 'slate-react$': `${registry.voltoPath}/packages/volto-slate/src/slate-react`,
254
257
  };
255
258
 
256
259
  const [
@@ -170,7 +170,7 @@ export const TitleBlockEdit = (props) => {
170
170
  <Slate
171
171
  editor={editor}
172
172
  onChange={handleChange}
173
- value={initialValue}
173
+ initialValue={initialValue}
174
174
  className={cx('block description', {
175
175
  selected: selected,
176
176
  })}
@@ -31,8 +31,7 @@ export const customSelectStyles = {
31
31
  }),
32
32
  valueContainer: (styles) => ({
33
33
  ...styles,
34
- padding: '0px',
35
- paddingLeft: 0,
34
+ padding: '8px',
36
35
  }),
37
36
  dropdownIndicator: (styles) => ({
38
37
  paddingRight: 0,
@@ -155,7 +155,7 @@ export const TitleBlockEdit = (props) => {
155
155
  return <div />;
156
156
  }
157
157
  return (
158
- <Slate editor={editor} onChange={handleChange} value={initialValue}>
158
+ <Slate editor={editor} onChange={handleChange} initialValue={initialValue}>
159
159
  <Editable
160
160
  readOnly={!editable}
161
161
  onKeyDown={handleKeyDown}
@@ -35,7 +35,11 @@ import {
35
35
  getSchema,
36
36
  listActions,
37
37
  } from '@plone/volto/actions';
38
- import { getBaseUrl, hasBlocksData } from '@plone/volto/helpers';
38
+ import {
39
+ flattenToAppURL,
40
+ getBaseUrl,
41
+ hasBlocksData,
42
+ } from '@plone/volto/helpers';
39
43
  import { preloadLazyLibs } from '@plone/volto/helpers/Loadable';
40
44
 
41
45
  import saveSVG from '@plone/volto/icons/save.svg';
@@ -260,7 +264,12 @@ class Edit extends Component {
260
264
 
261
265
  setComparingLanguage(lang, content_id) {
262
266
  this.setState({ comparingLanguage: lang });
263
- this.props.getContent(content_id, null, 'compare_to', null);
267
+ this.props.getContent(
268
+ flattenToAppURL(content_id),
269
+ null,
270
+ 'compare_to',
271
+ null,
272
+ );
264
273
  }
265
274
 
266
275
  form = React.createRef();
@@ -174,7 +174,7 @@ export const TextLineEdit = (props) => {
174
174
  return <div />;
175
175
  }
176
176
  return (
177
- <Slate editor={editor} onChange={handleChange} value={initialValue}>
177
+ <Slate editor={editor} onChange={handleChange} initialValue={initialValue}>
178
178
  <Editable
179
179
  readOnly={!editable}
180
180
  onKeyDown={handleKeyDown}
@@ -246,6 +246,8 @@ export class DatetimeWidgetComponent extends Component {
246
246
  )}
247
247
  {resettable && (
248
248
  <button
249
+ // FF needs that the type is "button" in order to not POST the form
250
+ type="button"
249
251
  disabled={this.props.isDisabled || !datetime}
250
252
  onClick={() => this.onResetDates()}
251
253
  className="item ui noborder button"
@@ -41,6 +41,7 @@ const Footer = ({ intl }) => {
41
41
  color="grey"
42
42
  textAlign="center"
43
43
  id="footer"
44
+ aria-label="Footer"
44
45
  >
45
46
  <Container>
46
47
  <Segment basic inverted color="grey" className="discreet">
@@ -128,7 +128,7 @@ class Navigation extends Component {
128
128
  */
129
129
  render() {
130
130
  return (
131
- <nav className="navigation" id="navigation" aria-label="navigation">
131
+ <nav className="navigation" id="navigation" aria-label="Site">
132
132
  <div className="hamburger-wrapper mobile tablet only">
133
133
  <button
134
134
  className={cx('hamburger hamburger--spin', {
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { useIntl, defineMessages } from 'react-intl';
3
+ import { Pluggable } from '@plone/volto/components/manage/Pluggable';
3
4
 
4
5
  const messages = defineMessages({
5
6
  mainView: {
@@ -23,7 +24,7 @@ const SkipLinks = () => {
23
24
  <div
24
25
  className="skiplinks-wrapper"
25
26
  role="complementary"
26
- aria-label="skiplinks"
27
+ aria-label="Skiplinks"
27
28
  >
28
29
  <a className="skiplink" href="#view">
29
30
  {intl.formatMessage(messages.mainView)}
@@ -34,6 +35,7 @@ const SkipLinks = () => {
34
35
  <a className="skiplink" href="#footer">
35
36
  {intl.formatMessage(messages.footer)}
36
37
  </a>
38
+ <Pluggable name="main.skiplinks" />
37
39
  </div>
38
40
  );
39
41
  };
@@ -3,6 +3,7 @@ import renderer from 'react-test-renderer';
3
3
  import configureStore from 'redux-mock-store';
4
4
  import { Provider } from 'react-intl-redux';
5
5
  import { MemoryRouter } from 'react-router-dom';
6
+ import { PluggablesProvider } from '@plone/volto/components/manage/Pluggable';
6
7
 
7
8
  import SkipLinks from './SkipLinks';
8
9
 
@@ -18,9 +19,11 @@ describe('SkipLinks', () => {
18
19
  });
19
20
  const component = renderer.create(
20
21
  <Provider store={store}>
21
- <MemoryRouter>
22
- <SkipLinks />
23
- </MemoryRouter>
22
+ <PluggablesProvider>
23
+ <MemoryRouter>
24
+ <SkipLinks />
25
+ </MemoryRouter>
26
+ </PluggablesProvider>
24
27
  </Provider>,
25
28
  );
26
29
  const json = component.toJSON();
@@ -183,7 +183,7 @@ class Html extends Component {
183
183
  <body className={bodyClass}>
184
184
  <div role="navigation" aria-label="Toolbar" id="toolbar" />
185
185
  <div id="main" dangerouslySetInnerHTML={{ __html: markup }} />
186
- <div id="sidebar" />
186
+ <div role="complementary" aria-label="Sidebar" id="sidebar" />
187
187
  <script
188
188
  dangerouslySetInnerHTML={{
189
189
  __html: `window.__data=${serialize(
@@ -42,6 +42,15 @@
42
42
  border-color: rgba(120, 192, 215, 0.75);
43
43
  }
44
44
 
45
+ .block-editor-title,
46
+ .block-editor-slate,
47
+ .block-editor-slateTable,
48
+ .slate-editor.selected {
49
+ :focus-visible {
50
+ outline: none;
51
+ }
52
+ }
53
+
45
54
  .block .block:hover::before {
46
55
  border-color: rgba(120, 192, 215, 0.375);
47
56
  }
package/pyvenv.cfg DELETED
@@ -1,3 +0,0 @@
1
- home = /opt/homebrew/opt/python@3.9/bin
2
- include-system-site-packages = false
3
- version = 3.9.16