Skip to content

Commit

Permalink
Upgrade slate libraries; fix empty link element left hanging when hit…
Browse files Browse the repository at this point in the history
… enter at end of link (#5186)

Co-authored-by: iFlameing <ialokkumarsingh0@gmail.com>
Co-authored-by: Victor Fernandez de Alba <sneridagh@gmail.com>
Co-authored-by: Steve Piercy <web@stevepiercy.com>
  • Loading branch information
4 people committed Nov 7, 2023
1 parent 992d036 commit ce04d9b
Show file tree
Hide file tree
Showing 19 changed files with 151 additions and 74 deletions.
28 changes: 28 additions & 0 deletions cypress/tests/core/volto-slate/06-block-slate-format-link.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,32 @@ describe('Block Tests: Links', () => {
cy.get('[id="page-document"] p a').contains('Colorless green ideas');
cy.get('[id="page-document"] p a').contains('sleep furiously');
});

it('As editor I can add a link and pressing enter does not add another link in the next block', function () {
// https://github.com/plone/volto/pull/5186
cy.get('#toolbar').click();
cy.getSlate().type('Colorless green ideas sleep furiously');

cy.log('Create a Link');

cy.setSlateSelection('ideas', 'furiously');
cy.clickSlateButton('Add link');

cy.get('.slate-toolbar .link-form-container input').type(
'https://google.com{enter}',
);
cy.getSlate().should('have.descendants', 'a.slate-editor-link');
cy.getSlate().type('{rightarrow}').type('{enter}');
cy.getSlate().type('Hello').type('{enter}');

cy.toolbarSave();

cy.log('Then the page view should contain a link');
cy.get('.ui.container p').contains('Colorless green ideas sleep furiously');
// It should be only one, it will fail if there are two
cy.get('.ui.container p a')
.should('have.text', 'ideas sleep furiously')
.and('have.attr', 'href')
.and('include', 'https://google.com');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ is simply dummy text of the printing and typesetting industry.
// Save
cy.toolbarSave();

cy.get('[id="page-document"] p a').should('have.length', 1);
cy.get('[id="page-document"] p a').should('have.length', 0);
});
});
16 changes: 16 additions & 0 deletions docs/source/upgrade-guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ The generator will also "update" your project with the latest changes, and propo
Thus it is safe to run it on top of your project and answer the prompts.
```

(volto-upgrade-guide-18.x.x)=

## Upgrading to Volto 18.x.x

### Upgraded Slate libraries

The support libraries for Slate integration have been upgraded, mainly for bug fixes.
This is a breaking change.
The deprecated prop `value` in the main editor component setting is no longer supported, and has been replaced by `initialValue`.

If you use this component in your add-ons or projects directly, you need to replace the name of the prop.

```{note}
In your add-ons and projects, we advise you to always use the public components provided by Volto, instead of directly using the support libraries packaged in Volto.
```

(volto-upgrade-guide-17.x.x)=

## Upgrading to Volto 17.x.x
Expand Down
1 change: 1 addition & 0 deletions news/5291.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix empty link element left hanging when hit enter at end of link. @iFlameing @tiberiuichim
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -388,9 +388,9 @@
"semantic-ui-less": "2.4.1",
"semantic-ui-react": "2.0.3",
"serialize-javascript": "3.1.0",
"slate": "0.84.0",
"slate-hyperscript": "0.81.3",
"slate-react": "0.83.2",
"slate": "0.100.0",
"slate-hyperscript": "0.100.0",
"slate-react": "0.98.4",
"start-server-and-test": "1.14.0",
"style-loader": "3.3.1",
"stylelint": "15.10.3",
Expand Down
10 changes: 5 additions & 5 deletions packages/volto-slate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
"is-url": "1.2.4",
"jsdom": "^16.6.0",
"react-intersection-observer": "^8.32.0",
"slate": "^0.71.0",
"slate-history": "^0.66.0",
"slate-hyperscript": "^0.67.0",
"slate-react": "^0.71.0",
"slate": "0.100.0",
"slate-history": "0.100.0",
"slate-hyperscript": "0.100.0",
"slate-react": "0.98.4",
"weak-key": "^1.0.2"
},
"devDependencies": {
Expand All @@ -40,4 +40,4 @@
"lint:fix": "../node_modules/eslint/bin/eslint.js --fix 'src/**/*.{js,jsx}'",
"i18n": "mv .i18n.babel.config.js babel.config.js; rm -rf build/messages && NODE_ENV=production node src/i18n.js; mv babel.config.js .i18n.babel.config.js"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ exports[`TextBlockEdit renders w/o errors 1`] = `
data-slate-editor="true"
data-slate-node="value"
spellcheck="false"
style="position: relative; outline: none; white-space: pre-wrap; word-wrap: break-word; min-height: 0px;"
style="position: relative; white-space: pre-wrap; word-wrap: break-word;"
tabindex="0"
zindex="-1"
>
Expand All @@ -34,13 +34,6 @@ exports[`TextBlockEdit renders w/o errors 1`] = `
class=""
data-slate-leaf="true"
>
<span
contenteditable="false"
data-slate-placeholder="true"
style="position: absolute; pointer-events: none; width: 100%; max-width: 100%; display: block; opacity: 0.333; user-select: none; text-decoration: none;"
>
Type text…
</span>
<span
data-slate-length="0"
data-slate-zero-width="n"
Expand Down
9 changes: 6 additions & 3 deletions packages/volto-slate/src/blocks/Text/keyboard/joinBlocks.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ReactDOM from 'react-dom';
import { cloneDeep } from 'lodash';
import { serializeNodesToText } from '@plone/volto-slate/editor/render';
import { Editor } from 'slate';
import {
Expand All @@ -8,14 +9,14 @@ import {
isCursorAtBlockEnd,
mergeSlateWithBlockBackward,
mergeSlateWithBlockForward,
makeEditor,
} from '@plone/volto-slate/utils';
import {
changeBlock,
deleteBlock,
getBlocksFieldname,
getBlocksLayoutFieldname,
} from '@plone/volto/helpers';

/**
* Joins the current block (which has an active Slate Editor)
* with the previous block, to make a single block.
Expand Down Expand Up @@ -164,9 +165,11 @@ function getBlockEndAsRange(block) {
const { value } = block;
const location = [value.length - 1]; // adress of root node
const editor = { children: value };
const path = Editor.last(editor, location)[1]; // last Node in the block
const newEditor = makeEditor();
newEditor.children = cloneDeep(editor.children);
const path = Editor.last(newEditor, location)[1]; // last Node in the block
// The last Text node (leaf node) entry inside the path computed just above.
const [leaf, leafpath] = Editor.leaf(editor, path);
const [leaf, leafpath] = Editor.leaf(newEditor, path);
// The offset of the Points in the collapsed Range computed below:
const offset = (leaf.text || '').length;

Expand Down
4 changes: 3 additions & 1 deletion packages/volto-slate/src/editor/SlateEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class SlateEditor extends Component {
} catch {}
}, 100); // flush
}

this.state.editor.normalize({ force: true });
}
}

Expand Down Expand Up @@ -257,7 +259,7 @@ class SlateEditor extends Component {
<EditorContext.Provider value={editor}>
<Slate
editor={editor}
value={this.props.value || slateSettings.defaultValue()}
initialValue={this.props.value || slateSettings.defaultValue()}
onChange={this.handleChange}
>
{selected ? (
Expand Down
45 changes: 25 additions & 20 deletions packages/volto-slate/src/editor/plugins/Link/extensions.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
import { Text, Transforms, Element } from 'slate'; // Editor,
import { SIMPLELINK } from '@plone/volto-slate/constants';
import { jsx } from 'slate-hyperscript';
import { deserialize } from '@plone/volto-slate/editor/deserialize';

export const withSimpleLink = (editor) => {
// const { insertData, insertText, isInline } = editor;
const nodeToText = (node) => {
if (Text.isText(node)) {
return node.text.trim();
} else {
return node.children.map(nodeToText).join('');
}
};

const { isInline } = editor;
export const withSimpleLink = (editor) => {
const { isInline, normalizeNode } = editor;

editor.isInline = (element) => {
return element && element.type === SIMPLELINK ? true : isInline(element);
};

// editor.insertText = (text) => {
// if (text && isUrl(text)) {
// wrapLink(editor, text);
// } else {
// insertText(text);
// }
// };
//
// editor.insertData = (data) => {
// const text = data.getData('text/plain');
//
// if (text && isUrl(text)) {
// wrapLink(editor, text);
// } else {
// insertData(data);
// }
// };
editor.normalizeNode = (entry) => {
const [node, path] = entry;
const isTextNode = Text.isText(node);
const isElementNode = Element.isElement(node);
const isLinkTypeNode = node.type === SIMPLELINK;

// delete childless link nodes
if (!isTextNode && isElementNode && isLinkTypeNode && !nodeToText(node)) {
Transforms.removeNodes(editor, { at: path });
return;
}

return normalizeNode(entry);
};

return editor;
};

Expand Down
11 changes: 7 additions & 4 deletions packages/volto-slate/src/utils/selection.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { castArray } from 'lodash';
import { castArray, cloneDeep } from 'lodash';
import { Editor, Transforms, Range, Node } from 'slate';
import { ReactEditor } from 'slate-react';
import { isCursorInList } from '@plone/volto-slate/utils';
import { isCursorInList, makeEditor } from '@plone/volto-slate/utils';
import { LI } from '@plone/volto-slate/constants';
import config from '@plone/volto/registry';

Expand Down Expand Up @@ -155,7 +155,8 @@ export function getFragmentFromStartOfSelectionToEndOfEditor(
}

// immer doesn't like editor.savedSelection
const newEditor = { children: editor.children };
const newEditor = makeEditor();
newEditor.children = cloneDeep(editor.children);
return Editor.fragment(newEditor, range);
}

Expand All @@ -174,7 +175,9 @@ export function getFragmentFromBeginningOfEditorToStartOfSelection(

// immer doesn't like editor.savedSelection
// TODO: there's a bug here related to splitting lists
const newEditor = { children: editor.children };
const newEditor = makeEditor();
newEditor.children = cloneDeep(editor.children);

return Editor.fragment(
newEditor,
Editor.range(
Expand Down
2 changes: 1 addition & 1 deletion src/components/manage/Blocks/Description/Edit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export const DescriptionBlockEdit = (props) => {
<Slate
editor={editor}
onChange={handleChange}
value={initialValue}
initialValue={initialValue}
className={cx('block description', {
selected: selected,
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ exports[`renders edit blocks renders an edit description block component 1`] = `
spellCheck={false}
style={
Object {
"outline": "none",
"position": "relative",
"whiteSpace": "pre-wrap",
"wordWrap": "break-word",
Expand Down
2 changes: 1 addition & 1 deletion src/components/manage/Blocks/Title/Edit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export const TitleBlockEdit = (props) => {
return <div />;
}
return (
<Slate editor={editor} onChange={handleChange} value={initialValue}>
<Slate editor={editor} onChange={handleChange} initialValue={initialValue}>
<Editable
readOnly={!editable}
onKeyDown={handleKeyDown}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ exports[`renders edit blocks renders an edit title block component 1`] = `
spellCheck={false}
style={
Object {
"outline": "none",
"position": "relative",
"whiteSpace": "pre-wrap",
"wordWrap": "break-word",
Expand Down
2 changes: 1 addition & 1 deletion src/components/manage/TextLineEdit/TextLineEdit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export const TextLineEdit = (props) => {
return <div />;
}
return (
<Slate editor={editor} onChange={handleChange} value={initialValue}>
<Slate editor={editor} onChange={handleChange} initialValue={initialValue}>
<Editable
readOnly={!editable}
onKeyDown={handleKeyDown}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ exports[`renders TextLineEdit renders an TextLineEdit as h1 1`] = `
spellCheck={false}
style={
Object {
"outline": "none",
"position": "relative",
"whiteSpace": "pre-wrap",
"wordWrap": "break-word",
Expand Down Expand Up @@ -86,7 +85,6 @@ exports[`renders TextLineEdit renders an TextLineEdit as h2 1`] = `
spellCheck={false}
style={
Object {
"outline": "none",
"position": "relative",
"whiteSpace": "pre-wrap",
"wordWrap": "break-word",
Expand Down Expand Up @@ -144,7 +142,6 @@ exports[`renders TextLineEdit renders an TextLineEdit as h2 with a classname 1`]
spellCheck={false}
style={
Object {
"outline": "none",
"position": "relative",
"whiteSpace": "pre-wrap",
"wordWrap": "break-word",
Expand Down
9 changes: 9 additions & 0 deletions theme/themes/pastanaga/extras/blocks.less
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@
border-color: rgba(120, 192, 215, 0.75);
}

.block-editor-title,
.block-editor-slate,
.block-editor-slateTable,
.slate-editor.selected {
:focus-visible {
outline: none;
}
}

.block .block:hover::before {
border-color: rgba(120, 192, 215, 0.375);
}
Expand Down

0 comments on commit ce04d9b

Please sign in to comment.